# HG changeset patch # User Kim Alvefur # Date 1688155309 -7200 # Node ID 8ec7b7d6556f72adca1427557190b6feb4605766 # Parent 4906d4990ffec6c9a494e769a34b08ec53547e97 util.cache: Keep eviction candidate if callback resized to make room Previously either the old or the new values would be rejected, even if the cache was resized to allow more items. diff -r 4906d4990ffe -r 8ec7b7d6556f spec/util_cache_spec.lua --- a/spec/util_cache_spec.lua Fri Jun 30 18:51:03 2023 +0200 +++ b/spec/util_cache_spec.lua Fri Jun 30 22:01:49 2023 +0200 @@ -388,5 +388,26 @@ c:resize(3); assert.same({"v5", "v4", "v3"}, vs(c)); end); + + it("eviction stuff", function () + local c; + c = cache.new(4, function(_k,_v) + if c.size < 10 then + c:resize(c.size*2); + end + end) + for i = 1,20 do + c:set(i,i) + end + assert.equal(16, c.size); + assert.is_nil(c:get(1)) + assert.is_nil(c:get(4)) + assert.equal(5, c:get(5)) + assert.equal(20, c:get(20)) + c:resize(4) + assert.equal(20, c:get(20)) + assert.equal(17, c:get(17)) + assert.is_nil(c:get(10)) + end) end); end); diff -r 4906d4990ffe -r 8ec7b7d6556f util/cache.lua --- a/util/cache.lua Fri Jun 30 18:51:03 2023 +0200 +++ b/util/cache.lua Fri Jun 30 22:01:49 2023 +0200 @@ -54,12 +54,17 @@ if self._count == self.size then local tail = self._tail; local on_evict, evicted_key, evicted_value = self._on_evict, tail.key, tail.value; - if on_evict ~= nil and (on_evict == false or on_evict(evicted_key, evicted_value) == false) then + + local do_evict = on_evict and on_evict(evicted_key, evicted_value); + + if do_evict == false then -- Cache is full, and we're not allowed to evict return false; + elseif self._count == self.size then + -- Cache wasn't grown + _remove(self, tail); + self._data[evicted_key] = nil; end - _remove(self, tail); - self._data[evicted_key] = nil; end m = { key = k, value = v, prev = nil, next = nil };