Поиск набора данных HDF5
В настоящее время я изучаю HDF5. Я прочитал интересные комментарии из потока "Оценка HDF5", и я понимаю, что HDF5 является решением выбора для хранения данных, но как вы его запрашиваете? Например, скажем, у меня есть большой файл, содержащий некоторые идентификаторы: есть ли способ быстро узнать, присутствует ли данный файл в файле?
Ответы
Ответ 1
Я думаю, что ответ "не напрямую".
Вот некоторые из способов, по которым, я думаю, вы могли бы достичь функциональности.
Использовать группы:
Иерархия групп может использоваться в виде дерева Radix Tree для хранения данных. Это, вероятно, недостаточно масштабируется, хотя.
Использовать наборы данных индекса:
HDF имеет ссылочный тип, который можно использовать для ссылки на основную таблицу из отдельных таблиц индексов. После записи основных данных можно использовать другие наборы данных, отсортированные по другим клавишам со ссылками. Например:
MainDataset (sorted on identifier)
0: { A, "C", 2 }
1: { B, "B", 1 }
2: { C, "A", 3 }
StringIndex
0: { "A", Reference ("MainDataset", 2) }
1: { "B", Reference ("MainDataset", 1) }
2: { "C", Reference ("MainDataset", 0) }
IntIndex
0: { 1, Reference ("MainDataset", 1) }
1: { 2, Reference ("MainDataset", 0) }
2: { 3, Reference ("MainDataset", 2) }
Чтобы использовать вышеизложенное, двоичный поиск должен быть записан при поиске поля в таблицах индекса.
В памяти Индекс:
В зависимости от размера набора данных может быть так же просто использовать индекс памяти, который читается/записывается в собственный набор данных, используя что-то вроде "boost:: serialize".
HDF5-FastQuery:
Этот документ (а также эта страница) описывают использование индексов растровых изображений для выполнения сложных запросов по набору данных HDF. Я не пробовал это.
Ответ 2
H5Lexists был введен для этого в HDF5 1.8.0:
http://www.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Exists
Вы также можете перебирать вещи, которые находятся в файле HDF5, с H5Literate:
http://www.hdfgroup.org/HDF5/doc/RM/RM_H5L.html#Link-Iterate
Но вы также можете вручную проверить предыдущие версии, пытаясь открыть набор данных. Мы используем такой код, чтобы иметь дело с любой версией HDF5:
bool DoesDatasetExist(const std::string& rDatasetName)
{
#if H5_VERS_MAJOR>=1 && H5_VERS_MINOR>=8
// This is a nice method for testing existence, introduced in HDF5 1.8.0
htri_t dataset_status = H5Lexists(mFileId, rDatasetName.c_str(), H5P_DEFAULT);
return (dataset_status>0);
#else
bool result=false;
// This is not a nice way of doing it because the error stack produces a load of 'HDF failed' output.
// The "TRY" macros are a convenient way to temporarily turn the error stack off.
H5E_BEGIN_TRY
{
hid_t dataset_id = H5Dopen(mFileId, rDatasetName.c_str());
if (dataset_id>0)
{
H5Dclose(dataset_id);
result = true;
}
}
H5E_END_TRY;
return result;
#endif
}
Ответ 3
Возможно, этот документ будет очень полезен для вас.
http://www.cse.ohio-state.edu/~wayi/papers/HDF5_SQL.pdf
Это то, что вам нужно? Вы можете запросить данные HDF5 с помощью SQL, который является декларативным языком.
В отличие от FastQuery, в этой работе нет индекса, но наша группа также предоставляет версию с открытым исходным кодом с индексом растрового изображения.
Кроме того, если вы хотите завершить запрос (особенно для агрегации) в режиме реального времени, вы должны рассмотреть примерную агрегацию или онлайн-агрегацию. Я также разработал некоторые продукты, которые непосредственно работают на HDF5.
Кроме того, некоторые запросы по HDF5 могут быть намного сложнее, чем вы видели в реляционных базах данных. Некоторые запросы ориентированы на массивы, а не реляционные таблицы. Просто google "SciQL", тогда вы можете найти сложные и уникальные типы запросов для модели данных на основе массива, что, безусловно, может быть применено к HDF5. Вам нужно выполнять такие запросы? Я также разработал продукт для поддержки некоторых сложных типов запросов.
Ответ 4
Что вы подразумеваете под идентификатором? Если вы имеете в виду атрибут, проверьте этот учебник. В C:
status = H5Aread(attr_id, mem_type_id, buf);
status = H5Awrite(attr_id, mem_type_id, buf);