Dans un programme C++, j'essaie de définir une fonction de comparaison personnalisée pour une base de données Berkeley, à l'aide de la commande Db::set_bt_function
(la BD est ouverte comme un type BTREE). Mon code fonctionne bien lorsque je ne modifie pas la fonction de comparaison ; je peux mettre et récupérer des clés/valeurs en utilisant la fonction Db::put
y Db::get
.
Pour essayer le set_bt_function
j'ai défini ma propre "comparaison lexicographique" comme suit :
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;
}
Cela devrait donc conduire exactement au même comportement que mon code de référence, lorsque la fonction de comparaison n'est pas modifiée, puisque par défaut Berkeley DB utilise l'ordre lexicographique.
Pourtant, en utilisant cette fonction de comparaison, Db::get
ne fonctionne plus. Il renvoie -30999 (DB_BUFFER_SMALL).
Voici ce que je fais pour obtenir la valeur associée à une clé donnée :
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());
Savez-vous pourquoi ce code fonctionne lorsque je ne configure pas la fonction de comparaison, et ne fonctionne pas lorsque je le fais ?
Remarque : si j'accède aux touches/valeurs en utilisant un curseur ( Dbc::get
) Je n'ai pas ce problème.