Commit 012de19d authored by Matthieu Dorier's avatar Matthieu Dorier
Browse files

added sdskv_exists and a new way of adding databases

parent 90bd4f4d
...@@ -140,6 +140,20 @@ int sdskv_length(sdskv_provider_handle_t handle, ...@@ -140,6 +140,20 @@ int sdskv_length(sdskv_provider_handle_t handle,
sdskv_database_id_t db_id, const void *key, sdskv_database_id_t db_id, const void *key,
hg_size_t ksize, hg_size_t* vsize); hg_size_t ksize, hg_size_t* vsize);
/**
* @brief Checks if the given key exists in the database.
*
* @param[in] handle provider handle
* @param[in] db_id database id
* @param[in] key key to lookup
* @param[in] ksize size of the key
* @param[out] flag 1 if the key exists, 0 otherwise
*
* @return SDSKV_SUCCESS or error code defined in sdskv-common.h
*/
int sdskv_exists(sdskv_provider_handle_t handle,
sdskv_database_id_t db_id, const void *key,
hg_size_t ksize, int* flag);
/** /**
* @brief Erases the key/value pair pointed by the given key. * @brief Erases the key/value pair pointed by the given key.
* *
......
...@@ -8,7 +8,7 @@ extern "C" { ...@@ -8,7 +8,7 @@ extern "C" {
typedef enum sdskv_db_type_t typedef enum sdskv_db_type_t
{ {
KVDB_MAP, /* Datastore implementation using std::map */ KVDB_MAP = 0, /* Datastore implementation using std::map */
KVDB_BWTREE, /* Datastore implementation using a BwTree */ KVDB_BWTREE, /* Datastore implementation using a BwTree */
KVDB_LEVELDB, /* Datastore implementation using LevelDB */ KVDB_LEVELDB, /* Datastore implementation using LevelDB */
KVDB_BERKELEYDB /* Datasotre implementation using BerkeleyDB */ KVDB_BERKELEYDB /* Datasotre implementation using BerkeleyDB */
......
...@@ -22,6 +22,19 @@ extern "C" { ...@@ -22,6 +22,19 @@ extern "C" {
typedef struct sdskv_server_context_t* sdskv_provider_t; typedef struct sdskv_server_context_t* sdskv_provider_t;
typedef int (*sdskv_compare_fn)(const void*, size_t, const void*, size_t); typedef int (*sdskv_compare_fn)(const void*, size_t, const void*, size_t);
typedef struct sdskv_server_context_t* sdskv_provider_t;
typedef int (*sdskv_compare_fn)(const void*, size_t, const void*, size_t);
typedef struct sdskv_config_t {
const char* db_name; // name of the database
const char* db_path; // path to the database
sdskv_db_type_t db_type; // type of database
sdskv_compare_fn db_comparison_fn; // comparison function (can be NULL)
int db_no_overwrite; // prevents overwritting data if set to 1
} sdskv_config_t;
#define SDSKV_CONFIG_DEFAULT { "", "", KVDB_MAP, SDSKV_COMPARE_DEFAULT, 0 }
/** /**
* @brief Creates a new provider. * @brief Creates a new provider.
* *
...@@ -58,6 +71,23 @@ int sdskv_provider_add_database( ...@@ -58,6 +71,23 @@ int sdskv_provider_add_database(
const char* db_path, const char* db_path,
sdskv_db_type_t db_type, sdskv_db_type_t db_type,
sdskv_compare_fn comp_fn, sdskv_compare_fn comp_fn,
sdskv_database_id_t* sb_id)
__attribute__((deprecated("use sdskv_provider_attach_database instead")));
/**
* Makes the provider start managing a database. The database will
* be created if it does not exist. Otherwise, the provider will start
* to manage the existing database.
*
* @param[in] provider provider
* @param[in] config configuration object to use for the database
* @param[out] db_id resulting id identifying the database
*
* @return SDSKV_SUCCESS or error code defined in sdskv-common.h
*/
int sdskv_provider_attach_database(
sdskv_provider_t provider,
const sdskv_config_t* config,
sdskv_database_id_t* sb_id); sdskv_database_id_t* sb_id);
/** /**
......
...@@ -30,7 +30,7 @@ BerkeleyDBDataStore::~BerkeleyDBDataStore() { ...@@ -30,7 +30,7 @@ BerkeleyDBDataStore::~BerkeleyDBDataStore() {
delete _dbenv; delete _dbenv;
}; };
void BerkeleyDBDataStore::createDatabase(const std::string& db_name, const std::string& db_path) { bool BerkeleyDBDataStore::openDatabase(const std::string& db_name, const std::string& db_path) {
int status = 0; int status = 0;
if (!db_path.empty()) { if (!db_path.empty()) {
...@@ -125,9 +125,7 @@ void BerkeleyDBDataStore::createDatabase(const std::string& db_name, const std:: ...@@ -125,9 +125,7 @@ void BerkeleyDBDataStore::createDatabase(const std::string& db_name, const std::
std::cerr << "status = " << status << std::endl; std::cerr << "status = " << status << std::endl;
} }
} }
assert(status == 0); // fall over return (status == 0);
// debugging support?
}; };
void BerkeleyDBDataStore::set_comparison_function(comparator_fn less) { void BerkeleyDBDataStore::set_comparison_function(comparator_fn less) {
...@@ -137,7 +135,11 @@ void BerkeleyDBDataStore::set_comparison_function(comparator_fn less) { ...@@ -137,7 +135,11 @@ void BerkeleyDBDataStore::set_comparison_function(comparator_fn less) {
bool BerkeleyDBDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) { bool BerkeleyDBDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) {
int status = 0; int status = 0;
bool success = false; bool success = false;
if(_no_overwrite) {
if(exists(key)) return false;
}
// IGNORE case deals with redundant puts (where key/value is the same). In BerkeleyDB a // IGNORE case deals with redundant puts (where key/value is the same). In BerkeleyDB a
// redundant may overwrite previous value which is fine when key/value is the same. // redundant may overwrite previous value which is fine when key/value is the same.
// ALLOW case deals with actual duplicates (where key is the same but value is different). // ALLOW case deals with actual duplicates (where key is the same but value is different).
...@@ -164,6 +166,12 @@ bool BerkeleyDBDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) { ...@@ -164,6 +166,12 @@ bool BerkeleyDBDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) {
return success; return success;
}; };
bool BerkeleyDBDataStore::exists(const ds_bulk_t &key) {
Dbt db_key((void*)key.data(), key.size());
int status = _dbm->exists(NULL, &db_key, 0);
return status == 0;
}
bool BerkeleyDBDataStore::erase(const ds_bulk_t &key) { bool BerkeleyDBDataStore::erase(const ds_bulk_t &key) {
Dbt db_key((void*)key.data(), key.size()); Dbt db_key((void*)key.data(), key.size());
int status = _dbm->del(NULL, &db_key, 0); int status = _dbm->del(NULL, &db_key, 0);
...@@ -194,14 +202,14 @@ bool BerkeleyDBDataStore::get(const ds_bulk_t &key, ds_bulk_t &data) { ...@@ -194,14 +202,14 @@ bool BerkeleyDBDataStore::get(const ds_bulk_t &key, ds_bulk_t &data) {
success = true; success = true;
} }
else { else {
std::cerr << "BerkeleyDBDataStore::get: BerkeleyDB error on Get = " << status << std::endl; //std::cerr << "BerkeleyDBDataStore::get: BerkeleyDB error on Get = " << status << std::endl;
} }
if (success && _eraseOnGet) { if (success && _eraseOnGet) {
status = _dbm->del(NULL, &db_key, 0); status = _dbm->del(NULL, &db_key, 0);
if (status != 0) { if (status != 0) {
success = false; success = false;
std::cerr << "BerkeleyDBDataStore::get: BerkeleyDB error on delete (eraseOnGet) = " << status << std::endl; //std::cerr << "BerkeleyDBDataStore::get: BerkeleyDB error on delete (eraseOnGet) = " << status << std::endl;
} }
} }
......
...@@ -27,20 +27,24 @@ class BerkeleyDBDataStore : public AbstractDataStore { ...@@ -27,20 +27,24 @@ class BerkeleyDBDataStore : public AbstractDataStore {
BerkeleyDBDataStore(); BerkeleyDBDataStore();
BerkeleyDBDataStore(Duplicates duplicates, bool eraseOnGet, bool debug); BerkeleyDBDataStore(Duplicates duplicates, bool eraseOnGet, bool debug);
virtual ~BerkeleyDBDataStore(); virtual ~BerkeleyDBDataStore();
virtual void createDatabase(const std::string& db_name, const std::string& path); virtual bool openDatabase(const std::string& db_name, const std::string& path);
virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data); virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data);
virtual bool get(const ds_bulk_t &key, ds_bulk_t &data); virtual bool get(const ds_bulk_t &key, ds_bulk_t &data);
virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data); virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data);
virtual bool exists(const ds_bulk_t &key);
virtual bool erase(const ds_bulk_t &key); virtual bool erase(const ds_bulk_t &key);
virtual void set_in_memory(bool enable); // enable/disable in-memory mode virtual void set_in_memory(bool enable); // enable/disable in-memory mode
virtual void set_comparison_function(comparator_fn less); virtual void set_comparison_function(comparator_fn less);
virtual void set_no_overwrite() {
_no_overwrite = true;
}
protected: protected:
virtual std::vector<ds_bulk_t> vlist_keys(const ds_bulk_t &start, size_t count, const ds_bulk_t &prefix); virtual std::vector<ds_bulk_t> vlist_keys(const ds_bulk_t &start, size_t count, const ds_bulk_t &prefix);
virtual std::vector<std::pair<ds_bulk_t,ds_bulk_t>> vlist_keyvals(const ds_bulk_t &start_key, size_t count, const ds_bulk_t &); virtual std::vector<std::pair<ds_bulk_t,ds_bulk_t>> vlist_keyvals(const ds_bulk_t &start_key, size_t count, const ds_bulk_t &);
DbEnv *_dbenv = nullptr; DbEnv *_dbenv = nullptr;
Db *_dbm = nullptr; Db *_dbm = nullptr;
DbWrapper* _wrapper = nullptr; DbWrapper* _wrapper = nullptr;
bool _no_overwrite = false;
}; };
#endif // bdb_datastore_h #endif // bdb_datastore_h
...@@ -24,7 +24,7 @@ BwTreeDataStore::~BwTreeDataStore() { ...@@ -24,7 +24,7 @@ BwTreeDataStore::~BwTreeDataStore() {
#endif #endif
}; };
void BwTreeDataStore::createDatabase(const std::string& db_name, const std::string& path) { bool BwTreeDataStore::openDatabase(const std::string& db_name, const std::string& path) {
_tree = new BwTree<ds_bulk_t, ds_bulk_t, _tree = new BwTree<ds_bulk_t, ds_bulk_t,
ds_bulk_less, ds_bulk_equal, ds_bulk_hash, ds_bulk_less, ds_bulk_equal, ds_bulk_hash,
ds_bulk_equal, ds_bulk_hash>(); ds_bulk_equal, ds_bulk_hash>();
...@@ -36,6 +36,7 @@ void BwTreeDataStore::createDatabase(const std::string& db_name, const std::stri ...@@ -36,6 +36,7 @@ void BwTreeDataStore::createDatabase(const std::string& db_name, const std::stri
} }
_tree->UpdateThreadLocal(1); _tree->UpdateThreadLocal(1);
_tree->AssignGCID(0); _tree->AssignGCID(0);
return true;
}; };
void BwTreeDataStore::set_comparison_function(comparator_fn less) { void BwTreeDataStore::set_comparison_function(comparator_fn less) {
...@@ -46,6 +47,10 @@ bool BwTreeDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) { ...@@ -46,6 +47,10 @@ bool BwTreeDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) {
std::vector<ds_bulk_t> values; std::vector<ds_bulk_t> values;
bool success = false; bool success = false;
if(_no_overwrite) {
if(exists(key)) return false;
}
if(!_tree) return false; if(!_tree) return false;
if (_duplicates == Duplicates::ALLOW) { if (_duplicates == Duplicates::ALLOW) {
......
...@@ -14,19 +14,27 @@ public: ...@@ -14,19 +14,27 @@ public:
BwTreeDataStore(); BwTreeDataStore();
BwTreeDataStore(Duplicates duplicates, bool eraseOnGet, bool debug); BwTreeDataStore(Duplicates duplicates, bool eraseOnGet, bool debug);
virtual ~BwTreeDataStore(); virtual ~BwTreeDataStore();
virtual void createDatabase(const std::string& db_name, const std::string& path); virtual bool openDatabase(const std::string& db_name, const std::string& path);
virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data); virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data);
virtual bool get(const ds_bulk_t &key, ds_bulk_t &data); virtual bool get(const ds_bulk_t &key, ds_bulk_t &data);
virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data); virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data);
virtual bool exists(const ds_bulk_t &key) {
ds_bulk_t data;
return get(key,data);
}
virtual bool erase(const ds_bulk_t &key); virtual bool erase(const ds_bulk_t &key);
virtual void set_in_memory(bool enable); // a no-op virtual void set_in_memory(bool enable); // a no-op
virtual void set_comparison_function(comparator_fn less); virtual void set_comparison_function(comparator_fn less);
virtual void set_no_overwrite() {
_no_overwrite = true;
}
protected: protected:
virtual std::vector<ds_bulk_t> vlist_keys(const ds_bulk_t &start, size_t count, const ds_bulk_t &prefix); virtual std::vector<ds_bulk_t> vlist_keys(const ds_bulk_t &start, size_t count, const ds_bulk_t &prefix);
virtual std::vector<std::pair<ds_bulk_t,ds_bulk_t>> vlist_keyvals(const ds_bulk_t &start_key, size_t count, const ds_bulk_t &prefix); virtual std::vector<std::pair<ds_bulk_t,ds_bulk_t>> vlist_keyvals(const ds_bulk_t &start_key, size_t count, const ds_bulk_t &prefix);
BwTree<ds_bulk_t, ds_bulk_t, BwTree<ds_bulk_t, ds_bulk_t,
ds_bulk_less, ds_bulk_equal, ds_bulk_hash, ds_bulk_less, ds_bulk_equal, ds_bulk_hash,
ds_bulk_equal, ds_bulk_hash> *_tree = NULL; ds_bulk_equal, ds_bulk_hash> *_tree = NULL;
bool _no_overwrite = false;
}; };
#endif // bwtree_datastore_h #endif // bwtree_datastore_h
...@@ -18,13 +18,15 @@ public: ...@@ -18,13 +18,15 @@ public:
AbstractDataStore(); AbstractDataStore();
AbstractDataStore(Duplicates duplicates, bool eraseOnGet, bool debug); AbstractDataStore(Duplicates duplicates, bool eraseOnGet, bool debug);
virtual ~AbstractDataStore(); virtual ~AbstractDataStore();
virtual void createDatabase(const std::string& db_name, const std::string& path)=0; virtual bool openDatabase(const std::string& db_name, const std::string& path)=0;
virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data)=0; virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data)=0;
virtual bool get(const ds_bulk_t &key, ds_bulk_t &data)=0; virtual bool get(const ds_bulk_t &key, ds_bulk_t &data)=0;
virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data)=0; virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data)=0;
virtual bool exists(const ds_bulk_t &key) = 0;
virtual bool erase(const ds_bulk_t &key) = 0; virtual bool erase(const ds_bulk_t &key) = 0;
virtual void set_in_memory(bool enable)=0; // enable/disable in-memory mode (where supported) virtual void set_in_memory(bool enable)=0; // enable/disable in-memory mode (where supported)
virtual void set_comparison_function(comparator_fn less)=0; virtual void set_comparison_function(comparator_fn less)=0;
virtual void set_no_overwrite()=0;
std::vector<ds_bulk_t> list_keys( std::vector<ds_bulk_t> list_keys(
const ds_bulk_t &start_key, size_t count, const ds_bulk_t& prefix=ds_bulk_t()) { const ds_bulk_t &start_key, size_t count, const ds_bulk_t& prefix=ds_bulk_t()) {
......
...@@ -25,41 +25,57 @@ ...@@ -25,41 +25,57 @@
class datastore_factory { class datastore_factory {
static AbstractDataStore* create_map_datastore( static AbstractDataStore* open_map_datastore(
const std::string& name, const std::string& path) { const std::string& name, const std::string& path) {
auto db = new MapDataStore(); auto db = new MapDataStore();
db->createDatabase(name, path); if(db->openDatabase(name, path)) {
return db; return db;
} else {
delete db;
return nullptr;
}
} }
static AbstractDataStore* create_bwtree_datastore( static AbstractDataStore* open_bwtree_datastore(
const std::string& name, const std::string& path) { const std::string& name, const std::string& path) {
#ifdef USE_BWTREE #ifdef USE_BWTREE
auto db = new BwTreeDataStore(); auto db = new BwTreeDataStore();
db->createDatabase(name, path); if(db->openDatabase(name, path)) {
return db; return db;
} else {
delete db;
return nullptr;
}
#else #else
return nullptr; return nullptr;
#endif #endif
} }
static AbstractDataStore* create_berkeleydb_datastore( static AbstractDataStore* open_berkeleydb_datastore(
const std::string& name, const std::string& path) { const std::string& name, const std::string& path) {
#ifdef USE_BDB #ifdef USE_BDB
auto db = new BerkeleyDBDataStore(); auto db = new BerkeleyDBDataStore();
db->createDatabase(name, path); if(db->openDatabase(name, path)) {
return db; return db;
} else {
delete db;
return nullptr;
}
#else #else
return nullptr; return nullptr;
#endif #endif
} }
static AbstractDataStore* create_leveldb_datastore( static AbstractDataStore* open_leveldb_datastore(
const std::string& name, const std::string& path) { const std::string& name, const std::string& path) {
#ifdef USE_LEVELDB #ifdef USE_LEVELDB
auto db = new LevelDBDataStore(); auto db = new LevelDBDataStore();
db->createDatabase(name, path); if(db->openDatabase(name, path)) {
return db; return db;
} else {
delete db;
return nullptr;
}
#else #else
return nullptr; return nullptr;
#endif #endif
...@@ -68,12 +84,12 @@ class datastore_factory { ...@@ -68,12 +84,12 @@ class datastore_factory {
public: public:
#ifdef SDSKV #ifdef SDSKV
static AbstractDataStore* create_datastore( static AbstractDataStore* open_datastore(
sdskv_db_type_t type, sdskv_db_type_t type,
const std::string& name, const std::string& name,
const std::string& path) const std::string& path)
#else #else
static AbstractDataStore* create_datastore( static AbstractDataStore* open_datastore(
kv_db_type_t type, kv_db_type_t type,
const std::string& name="db", const std::string& name="db",
const std::string& path="db") const std::string& path="db")
...@@ -81,13 +97,13 @@ class datastore_factory { ...@@ -81,13 +97,13 @@ class datastore_factory {
{ {
switch(type) { switch(type) {
case KVDB_MAP: case KVDB_MAP:
return create_map_datastore(name, path); return open_map_datastore(name, path);
case KVDB_BWTREE: case KVDB_BWTREE:
return create_bwtree_datastore(name, path); return open_bwtree_datastore(name, path);
case KVDB_LEVELDB: case KVDB_LEVELDB:
return create_leveldb_datastore(name, path); return open_leveldb_datastore(name, path);
case KVDB_BERKELEYDB: case KVDB_BERKELEYDB:
return create_berkeleydb_datastore(name, path); return open_berkeleydb_datastore(name, path);
} }
return nullptr; return nullptr;
}; };
......
...@@ -35,7 +35,7 @@ LevelDBDataStore::~LevelDBDataStore() { ...@@ -35,7 +35,7 @@ LevelDBDataStore::~LevelDBDataStore() {
//leveldb::Env::Shutdown(); // Riak version only //leveldb::Env::Shutdown(); // Riak version only
}; };
void LevelDBDataStore::createDatabase(const std::string& db_name, const std::string& db_path) { bool LevelDBDataStore::openDatabase(const std::string& db_name, const std::string& db_path) {
leveldb::Options options; leveldb::Options options;
leveldb::Status status; leveldb::Status status;
...@@ -52,10 +52,9 @@ void LevelDBDataStore::createDatabase(const std::string& db_name, const std::str ...@@ -52,10 +52,9 @@ void LevelDBDataStore::createDatabase(const std::string& db_name, const std::str
if (!status.ok()) { if (!status.ok()) {
// error // error
std::cerr << "LevelDBDataStore::createDatabase: LevelDB error on Open = " << status.ToString() << std::endl; std::cerr << "LevelDBDataStore::createDatabase: LevelDB error on Open = " << status.ToString() << std::endl;
return false;
} }
assert(status.ok()); // fall over return true;
// debugging support?
}; };
void LevelDBDataStore::set_comparison_function(comparator_fn less) { void LevelDBDataStore::set_comparison_function(comparator_fn less) {
...@@ -65,8 +64,12 @@ void LevelDBDataStore::set_comparison_function(comparator_fn less) { ...@@ -65,8 +64,12 @@ void LevelDBDataStore::set_comparison_function(comparator_fn less) {
bool LevelDBDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) { bool LevelDBDataStore::put(const ds_bulk_t &key, const ds_bulk_t &data) {
leveldb::Status status; leveldb::Status status;
bool success = false; bool success = false;
high_resolution_clock::time_point start = high_resolution_clock::now(); if(_no_overwrite) {
if(exists(key)) return false;
}
//high_resolution_clock::time_point start = high_resolution_clock::now();
// IGNORE case deals with redundant puts (where key/value is the same). In LevelDB a // IGNORE case deals with redundant puts (where key/value is the same). In LevelDB a
// redundant put simply overwrites previous value which is fine when key/value is the same. // redundant put simply overwrites previous value which is fine when key/value is the same.
if (_duplicates == Duplicates::IGNORE) { if (_duplicates == Duplicates::IGNORE) {
...@@ -96,11 +99,18 @@ bool LevelDBDataStore::erase(const ds_bulk_t &key) { ...@@ -96,11 +99,18 @@ bool LevelDBDataStore::erase(const ds_bulk_t &key) {
return status.ok(); return status.ok();
} }
bool LevelDBDataStore::exists(const ds_bulk_t &key) {
leveldb::Status status;
std::string value;
status = _dbm->Get(leveldb::ReadOptions(), toString(key), &value);
return status.ok();
}
bool LevelDBDataStore::get(const ds_bulk_t &key, ds_bulk_t &data) { bool LevelDBDataStore::get(const ds_bulk_t &key, ds_bulk_t &data) {
leveldb::Status status; leveldb::Status status;
bool success = false; bool success = false;
high_resolution_clock::time_point start = high_resolution_clock::now(); //high_resolution_clock::time_point start = high_resolution_clock::now();
data.clear(); data.clear();
std::string value; std::string value;
status = _dbm->Get(leveldb::ReadOptions(), toString(key), &value); status = _dbm->Get(leveldb::ReadOptions(), toString(key), &value);
......
...@@ -39,13 +39,17 @@ class LevelDBDataStore : public AbstractDataStore { ...@@ -39,13 +39,17 @@ class LevelDBDataStore : public AbstractDataStore {
LevelDBDataStore(); LevelDBDataStore();
LevelDBDataStore(Duplicates duplicates, bool eraseOnGet, bool debug); LevelDBDataStore(Duplicates duplicates, bool eraseOnGet, bool debug);
virtual ~LevelDBDataStore(); virtual ~LevelDBDataStore();
virtual void createDatabase(const std::string& db_name, const std::string& path); virtual bool openDatabase(const std::string& db_name, const std::string& path);
virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data); virtual bool put(const ds_bulk_t &key, const ds_bulk_t &data);
virtual bool get(const ds_bulk_t &key, ds_bulk_t &data); virtual bool get(const ds_bulk_t &key, ds_bulk_t &data);
virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data); virtual bool get(const ds_bulk_t &key, std::vector<ds_bulk_t> &data);
virtual bool exists(const ds_bulk_t &key);
virtual bool erase(const ds_bulk_t &key); virtual bool erase(const ds_bulk_t &key);
virtual void set_in_memory(bool enable); // not supported, a no-op virtual void set_in_memory(bool enable); // not supported, a no-op
virtual void set_comparison_function(comparator_fn less); virtual void set_comparison_function(comparator_fn less);
virtual void set_no_overwrite() {
_no_overwrite = true;
}
protected: protected:
virtual std::vector<ds_bulk_t> vlist_keys(const ds_bulk_t &start, size_t count, const ds_bulk_t &prefix); virtual std::vector<ds_bulk_t> vlist_keys(const ds_bulk_t &start, size_t count, const ds_bulk_t &prefix);
virtual std::vector<std::pair<ds_bulk_t,ds_bulk_t>> vlist_keyvals(const ds_bulk_t &start_key, size_t count, const ds_bulk_t &prefix); virtual std::vector<std::pair<ds_bulk_t,ds_bulk_t>> vlist_keyvals(const ds_bulk_t &start_key, size_t count, const ds_bulk_t &prefix);
...@@ -55,6 +59,7 @@ class LevelDBDataStore : public AbstractDataStore { ...@@ -55,6 +59,7 @@ class LevelDBDataStore : public AbstractDataStore {
ds_bulk_t fromString(const std::string &keystr); ds_bulk_t fromString(const std::string &keystr);
AbstractDataStore::comparator_fn _less; AbstractDataStore::comparator_fn _less;
LevelDBDataStoreComparator _keycmp; LevelDBDataStoreComparator _keycmp;
bool _no_overwrite = false;
};