112 lines
2 KiB
Python
112 lines
2 KiB
Python
import re
|
|
|
|
from datetime import datetime
|
|
from collections import OrderedDict
|
|
|
|
|
|
def parse_ttl(ttl):
|
|
m = re.match(r'^(\d+)([smhdw]?)$', ttl)
|
|
|
|
if not m:
|
|
logging.warning(f'Invalid TTL: {ttl}. Setting to default: 1h')
|
|
amount = 1
|
|
unit = 'h'
|
|
|
|
else:
|
|
amount = m.group(1)
|
|
unit = m.group(2)
|
|
|
|
units = {
|
|
's': 1,
|
|
'm': 60,
|
|
'h': 60 * 60,
|
|
'd': 24 * 60 * 60,
|
|
'w': 7 * 24 * 60 * 60,
|
|
}
|
|
|
|
if unit:
|
|
multiplier = units[unit]
|
|
|
|
else:
|
|
multiplier = 1
|
|
|
|
return multiplier * int(amount)
|
|
|
|
|
|
class TTLCache:
|
|
def __init__(self, ttl='1h', maxsize=1024):
|
|
self.items = OrderedDict()
|
|
self.ttl = parse_ttl(ttl)
|
|
self.maxsize = maxsize
|
|
|
|
|
|
def invalidate(self, key):
|
|
if key in self.items:
|
|
del self.items[key]
|
|
|
|
|
|
def store(self, key, value):
|
|
timestamp = int(datetime.timestamp(datetime.now()))
|
|
item = self.items.get(key)
|
|
|
|
while len(self.items) >= self.maxsize and self.maxsize != 0:
|
|
self.items.popitem(last=False)
|
|
|
|
if item == None:
|
|
data = {'data': value}
|
|
self.items[key] = data
|
|
|
|
elif self.items[key]['timestamp'] + self.ttl < timestamp:
|
|
del self.items[key]
|
|
|
|
self.items[key]['timestamp'] = timestamp + self.ttl
|
|
self.items.move_to_end(key)
|
|
|
|
|
|
def fetch(self, key):
|
|
item = self.items.get(key)
|
|
|
|
if item != None:
|
|
timestamp = int(datetime.timestamp(datetime.now()))
|
|
|
|
if timestamp >= self.items[key]['timestamp']:
|
|
del self.items[key]
|
|
|
|
else:
|
|
self.items[key]['timestamp'] = timestamp + self.ttl
|
|
self.items.move_to_end(key)
|
|
return self.items[key]['data']
|
|
|
|
|
|
class LRUCache:
|
|
def __init__(self, maxsize=1024):
|
|
self.items = OrderedDict()
|
|
self.maxsize = maxsize
|
|
|
|
|
|
def invalidate(self, key):
|
|
if key in self.items:
|
|
del self.items[key]
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def store(self, key, value):
|
|
while len(self.items) >= self.maxsize and self.maxsize != 0:
|
|
self.items.popitem(last=False)
|
|
|
|
if (key in self.items) == False:
|
|
self.items[key] = value
|
|
|
|
self.items.move_to_end(key)
|
|
|
|
|
|
def fetch(self, key):
|
|
if key in self.items:
|
|
return self.items[key]
|
|
|
|
return
|
|
|