Add leveldb::Cache::Prune

Prune() drops on-memory read cache of the database, so that the client can
relief its memory shortage.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=101335710
This commit is contained in:
tzik 2015-08-23 20:35:01 -07:00 committed by Chris Mumford
parent 40c17c0b84
commit bb61e00815
3 changed files with 39 additions and 0 deletions

View File

@ -81,6 +81,13 @@ class Cache {
// its cache keys. // its cache keys.
virtual uint64_t NewId() = 0; virtual uint64_t NewId() = 0;
// Remove all cache entries that are not actively in use. Memory-constrained
// applications may wish to call this method to reduce memory usage.
// Default implementation of Prune() does nothing. Subclasses are strongly
// encouraged to override the default implementation. A future release of
// leveldb may change Prune() to a pure abstract method.
virtual void Prune() {}
private: private:
void LRU_Remove(Handle* e); void LRU_Remove(Handle* e);
void LRU_Append(Handle* e); void LRU_Append(Handle* e);

View File

@ -147,6 +147,7 @@ class LRUCache {
Cache::Handle* Lookup(const Slice& key, uint32_t hash); Cache::Handle* Lookup(const Slice& key, uint32_t hash);
void Release(Cache::Handle* handle); void Release(Cache::Handle* handle);
void Erase(const Slice& key, uint32_t hash); void Erase(const Slice& key, uint32_t hash);
void Prune();
private: private:
void LRU_Remove(LRUHandle* e); void LRU_Remove(LRUHandle* e);
@ -264,6 +265,19 @@ void LRUCache::Erase(const Slice& key, uint32_t hash) {
} }
} }
void LRUCache::Prune() {
MutexLock l(&mutex_);
for (LRUHandle* e = lru_.next; e != &lru_; ) {
LRUHandle* next = e->next;
if (e->refs == 1) {
table_.Remove(e->key(), e->hash);
LRU_Remove(e);
Unref(e);
}
e = next;
}
}
static const int kNumShardBits = 4; static const int kNumShardBits = 4;
static const int kNumShards = 1 << kNumShardBits; static const int kNumShards = 1 << kNumShardBits;
@ -314,6 +328,11 @@ class ShardedLRUCache : public Cache {
MutexLock l(&id_mutex_); MutexLock l(&id_mutex_);
return ++(last_id_); return ++(last_id_);
} }
virtual void Prune() {
for (int s = 0; s < kNumShards; s++) {
shard_[s].Prune();
}
}
}; };
} // end anonymous namespace } // end anonymous namespace

View File

@ -179,6 +179,19 @@ TEST(CacheTest, NewId) {
ASSERT_NE(a, b); ASSERT_NE(a, b);
} }
TEST(CacheTest, Prune) {
Insert(1, 100);
Insert(2, 200);
Cache::Handle* handle = cache_->Lookup(EncodeKey(1));
ASSERT_TRUE(handle);
cache_->Prune();
cache_->Release(handle);
ASSERT_EQ(100, Lookup(1));
ASSERT_EQ(-1, Lookup(2));
}
} // namespace leveldb } // namespace leveldb
int main(int argc, char** argv) { int main(int argc, char** argv) {