@@ -8,13 +8,16 @@ static constexpr uint32_t sizeofChar = sizeof(char);
88
99MiniKVDB::MiniKVDB () {
1010 hashSize_ = HASH_SIZE_INIT;
11- hash1_ = std::unique_ptr<HashTable>(new HashTable (hashSize_));
11+ hash1_ = std::shared_ptr<HashTable>(new HashTable (hashSize_));
12+ hash2_ = std::shared_ptr<HashTable>(new HashTable (hashSize_));
1213 expires_ = std::unique_ptr<HashTable>(new HashTable (hashSize_));
1314 io_ = std::unique_ptr<KVio>(new KVio (RDB_FILE_NAME));
1415 rdbFileReadInitDB ();
1516 rdbe_ = new rdbEntry ();
1617 timer_ = std::shared_ptr<KVTimer>(new KVTimer ());
1718 timer_->start (RDB_INTERVAL, std::bind (&MiniKVDB::rdbSave, this ));
19+ timer_->start (REHASH_DETECT_INTERVAL, std::bind (&MiniKVDB::rehash, this ));
20+ rehashFlag_ = false ;
1821}
1922
2023MiniKVDB::~MiniKVDB () {
@@ -24,7 +27,16 @@ MiniKVDB::~MiniKVDB() {
2427}
2528
2629void MiniKVDB::insert (std::string key, std::string val, uint32_t encoding) {
27- hash1_->insert (key, val, encoding);
30+ if (!rehashFlag_) {
31+ hash1_->insert (key, val, encoding);
32+ return ;
33+ }
34+ if (hash1_->exist (key)) {
35+ hash1_->insert (key, val, encoding);
36+ return ;
37+ }
38+ hash2_->insert (key, val, encoding);
39+ progressiveRehash (hash2_);
2840}
2941
3042void MiniKVDB::get (std::string key, std::vector<std::string>& res) {
@@ -44,7 +56,16 @@ void MiniKVDB::get(std::string key, std::vector<std::string>& res) {
4456 return ;
4557 }
4658 }
47- hash1_->get (key, res);
59+ if (!rehashFlag_) {
60+ hash1_->get (key, res);
61+ return ;
62+ }
63+ if (hash1_->exist (key)) {
64+ hash1_->get (key, res);
65+ return ;
66+ }
67+ hash2_->get (key, res);
68+ progressiveRehash (hash2_);
4869}
4970
5071int MiniKVDB::del (std::string key) {
@@ -196,4 +217,23 @@ void MiniKVDB::rdbFileReadInitDB() {
196217 rdbLoadEntry ();
197218 }
198219 kvlogi (" Rdb file loaded." );
220+ }
221+
222+ void MiniKVDB::rehash () {
223+ if (rehashFlag_) return ;
224+ std::shared_lock<std::shared_mutex> lk (smutex_);
225+ if (!hash1_->needRehash ()) return ;
226+ lk.unlock ();
227+ rehashFlag_ = true ;
228+ hash2_->resize (hash1_->size () * 2 );
229+ }
230+
231+ void MiniKVDB::progressiveRehash (std::shared_ptr<HashTable> h2) {
232+ if (!rehashFlag_) return ;
233+ bool completed = hash1_->progressiveRehash (h2, REHASH_MAX_EMPTY_VISITS);
234+ if (completed) {
235+ rehashFlag_ = false ;
236+ std::swap (hash1_, hash2_);
237+ hash2_->clear ();
238+ }
199239}
0 commit comments