methods for addition with overwrite

This commit is contained in:
Blue 2022-12-14 01:57:49 +03:00
parent 928558539c
commit 08daad48ad
Signed by: blue
GPG Key ID: 9B203B252A63EE38
4 changed files with 60 additions and 0 deletions

View File

@ -39,6 +39,7 @@ private:
public:
virtual void addRecord(const K& key, const V& value) override;
virtual bool forceRecord(const K& key, const V& value) override;
virtual void changeRecord(const K& key, const V& value) override;
virtual void removeRecord(const K& key) override;
virtual V getRecord(const K& key) const override;

View File

@ -52,8 +52,35 @@ void DataBase::Cache<K, V>::addRecord(const K& key, const V& value) {
Table<K, V>::addRecord(key, value);
cache->insert(std::make_pair(key, value));
if (*mode != Mode::full) {
abscent->erase(key);
}
}
template<class K, class V>
bool DataBase::Cache<K, V>::forceRecord(const K& key, const V& value) {
if (!DataBase::Table<K, V>::db->opened) {
throw Closed("forceRecord", DataBase::Table<K, V>::db->name, DataBase::Table<K, V>::name);
}
bool added = Table<K, V>::forceRecord(key, value);
if (*mode == Mode::full) {
(*cache)[key] = value;
} else {
if (added) {
abscent->erase(key);
}
std::pair<typename std::map<K, V>::iterator, bool> result = cache->insert(std::make_pair(key, value));
if (!result.second) {
result.first->second = value;
} else if (!added) { //this way database had value but cache didn't, so, need to decrease sizeDifference
handleMode();
}
}
return added;
}
template<class K, class V>
void DataBase::Cache<K, V>::changeRecord(const K& key, const V& value) {

View File

@ -55,6 +55,7 @@ protected:
public:
virtual void addRecord(const K& key, const V& value);
virtual bool forceRecord(const K& key, const V& value); //returns true if there was addition, false if change
virtual void changeRecord(const K& key, const V& value);
virtual void removeRecord(const K& key);
virtual V getRecord(const K& key) const;

View File

@ -58,7 +58,38 @@ void DataBase::Table<K, V>::addRecord(const K& key, const V& value) {
}
}
template<class K, class V>
bool DataBase::Table<K, V>::forceRecord(const K& key, const V& value) {
if (!db->opened) {
throw Closed("forceRecord", db->name, name);
}
bool added;
MDB_val lmdbKey = keySerializer->setData(key);
MDB_val lmdbData;
MDB_txn *txn;
mdb_txn_begin(db->environment, NULL, 0, &txn);
int rc;
rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData);
if (rc == 0) {
added = false;
} else if (rc == MDB_NOTFOUND) {
added = true;
} else {
mdb_txn_abort(txn);
throw Unknown(db->name, mdb_strerror(rc), name);
}
lmdbData = valueSerializer->setData(value);
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, 0);
if (rc != 0) {
mdb_txn_abort(txn);
throw Unknown(db->name, mdb_strerror(rc), name);
} else {
mdb_txn_commit(txn);
}
return added;
}
template<class K, class V>
void DataBase::Table<K, V>::changeRecord(const K& key, const V& value) {