Я бы не стал разбивать данные на фрагменты и сохранял бы их как серии наборов данных из одного массива (в соответствии с тем, что предлагает Бенджамин).Я только что завершил загрузку выходных данных корпоративного приложения, над которым я работал, в HDF5 и смог упаковать около 4,5 миллиардов составных типов данных в 450 000 наборов данных, каждый из которых содержит массив из 10 000 данных.Запись и чтение теперь кажутся довольно мгновенными, но когда я изначально пытался разделить данные на части, они были мучительно медленными.
Просто мысль!
Обновление:
Это парафрагменты взяты из моего реального кода (я пишу на C против Python, но вы должны понять, что я делаю) и изменены для ясности.Я просто пишу длинные целые числа без знака в массивах (10000 значений на массив) и читаю их обратно, когда мне нужно фактическое значение
Это мой типичный код записи.В этом случае я просто записываю длинную целочисленную последовательность без знака в последовательность массивов и загружаю каждую последовательность массивов в hdf5 по мере их создания.
//Our dummy data: a rolling count of long unsigned integers
long unsigned int k = 0UL;
//We'll use this to store our dummy data, 10,000 at a time
long unsigned int kValues[NUMPERDATASET];
//Create the SS adata files.
hid_t ssdb = H5Fcreate(SSHDF, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
//NUMPERDATASET = 10,000, so we get a 1 x 10,000 array
hsize_t dsDim[1] = {NUMPERDATASET};
//Create the data space.
hid_t dSpace = H5Screate_simple(1, dsDim, NULL);
//NUMDATASETS = MAXSSVALUE / NUMPERDATASET, where MAXSSVALUE = 4,500,000,000
for (unsigned long int i = 0UL; i < NUMDATASETS; i++){
for (unsigned long int j = 0UL; j < NUMPERDATASET; j++){
kValues[j] = k;
k += 1UL;
}
//Create the data set.
dssSet = H5Dcreate2(ssdb, g_strdup_printf("%lu", i), H5T_NATIVE_ULONG, dSpace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
//Write data to the data set.
H5Dwrite(dssSet, H5T_NATIVE_ULONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, kValues);
//Close the data set.
H5Dclose(dssSet);
}
//Release the data space
H5Sclose(dSpace);
//Close the data files.
H5Fclose(ssdb);
Это немного измененная версия моего кода для чтения.Есть более элегантные способы сделать это (то есть, я мог бы использовать гиперплоскости, чтобы получить значение), но это было самое чистое решение в отношении моего довольно дисциплинированного процесса разработки Agile / BDD.
unsigned long int getValueByIndex(unsigned long int nnValue){
//NUMPERDATASET = 10,000
unsigned long int ssValue[NUMPERDATASET];
//MAXSSVALUE = 4,500,000,000; i takes the smaller value of MAXSSVALUE or nnValue
//to avoid index out of range error
unsigned long int i = MIN(MAXSSVALUE-1,nnValue);
//Open the data file in read-write mode.
hid_t db = H5Fopen(_indexFilePath, H5F_ACC_RDONLY, H5P_DEFAULT);
//Create the data set. In this case, each dataset consists of a array of 10,000
//unsigned long int and is named according to its integer division value of i divided
//by the number per data set.
hid_t dSet = H5Dopen(db, g_strdup_printf("%lu", i / NUMPERDATASET), H5P_DEFAULT);
//Read the data set array.
H5Dread(dSet, H5T_NATIVE_ULONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, ssValue);
//Close the data set.
H5Dclose(dSet);
//Close the data file.
H5Fclose(db);
//Return the indexed value by using the modulus of i divided by the number per dataset
return ssValue[i % NUMPERDATASET];
}
Основноеtake-take - это внутренний цикл в коде записи и целочисленные операции деления и модуляции, чтобы получить индекс массива данных и индекс нужного значения в этом массиве.Дайте мне знать, если это достаточно ясно, чтобы вы могли собрать что-то подобное или лучше в h5py.В C это очень просто и дает мне значительно лучшее время чтения / записи по сравнению с решением по фрагментам данных.Плюс, поскольку я все равно не могу использовать сжатие с составными наборами данных, очевидный положительный эффект разбивки на куски - спорный вопрос, поэтому все мои соединения хранятся одинаково.