diff --git a/memdb/include/memdb.hpp b/memdb/include/memdb.hpp index 6fc4964..26c6ed0 100644 --- a/memdb/include/memdb.hpp +++ b/memdb/include/memdb.hpp @@ -1,14 +1,15 @@ #pragma once -#include #include #include #include -#include #include #include +#include +namespace shufeng2012 { + template class Memdb { @@ -18,7 +19,6 @@ struct memdb_column { T key; U value; std::chrono::system_clock::time_point timestamp; - bool be_del = false; }; struct index_keys { @@ -36,15 +36,10 @@ struct index_timestamp { private: std::list db; std::unordered_map keys; - std::priority_queue time_touch; - std::multiset time_touch_; + std::multiset time_touch; size_t __size = 0; int MAX_TIME = 60 * 10; // 10分钟 void flush(); - void update_queue(); - - // 内测版 - void flush_(); public: @@ -61,17 +56,11 @@ public: size_t size() const; const std::unordered_map & get_keys() const; const std::list & get_db() const; - const std::priority_queue & get_time_touch() const; + const std::multiset ::index_timestamp>& get_time_touch() const; bool insert(key_t to_be_ins_k, value_t ins_v); bool remove(key_t to_be_del_k); bool update(key_t to_be_udt_k, value_t udt_v, bool need_to_udt_timetouch=false); std::optional search(key_t to_be_sch_k); - - // 内测版 - const std::multiset & get_time_touch_() const; - bool insert_(key_t to_be_ins_k, value_t ins_v); - bool remove_(key_t to_be_del_k); - bool update_(key_t to_be_udt_k, value_t udt_v, bool need_to_udt_timetouch=false); - std::optional search_(key_t to_be_sch_k); -}; \ No newline at end of file +}; +} \ No newline at end of file diff --git a/memdb/src/main/memdb.cpp b/memdb/src/main/memdb.cpp index bdc7490..3ba1e09 100644 --- a/memdb/src/main/memdb.cpp +++ b/memdb/src/main/memdb.cpp @@ -2,46 +2,11 @@ +namespace shufeng2012 { template bool Memdb ::index_timestamp::operator<(const index_timestamp& a) const { - return this -> item -> timestamp > a.item -> timestamp; -} - - -template - -void Memdb ::flush() { - if (this -> time_touch.empty() == true) { - return; - } - std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); - typename std::list ::iterator it = this -> time_touch.top().item; - - while (now_time > it -> timestamp || it -> be_del == true) { - if (it -> be_del != true) this -> __size--; - this -> keys.erase(it -> key); - this -> time_touch.pop(); - this -> db.erase(it); - - if (this -> time_touch.empty() == true) { - return; - } - it = this -> time_touch.top().item; - now_time = std::chrono::system_clock::now(); - } -} - - -template - -void Memdb ::update_queue() { - std::priority_queue new_time_touch; - while (this -> time_touch.empty() == false) { - new_time_touch.push(this -> time_touch.top()); - this -> time_touch.pop(); - } - this -> time_touch = new_time_touch; + return this -> item -> timestamp < a.item -> timestamp; } @@ -52,7 +17,7 @@ Memdb ::Memdb() = default; template -Memdb ::Memdb(int max_time) : MAX_TIME(max_time) {} +Memdb ::Memdb(int max_time) : MAX_TIME(std::max(0, max_time)) {} template @@ -86,13 +51,42 @@ const std::list ::memdb_column>& Memdb ::get_db() co } +/* +内测版 +*/ + + template -const std::priority_queue ::index_timestamp>& Memdb ::get_time_touch() const { - return this -> time_touch; +void Memdb ::flush() { + if (this -> time_touch.empty() == true) { + return; + } + std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); + typename std::list ::iterator it = this -> time_touch.begin() -> item; + + while (now_time >= it -> timestamp) { + this -> __size--; + key_t to_be_del_k = it -> key; + this -> db.erase(it); + this -> keys.erase(to_be_del_k); + this -> time_touch.erase(this -> time_touch.begin()); + + if (this -> time_touch.empty() == true) { + return; + } + it = this -> time_touch.begin() -> item; + now_time = std::chrono::system_clock::now(); + } } +template + +const std::multiset ::index_timestamp>& Memdb ::get_time_touch() const { + return this -> time_touch; +} + template @@ -117,7 +111,7 @@ bool Memdb ::insert(key_t to_be_ins_k, value_t ins_v) { Memdb::index_timestamp new_time_touch; new_time_touch.item = std::prev(this -> db.end()); - this -> time_touch.push(new_time_touch); + this -> time_touch.insert(new_time_touch); this -> __size++; @@ -128,14 +122,17 @@ bool Memdb ::insert(key_t to_be_ins_k, value_t ins_v) { template bool Memdb ::remove(key_t to_be_del_k) { + //! 直接删除,不要lazy this -> flush(); if (this -> keys.find(to_be_del_k) == this -> keys.end()) { return this -> fail; } typename std::list ::iterator it = this -> keys[to_be_del_k].item; - it -> be_del = true; + // it -> be_del = true; this -> keys.erase(it -> key); + this -> time_touch.erase({it}); + this -> db.erase(it); this -> __size--; return this -> succ; @@ -145,6 +142,7 @@ bool Memdb ::remove(key_t to_be_del_k) { template bool Memdb ::update(key_t to_be_udt_k, value_t udt_v, bool need_to_udt_timetouch) { + //! 先删再加 this -> flush(); if (this -> keys.find(to_be_udt_k) == this -> keys.end()) { return this -> fail; @@ -154,8 +152,10 @@ bool Memdb ::update(key_t to_be_udt_k, value_t udt_v, bool need_to_udt_tim it -> value = udt_v; if (need_to_udt_timetouch == true) { std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); - it -> timestamp = now_time + std::chrono::seconds(MAX_TIME); - this -> update_queue(); + T copy_k = it -> key; + U copy_v = it -> value; + this -> remove(copy_k); + this -> insert(copy_k, copy_v); } return this -> succ; @@ -174,119 +174,4 @@ std::optional Memdb ::search(key_t to_be_sch_k){ return it -> value; } - -/* -内测版 -*/ - - -template - -void Memdb ::flush_() { - if (this -> time_touch_.empty() == true) { - return; - } - std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); - typename std::list ::iterator it = this -> time_touch_.begin() -> item; - - while (now_time > it -> timestamp || it -> be_del == true) { - if (it -> be_del != true) this -> __size--; - key_t to_be_del_k = it -> key; - this -> db.erase(it); - this -> keys.erase(to_be_del_k); - this -> time_touch_.erase(this -> time_touch_.begin()); - - if (this -> time_touch_.empty() == true) { - return; - } - it = this -> time_touch_.begin() -> item; - now_time = std::chrono::system_clock::now(); - } -} - - -template - -const std::multiset ::index_timestamp>& Memdb ::get_time_touch_() const { - return this -> time_touch_; -} - - -template - -bool Memdb ::insert_(key_t to_be_ins_k, value_t ins_v) { - this -> flush_(); - if (this -> keys.find(to_be_ins_k) != this -> keys.end()) { - return this -> fail; - } - - std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); - - Memdb::memdb_column new_column; - new_column.key = to_be_ins_k; - new_column.value = ins_v; - new_column.timestamp = now_time + std::chrono::seconds(MAX_TIME); - this -> db.push_back(new_column); - - Memdb::index_keys new_key; - new_key.key = to_be_ins_k; - new_key.item = std::prev(this -> db.end()); - this -> keys[to_be_ins_k] = new_key; - - Memdb::index_timestamp new_time_touch; - new_time_touch.item = std::prev(this -> db.end()); - this -> time_touch_.insert(new_time_touch); - - this -> __size++; - - return this -> succ; -} - - -template - -bool Memdb ::remove_(key_t to_be_del_k) { - this -> flush_(); - if (this -> keys.find(to_be_del_k) == this -> keys.end()) { - return this -> fail; - } - - typename std::list ::iterator it = this -> keys[to_be_del_k].item; - it -> be_del = true; - this -> keys.erase(it -> key); - this -> __size--; - - return this -> succ; -} - - -template - -bool Memdb ::update_(key_t to_be_udt_k, value_t udt_v, bool need_to_udt_timetouch) { - this -> flush_(); - if (this -> keys.find(to_be_udt_k) == this -> keys.end()) { - return this -> fail; - } - - typename std::list ::iterator it = this -> keys[to_be_udt_k].item; - it -> value = udt_v; - if (need_to_udt_timetouch == true) { - std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now(); - it -> timestamp = now_time + std::chrono::seconds(MAX_TIME); - } - - return this -> succ; -} - - -template - -std::optional Memdb ::search_(key_t to_be_sch_k){ - this -> flush_(); - if (this -> keys.find(to_be_sch_k) == this -> keys.end()) { - return std::nullopt; - } - - typename std::list ::iterator it = this -> keys[to_be_sch_k].item; - return it -> value; } \ No newline at end of file