fix cache implementation

the cache would behave badly when the same item was insert()ed twice:
it would add the size twice to memory consumption, but would never substract
it twice when purging the (actually single) object from cache. So the cache
would seem to fill up while in fact it wasn't.
pull/1143/head
Hans-Werner Hilse 10 years ago
parent 4fc1ff4491
commit 6b45a4ea06

@ -66,7 +66,32 @@ function Cache:new(o)
return o return o
end end
-- internal: remove reference in cache_order list
function Cache:_unref(key)
for i = #self.cache_order, 1, -1 do
if self.cache_order[i] == key then
table.remove(self.cache_order, i)
end
end
end
-- internal: free cache item
function Cache:_free(key)
if not self.cache[key] then return end
self.current_memsize = self.current_memsize - self.cache[key].size
self.cache[key]:onFree()
self.cache[key] = nil
end
-- drop an item named via key from the cache
function Cache:drop(key)
self:_unref(key)
self:_free(key)
end
function Cache:insert(key, object) function Cache:insert(key, object)
-- make sure that one key only exists once: delete existing
self:drop(key)
-- guarantee that we have enough memory in cache -- guarantee that we have enough memory in cache
if(object.size > self.max_memsize) then if(object.size > self.max_memsize) then
DEBUG("too much memory claimed for", key) DEBUG("too much memory claimed for", key)
@ -76,9 +101,7 @@ function Cache:insert(key, object)
-- (they are at the end of the cache_order array) -- (they are at the end of the cache_order array)
while self.current_memsize + object.size > self.max_memsize do while self.current_memsize + object.size > self.max_memsize do
local removed_key = table.remove(self.cache_order) local removed_key = table.remove(self.cache_order)
self.current_memsize = self.current_memsize - self.cache[removed_key].size self:_free(removed_key)
self.cache[removed_key]:onFree()
self.cache[removed_key] = nil
end end
-- insert new object in front of the LRU order -- insert new object in front of the LRU order
table.insert(self.cache_order, 1, key) table.insert(self.cache_order, 1, key)
@ -94,11 +117,7 @@ function Cache:check(key, ItemClass)
if self.cache[key] then if self.cache[key] then
if self.cache_order[1] ~= key then if self.cache_order[1] ~= key then
-- put key in front of the LRU list -- put key in front of the LRU list
for k, v in ipairs(self.cache_order) do self:_unref(key)
if v == key then
table.remove(self.cache_order, k)
end
end
table.insert(self.cache_order, 1, key) table.insert(self.cache_order, 1, key)
end end
return self.cache[key] return self.cache[key]

Loading…
Cancel
Save