summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortzik <tzik@google.com>2015-08-23 20:35:01 -0700
committerChris Mumford <cmumford@chromium.org>2015-10-13 14:05:21 -0700
commitbb61e008158efd868793307794447a406a084a86 (patch)
tree392b42fb3cf8d517165a33de52f2fb811c16de95
parent40c17c0b84ac0b791fb434096fd5c05f3819ad55 (diff)
downloadleveldb-bb61e008158efd868793307794447a406a084a86.tar.gz
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
-rw-r--r--include/leveldb/cache.h7
-rw-r--r--util/cache.cc19
-rw-r--r--util/cache_test.cc13
3 files changed, 39 insertions, 0 deletions
diff --git a/include/leveldb/cache.h b/include/leveldb/cache.h
index 1a201e5..5f86cd0 100644
--- a/include/leveldb/cache.h
+++ b/include/leveldb/cache.h
@@ -81,6 +81,13 @@ class Cache {
// its cache keys.
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:
void LRU_Remove(Handle* e);
void LRU_Append(Handle* e);
diff --git a/util/cache.cc b/util/cache.cc
index 8b197bc..7f5fc07 100644
--- a/util/cache.cc
+++ b/util/cache.cc
@@ -147,6 +147,7 @@ class LRUCache {
Cache::Handle* Lookup(const Slice& key, uint32_t hash);
void Release(Cache::Handle* handle);
void Erase(const Slice& key, uint32_t hash);
+ void Prune();
private:
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 kNumShards = 1 << kNumShardBits;
@@ -314,6 +328,11 @@ class ShardedLRUCache : public Cache {
MutexLock l(&id_mutex_);
return ++(last_id_);
}
+ virtual void Prune() {
+ for (int s = 0; s < kNumShards; s++) {
+ shard_[s].Prune();
+ }
+ }
};
} // end anonymous namespace
diff --git a/util/cache_test.cc b/util/cache_test.cc
index 4371671..90af5fe 100644
--- a/util/cache_test.cc
+++ b/util/cache_test.cc
@@ -179,6 +179,19 @@ TEST(CacheTest, NewId) {
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
int main(int argc, char** argv) {