(C++) Написание базы данных в HDF5

Здравствуйте, это мой первый раз с HDF5, я пытаюсь создать таблицу базы данных, используя набор данных, созданный вручную. Файл уже создан и развернут, однако каждый раз, когда я пытаюсь вставить один реестр данных (каждый раз cv:: mat 1x6, так как я пытался вставить весь набор данных, и я не мог ни того, ни другого), я получаю следующее сообщение:

H5Dwrite (): выбор файла + смещение вне основного экстента: второстепенное пространство данных: выход за пределы диапазона завершается после вызова экземпляра 'H5::DataSetIException'

Код, который я использую, является следующим

cv::Mat label;
int size = data.length()/n_features_objects;

size_t size_[2]={1,(hsize_t)n_features_objects};
hsize_t chunk[2]={1,(hsize_t)n_features_objects};
hsize_t max_size[2]={H5S_UNLIMITED,(hsize_t)n_features_objects};
H5::DSetCreatPropList prop;
prop.setChunk(2,chunk);
H5::DataSpace ds(2, size_,max_size);
H5::IntType datatype =  H5::PredType::NATIVE_UINT64;
objects = labelFile.createDataSet(objects_name.toStdString(),datatype, ds,prop);

//get size of the dataset
H5::DataSpace ds = objects.getSpace();
int dims = ds.getSimpleExtentNdims();
hsize_t rc [dims];
ds.getSimpleExtentDims(rc);
int rows = (int)rc[0];

for(int z=0; z<size;z++)
{
    hsize_t new_size[2]={1, (hsize_t)n_features_objects};
    labels.extend(new_size);

    cv::Mat label_oreg = cv::Mat::zeros(cv::Size(n_features_objects,1), CV_32SC1);
    //Adding data registries one by one
    label_oreg.at<int>(0,0) = label_oreg.at<int>(z,0);
    label_oreg.at<int>(0,1) = label_oreg.at<int>(z,1);
    label_oreg.at<int>(0,2) = label_oreg.at<int>(z,2);
    label_oreg.at<int>(0,3) = label_oreg.at<int>(z,3);
    label_oreg.at<int>(0,4) = label_oreg.at<int>(z,4);
    label_oreg.at<int>(0,5) = label_oreg.at<int>(z,5);

    hsize_t rows_ext[2] ={1, (hsize_t)n_features_objects};
    hsize_t offset[2] ={(hsize_t)1, 0};
    ds = labels.getSpace();
    ds.selectHyperslab(H5S_SELECT_SET,rows_ext, offset);
    H5::DataSpace mem_space(2, rows_ext);
    labels.write(label.data, H5::PredType::NATIVE_INT32, mem_space, ds);
}

Кто-нибудь знает, что мне здесь не хватает? Я думаю, что результат странный, так как у меня всегда есть новый кусок данных, зарегистрированных в пространстве данных, чтобы использовать его в качестве реестра.

1 ответ

Исходя из названия и описания вашей проблемы, кажется, что вы хотели бы добавить (т.е. добавить) данные в набор данных HDF5 без перезаписи существующих данных, как таблица (в реляционной базе данных) позволит вам добавлять строки без перезаписи существующие.

Если это правильно, вот общий пример, который иллюстрирует, как это можно сделать с помощью HDFql в C++ (я не знаю, как это сделать в других API-интерфейсах C++ HDF5):

// declare variables
unsigned long long values[6];
char script[1024];
int row = 0;

// create HDF5 file "my_file.h5"
HDFql::execute("CREATE FILE my_file.h5");

// open HDF5 file "my_file.h5"
HDFql::execute("USE FILE my_file.h5");

// create HDF5 dataset "my_dataset" of datatype unsigned long long (64 bit) of two dimensions (unlimited x 6)
HDFql::execute("CREATE CHUNKED(1, 6) DATASET my_dataset AS UNSIGNED BIGINT(UNLIMITED, 6)");

// register variable "values" for subsequent use (by HDFql)
HDFql::variableRegister(values);

// keep reading data (from hypothetical function "read") and store it in variable "values" until there is no more to read
while(read(values))
{
    // prepare script that writes variable "values" into the last position of the first dimension of dataset "my_dataset" (thanks to a hyperslab selection)
    sprintf(script, "INSERT INTO my_dataset(%d:1:1:1) VALUES FROM MEMORY 0", row++);

    // execute script
    HDFql::execute(script);

    // extend first dimension of dataset "my_dataset" one unit
    HDFql::execute("ALTER DIMENSION my_dataset TO (+1)");
}

// unregister variable "values" as it is no longer used/needed (by HDFql)
HDFql::variableUnregister(values);
Другие вопросы по тегам