From d93e74e7e7bd08d9f09d06bd19a2a8b77d1da5b4 Mon Sep 17 00:00:00 2001 From: Sahid Orentino Ferdjaoui Date: Wed, 11 Jun 2014 15:40:38 +0200 Subject: [PATCH] common: Enforces the methods lru_pin() and lru_unpin() If lru_*pin() is called twice, the counter will be incr/decr incorrectly since it will count more/less pinned objects than there is and so corrupts the balancing (lru_adjust()). Signed-off-by: Sahid Orentino Ferdjaoui --- src/include/lru.h | 14 +++++++++----- src/test/common/test_lru.cc | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/include/lru.h b/src/include/lru.h index 7024042e16027..6a9427420e736 100644 --- a/src/include/lru.h +++ b/src/include/lru.h @@ -315,14 +315,16 @@ class LRU { }; -inline void LRUObject::lru_pin() -{ +inline void LRUObject::lru_pin() { + if (lru && !lru_pinned) { + lru->lru_num_pinned++; + lru->lru_adjust(); + } lru_pinned = true; - if (lru) lru->lru_num_pinned++; } + inline void LRUObject::lru_unpin() { - lru_pinned = false; - if (lru) { + if (lru && lru_pinned) { lru->lru_num_pinned--; // move from pintail -> bot @@ -330,7 +332,9 @@ inline void LRUObject::lru_unpin() { lru->lru_pintail.remove(this); lru->lru_bot.insert_tail(this); } + lru->lru_adjust(); } + lru_pinned = false; } #endif diff --git a/src/test/common/test_lru.cc b/src/test/common/test_lru.cc index 7a0a1413cf1a3..fb6f6529949f0 100644 --- a/src/test/common/test_lru.cc +++ b/src/test/common/test_lru.cc @@ -89,6 +89,38 @@ TEST(lru, Adjust) { ASSERT_EQ(100, lru.lru_get_size()); } +TEST(lru, Pinning) { + LRU lru = LRU(); + + Item *ob0 = new Item(0); + Item *ob1 = new Item(1); + + // test before ob1 are in a LRU + ob1->lru_pin(); + ASSERT_FALSE(ob1->lru_is_expireable()); + + ob1->lru_unpin(); + ASSERT_TRUE(ob1->lru_is_expireable()); + + // test when ob1 are in a LRU + lru.lru_touch(ob0); + lru.lru_touch(ob1); + + ob1->lru_pin(); + ob1->lru_pin(); // Verify that, one incr. + ASSERT_EQ(1, lru.lru_get_num_pinned()); + ASSERT_FALSE(ob1->lru_is_expireable()); + + ob1->lru_unpin(); + ob1->lru_unpin(); // Verify that, one decr. + ASSERT_EQ(0, lru.lru_get_num_pinned()); + ASSERT_TRUE(ob1->lru_is_expireable()); + + ASSERT_EQ(0, (static_cast(lru.lru_expire()))->id); + ob0->lru_pin(); + ASSERT_EQ(1, (static_cast(lru.lru_expire()))->id); +} + /* * Local Variables: -- 2.47.3