Commit b23286ea authored by Matthieu Dorier's avatar Matthieu Dorier

DataStore functionalities (and iterators) done

parent e9c43787
......@@ -87,6 +87,7 @@ int main(int argc, char *argv[])
ret = sdskv_provider_register(mid, sdskv_mplex_id, SDSKV_ABT_POOL_DEFAULT, &sdskv_prov);
ASSERT(ret == 0, "sdskv_provider_register() failed (ret = %d)\n", ret);
// XXX creating the database - this should come from a config file
sdskv_database_id_t db_id;
ret = sdskv_provider_add_database(sdskv_prov, "hepnosdb", KVDB_MAP, SDSKV_COMPARE_DEFAULT, &db_id);
ASSERT(ret == 0, "sdskv_provider_add_database() failed (ret = %d)\n", ret);
......
#ifndef __HEPNOS_DATA_SET_H
#define __HEPNOS_DATA_SET_H
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <hepnos/Exception.hpp>
#include <hepnos/DataStore.hpp>
namespace hepnos {
......@@ -13,11 +19,76 @@ class DataSet {
DataSet();
DataSet(DataStore& ds, uint8_t level, const std::string& name);
DataSet(DataStore& ds, uint8_t level, const std::string& fullname);
DataStore* m_datastore;
uint8_t m_level;
std::string m_name;
DataSet(DataStore& ds, uint8_t level, const std::string& container, const std::string& name);
bool storeBuffer(const std::string& key, const std::vector<char>& buffer);
bool loadBuffer(const std::string& key, std::vector<char>& buffer) const;
DataStore* m_datastore;
uint8_t m_level;
std::string m_container;
std::string m_name;
public:
const std::string& name() const {
return m_name;
}
const std::string container() const {
return m_container;
}
std::string fullname() const {
std::stringstream ss;
if(m_container.size() != 0)
ss << m_container << "/";
ss << m_name;
return ss.str();
}
DataSet next() const;
bool valid() const;
template<typename K, typename V>
bool store(const K& key, const V& value) {
std::stringstream ss_key, ss_value;
ss_key << key;
boost::archive::binary_oarchive oa(ss_value);
try {
oa << value;
} catch(...) {
throw Exception("Exception occured during serialization");
}
std::string serialized = ss_value.str();
std::vector<char> buffer(serialized.begin(), serialized.end());
return storeBuffer(ss_key.str(), buffer);
}
template<typename K, typename V>
bool load(const K& key, V& value) const {
std::stringstream ss_key;
ss_key << key;
std::vector<char> buffer;
if(!loadBuffer(key, buffer)) {
return false;
}
try {
std::string serialized(buffer.begin(), buffer.end());
std::stringstream ss(serialized);
boost::archive::binary_iarchive ia(ss);
ia >> value;
} catch(...) {
throw Exception("Exception occured during serialization");
}
return true;
}
bool operator==(const DataSet& other) const;
};
}
......
#ifndef __HEPNOS_DATA_STORE_H
#define __HEPNOS_DATA_STORE_H
#include <vector>
#include <string>
#include <memory>
......@@ -10,6 +11,8 @@ class DataSet;
class DataStore {
friend class DataSet;
public:
DataStore(const std::string& configFile);
......@@ -50,6 +53,16 @@ class DataStore {
class Impl;
std::unique_ptr<Impl> m_impl;
bool load(uint8_t level, const std::string& containerName,
const std::string& objectName, std::vector<char>& data) const;
bool store(uint8_t level, const std::string& containerName,
const std::string& objectName, const std::vector<char>& data);
size_t nextKeys(uint8_t level, const std::string& containerName,
const std::string& lower,
std::vector<std::string>& keys, size_t maxKeys) const;
};
class DataStore::const_iterator {
......
......@@ -5,11 +5,66 @@ namespace hepnos {
DataSet::DataSet()
: m_datastore(nullptr)
, m_level(0)
, m_container("")
, m_name("") {}
DataSet::DataSet(DataStore& ds, uint8_t level, const std::string& name)
DataSet::DataSet(DataStore& ds, uint8_t level, const std::string& fullname)
: m_datastore(&ds)
, m_level(level) {
size_t p = fullname.find_last_of('/');
if(p == std::string::npos) {
m_name = fullname;
} else {
m_name = fullname.substr(p+1);
m_container = fullname.substr(0, p);
}
}
DataSet::DataSet(DataStore& ds, uint8_t level, const std::string& container, const std::string& name)
: m_datastore(&ds)
, m_level(level)
, m_container(container)
, m_name(name) {}
DataSet DataSet::next() const {
if(!valid()) return DataSet();
std::vector<std::string> keys;
size_t s = m_datastore->nextKeys(m_level, m_container, m_name, keys, 1);
if(s == 0) return DataSet();
return DataSet(*m_datastore, m_level, m_container, keys[0]);
}
bool DataSet::valid() const {
return m_datastore != nullptr;
}
bool DataSet::storeBuffer(const std::string& key, const std::vector<char>& buffer) {
if(!valid()) {
throw Exception("Calling store() on invalid DataSet");
}
// forward the call to the datastore's store function
return m_datastore->store(0, fullname(), key, buffer);
}
bool DataSet::loadBuffer(const std::string& key, std::vector<char>& buffer) const {
if(!valid()) {
throw Exception("Calling load() on invalid DataSet");
}
// forward the call to the datastore's load function
std::stringstream ss;
if(m_container.size() != 0)
ss << m_container << "/";
ss << m_name;
return m_datastore->load(0, fullname(), key, buffer);
}
bool DataSet::operator==(const DataSet& other) const {
return m_datastore == other.m_datastore
&& m_level == other.m_level
&& m_container == other.m_container
&& m_name == other.m_name;
}
}
This diff is collapsed.
......@@ -3,6 +3,8 @@
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <memory>
namespace hepnos {
......@@ -36,12 +38,19 @@ typedef std::unique_ptr<DataStoreEntry, DataStoreEntryDeleter> DataStoreEntryPtr
inline DataStoreEntryPtr make_datastore_entry(uint8_t level, const std::string& name) {
size_t s = sizeof(DataStoreEntry) + name.size();
DataStoreEntry* entry = static_cast<DataStoreEntry*>(malloc(s));
DataStoreEntry* entry = static_cast<DataStoreEntry*>(calloc(1,s));
entry->m_level = level;
strcpy(entry->m_fullname, name.c_str());
return DataStoreEntryPtr(entry, DataStoreEntryDeleter());
}
inline DataStoreEntryPtr make_datastore_entry(uint8_t level, size_t nameSize) {
size_t s = sizeof(DataStoreEntry) + nameSize;
DataStoreEntry* entry = static_cast<DataStoreEntry*>(calloc(1,s));
entry->m_level = level;
return DataStoreEntryPtr(entry, DataStoreEntryDeleter());
}
}
#endif
add_executable(example example.cpp)
target_link_libraries(example hepnos)
target_link_libraries(example hepnos ${Boost_LIBRARIES})
......@@ -7,8 +7,56 @@ using namespace hepnos;
int main(int argc, char** argv) {
DataStore datastore(argv[1]);
DataSet dataset = datastore.createDataSet("myproject");
auto it = datastore.find("myproject");
std::cout << "====== Testing createDataSet =======" << std::endl;
DataSet dataset1 = datastore.createDataSet("AAAA");
std::cout << "Created " << dataset1.fullname() << std::endl;
DataSet dataset2 = datastore.createDataSet("BBB");
std::cout << "Created " << dataset2.fullname() << std::endl;
DataSet dataset3 = datastore.createDataSet("sssd");
std::cout << "Created " << dataset3.fullname() << std::endl;
DataSet dataset4 = datastore.createDataSet("myproject");
std::cout << "Created " << dataset4.fullname() << std::endl;
std::cout << "====== Testing next ================" << std::endl;
DataSet n = dataset4.next();
std::cout << "Next is " << n.fullname() << std::endl;
std::cout << "====== Testing find ================" << std::endl;
for(auto it = datastore.find("BBB");
it != datastore.end(); ++it) {
std::cout << "Dataset from iterator: " << it->fullname() << std::endl;
}
std::cout << "====== Testing begin ===============" << std::endl;
for(auto it = datastore.begin();
it != datastore.end(); ++it) {
std::cout << "Dataset from iterator: " << it->fullname() << std::endl;
}
std::cout << "====== Testing lower_bound =========" << std::endl;
{
auto it1 = datastore.lower_bound("BBB");
std::cout << "lower_bound(\"BBB\") = " << it1->fullname() << " (should be \"BBB\")" << std::endl;
auto it2 = datastore.lower_bound("BAA");
std::cout << "lower_bound(\"BAA\") = " << it2->fullname() << " (should be \"BBB\")" << std::endl;
}
std::cout << "====== Testing upper_bound =========" << std::endl;
{
auto it1 = datastore.upper_bound("myproject");
std::cout << "upper_bound(\"myproject\") = " << it1->fullname() << " (should be \"sssd\")" << std::endl;
auto it2 = datastore.upper_bound("myprojex");
std::cout << "upper_bound(\"myprojex\") = " << it2->fullname() << " (should be \"sssd\")" << std::endl;
auto it3 = datastore.upper_bound("myproj");
std::cout << "upper_bound(\"myproject\") = " << it3->fullname() << " (should be \"myproject\")" << std::endl;
}
std::cout << "====== Testing store ===============" << std::endl;
{
std::string key("matthieu");
std::string value("mdorier@anl.gov");
dataset4.store(key, value);
}
std::cout << "====== Testing load ===============" << std::endl;
{
std::string key("matthieu");
std::string value;
dataset4.load(key, value);
std::cout << "load(\"matthieu\") = " << value << std::endl;
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment