Software /
code /
prosody
Diff
util/cache.lua @ 6933:d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Tue, 24 Nov 2015 10:44:41 +0000 |
child | 6943:0a31ec3193f0 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/cache.lua Tue Nov 24 10:44:41 2015 +0000 @@ -0,0 +1,91 @@ +local cache_methods = {}; +local cache_mt = { __index = cache_methods }; + +local function new(size) + assert(size > 0, "cache size must be greater than zero"); + local data = {}; + return setmetatable({ data = data, count = 0, size = size, head = nil, tail = nil }, cache_mt); +end + +local function _remove(list, m) + if m.prev then + m.prev.next = m.next; + end + if m.next then + m.next.prev = m.prev; + end + if list.tail == m then + list.tail = m.prev; + end + if list.head == m then + list.head = m.next; + end + list.count = list.count - 1; +end + +local function _insert(list, m) + if list.head then + list.head.prev = m; + end + m.prev, m.next = nil, list.head; + list.head = m; + if not list.tail then + list.tail = m; + end + list.count = list.count + 1; +end + +function cache_methods:set(k, v) + local m = self.data[k]; + if m then + -- Key already exists + if v ~= nil then + -- Bump to head of list + _remove(self, m); + _insert(self, m); + m.value = v; + else + -- Remove from list + _remove(self, m); + self.data[k] = nil; + end + return; + end + -- New key + if v == nil then + return; + end + -- Check whether we need to remove oldest k/v + if self.count == self.size then + self.data[self.tail.key] = nil; + _remove(self, self.tail); + end + + m = { key = k, value = v, prev = nil, next = nil }; + self.data[k] = m; + _insert(self, m); +end + +function cache_methods:get(k) + local m = self.data[k]; + if m then + return m.value; + end + return nil; +end + +function cache_methods:items() + local m = self.head; + return function () + if not m then + return; + end + local k, v = m.key, m.value; + m = m.next; + return k, v; + end +end + +return { + new = new; +}