some debug, some idea how to utilize home hints of data by cache

This commit is contained in:
Blue 2022-10-08 19:45:07 +03:00
parent a613eaed27
commit c23dae2a25
Signed by: blue
GPG Key ID: 9B203B252A63EE38
2 changed files with 91 additions and 21 deletions

18
cache.h
View File

@ -25,27 +25,31 @@
template <class K, class V>
class DataBase::Cache : public DataBase::Table<K, V> {
friend class DataBase;
enum class Mode {
nothing,
size,
full
enum class Mode { //it's a cache state when we:
nothing, // - know nothing about records in database on disk
size, // - know just an amount of records
full // - shure that our cache is equal to the database on disk
};
protected:
Cache(const std::string& name, DataBase* parent);
~Cache() override;
private:
void handleMode() const;
public:
virtual void addRecord(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;
//virtual uint32_t count() const;
//virtual void drop();
virtual uint32_t count() const override;
virtual void drop() override;
protected:
Mode mode;
Mode* mode;
std::map<K, V>* cache;
std::set<K>* abscent;
uint32_t* sizeDifference;
};
#include "cache.hpp"

View File

@ -23,14 +23,19 @@
template<class K, class V>
DataBase::Cache<K, V>::Cache(const std::string& p_name, DataBase* parent):
DataBase::Table<K, V>(p_name, parent),
mode(Mode::nothing),
mode(new Mode),
cache(new std::map<K, V>()),
abscent(new std::set<K>())
abscent(new std::set<K>()),
sizeDifference(new uint32_t)
{
*mode = Mode::nothing;
*sizeDifference = 0;
}
template<class K, class V>
DataBase::Cache<K, V>::~Cache() {
delete sizeDifference;
delete mode;
delete cache;
delete abscent;
}
@ -50,26 +55,39 @@ void DataBase::Cache<K, V>::addRecord(const K& key, const V& value) {
}
template<class K, class V>
void DataBase::Cache<K, V>::changeRecord(const K& key, const V& value) {
if (!DataBase::Table<K, V>::db->opened) {
throw Closed("changeRecord", DataBase::Table<K, V>::db->name, DataBase::Table<K, V>::name);
}
if (*mode == Mode::full) {
typename std::map<K, V>::iterator itr = cache->find(key);
if (itr == cache->end() || abscent->count(key) > 0) {
if (itr != cache->end()) {
throw NotFound(DataBase::_Table::toString(key), DataBase::Table<K, V>::db->name, DataBase::Table<K, V>::name);
}
Table<K, V>::changeRecord(key, value);
itr->second = value;
} else {
if (abscent->count(key) > 0) {
throw NotFound(DataBase::_Table::toString(key), DataBase::Table<K, V>::db->name, DataBase::Table<K, V>::name);
}
try {
Table<K, V>::changeRecord(key, value);
typename std::map<K, V>::iterator itr = cache->find(key);
if (itr != cache->end()) {
itr->second = value;
} else {
cache->insert(std::make_pair(key, value));
handleMode();
}
} catch (const NotFound& error) {
abscent->insert(key);
throw error;
}
}
}
template<class K, class V>
V DataBase::Cache<K, V>::getRecord(const K& key) const {
@ -82,13 +100,14 @@ V DataBase::Cache<K, V>::getRecord(const K& key) const {
return itr->second;
}
if (abscent->count(key) == 0) {
if (*mode == Mode::full || abscent->count(key) == 0) {
throw NotFound(DataBase::_Table::toString(key), DataBase::Table<K, V>::db->name, DataBase::Table<K, V>::name);
}
try {
V value = Table<K, V>::getRecord(key);
cache->insert(std::make_pair(key, value));
handleMode();
return value;
} catch (const NotFound& error) {
abscent->insert(key);
@ -107,8 +126,55 @@ void DataBase::Cache<K, V>::removeRecord(const K& key) {
throw NotFound(DataBase::_Table::toString(key), DataBase::Table<K, V>::db->name, DataBase::Table<K, V>::name);
}
cache->erase(key);
Table<K, V>::removeRecord(key);
if (cache->erase(key) == 0) { //if it was not cached and we are now in size mode then the sizeDifference would decrease
handleMode();
}
if (*mode != Mode::full) {
abscent->insert(key);
}
}
template<class K, class V>
uint32_t DataBase::Cache<K, V>::count() const {
switch (*mode) {
case Mode::nothing:
{
uint32_t sz = DataBase::Table<K, V>::count();
*sizeDifference = sz - cache->size();
if (sz == 0) {
*mode = Mode::full;
abscent->clear();
} else {
*mode = Mode::size;
}
return sz;
}
case Mode::size:
return cache->size() + *sizeDifference;
case Mode::full:
return cache->size();
}
}
template<class K, class V>
void DataBase::Cache<K, V>::handleMode() const {
if (*mode == Mode::size) {
--(*sizeDifference);
if (*sizeDifference == 0) {
*mode = Mode::full;
abscent->clear();
}
}
}
template<class K, class V>
void DataBase::Cache<K, V>::drop() {
DataBase::Table<K, V>::drop();
cache->clear();
abscent->clear();
*mode = Mode::full;
*sizeDifference = 0;
}
#endif //DATABASE_CACHE_HPP