diff options
author | dormando <dormando@rydia.net> | 2017-01-22 21:06:05 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2017-01-22 21:06:05 -0800 |
commit | 4c80e2fd4cbf1d899ddc6dbb7978aafd40416aae (patch) | |
tree | bbff53b517afb0f6e947ea94f1783253ecc3ac32 /items.c | |
parent | 75a152390b54ae1516196eaa9859085fbb70474f (diff) | |
download | memcached-4c80e2fd4cbf1d899ddc6dbb7978aafd40416aae.tar.gz |
move WARM_LRU requires two hits overall
ITEM_FETCHED and ITEM_ACTIVE are now tracked separately. This also ensures
these flags are added only when an item would normally be bumped (previously
and INCR/DECR, failed store, etc could do it.
The original segmented LRU papers require two hits to be considered frequently
accessed. It's not completely clear if the initial cache miss counts as a hit
in the papers but increasing the frequency required to reach WARM still helps.
Diffstat (limited to 'items.c')
-rw-r--r-- | items.c | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -447,7 +447,7 @@ void do_item_update(item *it) { if (settings.lru_maintainer_thread) { assert((it->it_flags & ITEM_SLABBED) == 0); if ((it->it_flags & ITEM_LINKED) != 0) { - if (ITEM_lruid(it) == COLD_LRU) { + if (ITEM_lruid(it) == COLD_LRU && (it->it_flags & ITEM_ACTIVE)) { it->time = current_time; item_unlink_q(it); it->slabs_clsid = ITEM_clsid(it); @@ -844,8 +844,20 @@ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv, conn *c } was_found = 3; } else { - it->it_flags |= ITEM_FETCHED|ITEM_ACTIVE; if (do_update) { + /* We update the hit markers only during fetches. + * An item needs to be hit twice overall to be considered + * ACTIVE, but only needs a single hit to maintain activity + * afterward. + * FETCHED tells if an item has ever been active. + */ + if ((it->it_flags & ITEM_ACTIVE) == 0) { + if ((it->it_flags & ITEM_FETCHED) == 0) { + it->it_flags |= ITEM_FETCHED; + } else { + it->it_flags |= ITEM_ACTIVE; + } + } do_item_update(it); } DEBUG_REFCNT(it, '+'); |