estraier / tkrzw

a set of implementations of DBM
Apache License 2.0
164 stars 20 forks source link

How to store/retrieve in tkrzw database (C++): a double scalar, an array of doubles and text #48

Open torfinno opened 3 months ago

torfinno commented 3 months ago

Hi, I have been reading up on your 'tkrzw' as a potential replacement for Berkeley DB.

Based on some 'tkrzw' examples, I have tried to store and retrieve double scalars, vectors of doubles and text from a tkrzw-database. Unfortunately, I have not managed to create working code. I am using Linux.

Therefore, could you please give an example on how to save and retrieve from a tkrzw-database: a) double scalars;
b) vector of doubles; c) some text.

As an example, consider some daily temperature data: ~ temperatures = [ 19.1, 20.1, 21.1 ]; // C++: vector temperatures average = 20.1; // C++: double average; description = "The average is the sum of temperatures divided by three"; // C++: string description ~

Questions: 1: How to save the above into a tkrzw-database?

  1. How to read back the saved information at a later stage, to do further numerical processing?

Best regards

estraier commented 3 months ago

This is an working code. If you are not particular to space efficiency, using JSON is also a practical solution.

include "tkrzw_dbm_hash.h"

include

include

include

using namespace tkrzw;

// Serializes a value of a basic type into a string.
template std::string SerializeBasicValue(T value) { std::string serialized = std::string(sizeof(T), 0); char* ptr = serialized.data(); std::memcpy(ptr, &value, sizeof(value)); return serialized; }

// Deserializes a string into a value of a basic type.
template T DeserializeBasicValue(const std::string& serialized) { T value; if (serialized.size() >= sizeof(T)) { std::memcpy(&value, serialized.data(), sizeof(T)); } else { std::memset(&value, 0, sizeof(T)); } return value; }

// Serializes an array of a basic type into a string.
template std::string SerializeBasicArray(const std::vector& array) { std::string serialized = std::string(sizeof(T) array.size(), 0); char ptr = serialized.data(); for (const T elem : array) { std::memcpy(ptr, &elem, sizeof(elem)); ptr += sizeof(elem); } return serialized; }

// Deserializes a string into an array of a basic type.
template std::vector DeserializeBasicArray(const std::string& serialized) { int64_t num_elems = serialized.size() / sizeof(T); std::vector array; array.reserve(num_elems); const char* ptr = serialized.data(); while (num_elems > 0) { T elem = 0; std::memcpy(&elem, ptr, sizeof(elem)); array.push_back(elem); ptr += sizeof(elem); num_elems--; } return array; }

int main(int argc, char** argv) { HashDBM dbm; const std::vector temperatures = {19.1, 20.1, 21.1}; const double average = 20.1; const std::string description = "The average is the sum of temperatures divided by three";

// Opens the dtabase.
dbm.Open("mydatabase.tkh", true);

// Stores a serialized double array.
dbm.Set("temperatures", SerializeBasicArray(temperatures));

// Stores a serialized double value.
dbm.Set("average", SerializeBasicValue(average));

// Stores a string as-is.
dbm.Set("description", description);

// Closes the database.
dbm.Close();

// Opens the database again, as read-only one.
dbm.Open("mydatabase.tkh", false);

// Retrieves the serialized double array.
std::string value; if (dbm.Get("temperatures", &value).IsOK()) { for (const auto& elem : DeserializeBasicArray(value)) { std::cout << elem << std::endl; } }

// Retrieves the serialized double value.
value.clear(); if (dbm.Get("average", &value).IsOK()) { std::cout << DeserializeBasicValue(value) << std::endl; }

// Retrieves the string as-is.
value.clear(); if (dbm.Get("description", &value).IsOK()) { std::cout << value << std::endl; }

// Closes the database.
dbm.Close();

return 0; }

estraier commented 3 months ago

I pushed some code to make serialization/deserialization tasks easier. Those functions are implemented as SerializeBasicValue/DeerializeBasicValue and SerializeBasicVector/DeerializeBasicVector. And, you can store serialized values into a string map, which can be serialized as a string by SerializeStrMap.

This example code clarifies the usage. https://github.com/estraier/tkrzw/blob/master/example/struct_ex1.cc