Я использую Berkeley DB C ++ API 6.0 на OSX.
Мое приложение создает базу данных со следующими таблицами:
Основная таблица: (int, myStruct) -> myStruct является буфером.
Вторичный индекс: (float, myStruct) -> Ключ с плавающей запятой — это информация, которую я получаю в буфере myStruct со следующим обратным вызовом.
int meanExtractor(Db *sdbp,
const Dbt *pkey,
const Dbt *pdata,
Dbt *skey)
{
Dbt data = *pdata;
feature<float> f;
restoreDescriptor(f, data);
void* mean = malloc( sizeof(float) );
memcpy( mean, &f.mean, sizeof(float) );
skey->set_data(mean);
skey->set_size(sizeof(float));
skey->set_flags( DB_DBT_APPMALLOC );
return 0;
}
Когда я перебираю вторичный индекс и печатаю пары ключ / данные, плавающие ключи хорошо сохраняются.
Моя проблема в том, что я не могу запросить эту таблицу. Я хотел бы выполнить этот SQL-запрос, например:
SELECT * FROM secondary index WHERE keys > 1.5 && keys < 3.4
Моя таблица заполнена 50000 клавишами от 0,001 до 49,999. Дело в том, когда я использую этот метод, например:
I assume the Db and the table are already opened
float i = 0.05;
Dbt key = Dbt(&i, sizeof(float));
Dbc* dbc;
db->cursor( txn, &dbc, 0 );
int ret;
ret = dbc->get( key, &vald, DB_SET_RANGE));
Получил этот ключ: 0,275. Он должен получить 0,05 (потому что он существует) или по крайней мере 0,051.
И для любого другого плавающего значения в ключе Dbt, это дает мне несколько глупых значений. Если я поставлю флаг DB_SET, он просто не найдет никаких ключей.
Моя идея состояла в том, чтобы установить курсор на наименьшую клавишу, большую или равную моей клавише, а затем повторять с флагом DB_NEXT, пока я не достигну конца моего диапазона.
Это должно происходить из алгоритма поиска BerkeleyDB, но я видел (полезные, но недостаточные) примеры, которые делают именно то, что мне нужно, но с Java API, так что это доказывает, что это возможно сделать …
Я довольно застрял с этим, поэтому, если у кого-то уже была эта проблема, спасибо за помощь. Я могу поставить другие части моего кода, если это необходимо.
Я использовал пользовательскую функцию bt_compare в своем вторичном индексе, и теперь она отлично работает.
Других решений пока нет …