BerkeleyDB Db-> gt; не работает при использовании пользовательской функции сравнения

В программе на C ++ я пытаюсь установить пользовательскую функцию сравнения для БД Berkeley, используя Db::set_bt_function функция-член (БД открывается как тип BTREE). Мой код работает нормально, когда я не меняю функцию сравнения; Я могу поставить и получить ключи / значения, используя Db::put а также Db::get,

Чтобы попробовать set_bt_function Методом я определил свое собственное «лексикографическое сравнение» следующим образом:

int compkeys(Db *db, const Dbt *dbt1, const Dbt *dbt2, size_t *locp) {
size_t s = dbt1->get_size() > dbt2->get_size() ? dbt2->get_size() : dbt1->get_size();
int c = std::memcmp(dbt1->get_data(), dbt2->get_data(), s);
if(c != 0) return c;
if(dbt1->get_size() < dbt2->get_size()) return -1;
if(dbt1->get_size() > dbt2->get_size()) return 1;
return 0;
}

Так что это должно привести к тому же поведению, что и мой ссылочный код, когда функция сравнения не изменилась, поскольку по умолчанию в Berkeley DB используется лексикографический порядок.

Тем не менее, при использовании этой функции сравнения, Db::get больше не работает Возвращает -30999 (DB_BUFFER_SMALL).

Вот что я делаю, чтобы получить значение, связанное с данным ключом:

Db* _dbm = ... /* DB is open */
std::vector<char> mykey;
... /* mykey is set to some content */
Dbt db_key((void*)(mykey.data()), uint32_t(mykey.size()));
Dbt db_data;
db_key.set_flags(DB_DBT_USERMEM);
db_data.set_flags(DB_DBT_MALLOC);
int status = _dbm->get(NULL, &db_key, &db_data, 0);
... /* check status, do something with db_data */
free(db_data.get_data());

Любая идея, почему этот код работает, когда я не устанавливаю функцию сравнения, и нет, когда я?

Примечание: если я получаю доступ к ключу / значениям с помощью курсора (Dbc::getУ меня нет этой проблемы.

2

Решение

DB_BUFFER_SMALL ошибка в этом случае жалуется на ваш db_key Dbt, Вам нужно позвонить db_key.set_ulen(uint32_t(mykey.size())) сообщить BDB, сколько места вы выделили для хранения ключей, которые выходят из базы данных.

Все становится немного страннее, когда вы используете пользовательскую функцию сравнения. Вы можете иметь данные в ключе, который не является частью сравнения — и не в ключе, который вы передали get(), По этой причине BDB возвращает ключ, найденный в базе данных в вашем ключе db_key.

При настройке ulenсделайте его достаточно большим, чтобы вместить любой ключ, который может вернуться из базы данных. Вы можете обнаружить, что разумнее просто держать char массив в стеке, чтобы иметь дело с этим ключом вход / выход поведение.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]