Advertisement
Xetrill

xs_cache.script

Oct 18th, 2013
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.69 KB | None | 0 0
  1. ---[ PRIVATE ]-----------------------------------------------------------------
  2.  
  3. local tostring, pairs, insert
  4.     = tostring, pairs, table.insert
  5. local StringBuilder
  6.     = xs_text.StringBuilder
  7. local check, toWeakTable
  8.     = xs_utils.check, xs_utils.toWeakTable
  9. local bit_or, bit_and
  10.     = bit_or, bit_and
  11.  
  12.  
  13. ---[ PUBLIC ]------------------------------------------------------------------
  14.  
  15. __FILE__ = "xs_cache"
  16.  
  17. class "Cache" (XsObj)
  18.  
  19.     function Cache:__init() super("Cache")
  20.         self.values   = toWeakTable({}, "k")
  21.         self.builders = {}
  22.     end
  23.  
  24.     function Cache:__tostring()
  25.         if self:IsEmpty() then
  26.             return string.format("%s [%08X] (#0)\n", self.__cls, self.__uid)
  27.         end
  28.  
  29.         local buffer = StringBuilder()
  30.         buffer:AppendFormat("%s [%08X] (#%d)\n", self.__cls, self.__uid, self:Count()):IncreaseIndent()
  31.         for k, _ in pairs(self.builders) do
  32.             buffer:AppendLine("[", tostring(k), "] = ", tostring(self.values[k]))
  33.         end
  34.         return buffer:ToString()
  35.     end
  36.  
  37.     function Cache:__len()
  38.         return #self.builders
  39.     end
  40.  
  41.     function Cache:Count()
  42.         return #self.builders
  43.     end
  44.  
  45.     function Cache:IsEmpty()
  46.         return #self.builders == 0
  47.     end
  48.  
  49.     function Cache:Clear()
  50.         self.values   = toWeakTable({}, "k")
  51.         self.builders = {}
  52.     end
  53.  
  54.     function Cache:Register(key, builder)
  55.         check(key ~= nil, "[Cache:Add] argument #1 cannot be nil.")
  56.         check(type(builder) == "function", "[Cache:Add] argument #2 has to be a function")
  57.  
  58.         self.builders[key] = builder
  59.     end
  60.  
  61.     function Cache:Unregister(key)
  62.         check(key ~= nil, "[Cache:Remove] argument #1 cannot be nil.")
  63.  
  64.         if self.builders[key] == nil then
  65.             return false
  66.         end
  67.         self.builders[key] = nil
  68.         self.values[key] = nil
  69.         return true
  70.     end
  71.  
  72.     function Cache:Request(key, ...)
  73.         -- check(key ~= nil, "[Cache:Request] argument #1 cannot be nil.")
  74.         local value = self.values[key]
  75.         if value == nil then
  76.             value = self.builders[key](...)
  77.             self.values[key] = value
  78.         end
  79.         return value
  80.     end
  81.  
  82.     function Cache:Update(key, value)
  83.         -- check(key ~= nil, "[Cache:Update] argument #1 cannot be nil.")
  84.         -- check(self.builder[key] == nil, sprintf("[Cache:Update] Cannot update non-registered key %q.", key))
  85.         self.values[key] = value
  86.     end
  87.  
  88.     function Cache:Contains(key)
  89.         -- check(key ~= nil, "[Cache:Contains] argument #1 cannot be nil.")
  90.         return self.builders[key] ~= nil
  91.     end
  92.  
  93.  
  94. -- These state values exist as to avoid comparing potentially large and complex data.
  95. -- The code would be simpler without that 'optimization' though.
  96. -- So, it may be worth benchmarking this and maybe revert to ComputeCache's previous revision.
  97. local CC_STATE_DEFAULT = 0
  98. local CC_STATE_INVALID = 1
  99. local CC_STATE_UPDATED = 2
  100.  
  101. class "ComputeCache" (XsObj)
  102.  
  103.     function ComputeCache:__init() super("ComputeCache")
  104.         self.signature = nil
  105.         self.result = nil
  106.         self.state   = CC_STATE_DEFAULT
  107.     end
  108.  
  109.     function ComputeCache:IsInvalid(...)
  110.         if bit_and(self.state, CC_STATE_INVALID) ~= 0 or self.signature == nil then
  111.             return true
  112.         end
  113.  
  114.         local params = { ... }
  115.         if #self.signature ~= #params then
  116.             self.state = CC_STATE_INVALID
  117.             return true
  118.         end
  119.  
  120.         for i = 1, #params do
  121.             if params[i] ~= self.signature[i] then
  122.                 self.state = CC_STATE_INVALID
  123.                 return true
  124.             end
  125.         end
  126.         return false
  127.     end
  128.  
  129.     function ComputeCache:Update(...)
  130.         self.signature = toWeakTable({ ... }, "k")
  131.         self.state = bit_or(self.state, CC_STATE_UPDATED + CC_STATE_INVALID)
  132.     end
  133.  
  134.     function ComputeCache:SetResult(result)
  135.         if bit_and(self.state, CC_STATE_UPDATED) == 0 then
  136.             self.state = bit_or(self.state, CC_STATE_INVALID)
  137.         else
  138.             self.state = CC_STATE_DEFAULT
  139.         end
  140.         self.result = result
  141.     end
  142.  
  143.     function ComputeCache:GetResult(result)
  144.         return self.result
  145.     end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement