Как вставить целочисленные значения в rockdb, например uint64_t?

Я протестировал следующий код для вставки целочисленных значений, таких как uint64_t, в базу данных rockdb, используя приведение типов. Это правильный подход?

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>

#include<unistd.h>
#include<stdint.h>

const char DBPath[] = "/tmp/test_sample";

#include "rocksdb/c.h"

int main(int argc, char **argv){

   // Intialize basic parameters
   rocksdb_t *db;
   rocksdb_options_t *options = rocksdb_options_create();

   // Create the database if it's not already present
   rocksdb_options_set_create_if_missing(options,1);

   // Open database
   char *err = NULL;
   db = rocksdb_open(options,DBPath,&err);
   assert(!err);

   //Put key value
   //Insert insert value to the database
   rocksdb_writeoptions_t *writeoptions = rocksdb_writeoptions_create();
   int intKey = 256;
   int intValue = 256*256;

   const char* key;
   const char* value; 

   //Convert integer value to char array
   key = (char*)&intKey; 
   value = (char*)&intValue ; 

   rocksdb_put(db,writeoptions,key,strlen(key),value,strlen(value) + 1,&err);

   assert(!err);

   //Cleanup 
   rocksdb_writeoptions_destroy(writeoptions);
   rocksdb_options_destroy(options);
   rocksdb_close(db);

   return 0;
}

Я сослался на следующую ссылку: Можно ли хранить целые ключи/значения в LevelDB?


person kaviranga    schedule 18.04.2019    source источник
comment
strlen(value) вызывает неопределенное поведение. value = (char*)&intValue; не приводит к тому, что value является строкой с нулевым завершением. Передача strlen(value) будет считывать неопределенное количество символов до тех пор, пока strlen просто не встретится с 0 где-то в стеке вашей программы, вероятно, 4-м байтом в памяти 256x256, если используется аппаратное обеспечение с прямым порядком байтов.   -  person David C. Rankin    schedule 19.04.2019


Ответы (2)


Ваш подход не переносим. Что вы делаете, так это просто сбрасываете целочисленное представление в двоичное поле. Если код десериализации вашего int имеет другое понимание int, это не сработает. Вы должны использовать библиотеку сериализации, чтобы получить стабильное двоичное представление int, например. протобуф/плоские буферы.

Насколько вероятно, что это взорвется на вашем лице? Не знаю, зависит от вашей системы. Обратите внимание, что RocksDB внутри использует сериализованные представления для всех целочисленных типов: util/coding. ч

person midor    schedule 20.04.2019

Есть одно существенное различие между связанным сообщением и вашим собственным кодом: они используют sizeof, а вы используете strlen. strlen ищет в памяти нулевой байт. Это имеет смысл только тогда, когда у вас действительно есть символьная строка с нулевым завершением.

Здесь вы хотите сохранить целочисленные данные, независимо от того, содержат ли они нулевые байты или нет. Таким образом, вы должны объявить размер этих данных равным sizeof(int):

rocksdb_put(db,writeoptions,key,sizeof(int),value,sizeof(int),&err);
person Serge Ballesta    schedule 18.04.2019