Skip to content

Commit 18bddc1

Browse files
committed
Add timeout mechaism for cache.
1 parent 5f38c65 commit 18bddc1

File tree

4 files changed

+34
-14
lines changed

4 files changed

+34
-14
lines changed

mybatis/cache.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import pickle
3+
import time
34
from typing import Dict, Any, Optional
45

56
from pympler import asizeof
@@ -9,18 +10,11 @@ def __init__(self, sql, param_list):
910
self.sql = sql
1011
self.param_list = param_list
1112

12-
def __hash__(self):
13-
return hash((self.sql, self.param_list))
14-
15-
def __eq__(self, other):
16-
if not isinstance(other, CacheKey):
17-
return False
18-
return self.sql == other.sql and self.param_list == other.param_list
19-
2013
class Cache(object):
21-
def __init__(self, memory_limit:int):
14+
def __init__(self, memory_limit:int, max_live_ms:int):
2215
self.memory_limit = memory_limit
2316
self.memory_used = 0
17+
self.max_live_ms = max_live_ms
2418
self.table : Dict[str, CacheNode] = {}
2519
self.list = CacheList()
2620

@@ -69,7 +63,15 @@ def get(self, raw_key: CacheKey) -> Optional[Any]:
6963
key = json.dumps(raw_key.__dict__)
7064
if key not in self.table:
7165
return None
66+
7267
node = self.table[key]
68+
current_time_ms = int(time.time() * 1000)
69+
if current_time_ms - node.timestamp > self.max_live_ms:
70+
del self.table[node.key]
71+
self.list.remove(node)
72+
self.memory_used -= node.memory_usage
73+
return None
74+
7375
self.list.move_to_head(node)
7476
return json.loads(node.value)
7577

@@ -89,6 +91,7 @@ def __init__(self, key : Any, value : Any):
8991
self.memory_usage = asizeof.asizeof(key) + asizeof.asizeof(value)
9092
self.key = key
9193
self.value = value
94+
self.timestamp = int(time.time() * 1000)
9295

9396
class CacheList:
9497
def __init__(self):

mybatis/mybatis.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
import os
77

88
class Mybatis(object):
9-
def __init__(self, conn, mapper_path:str, cache_memory_limit:Optional[int]=None):
9+
def __init__(self, conn, mapper_path:str, cache_memory_limit:Optional[int]=None, cache_max_live_ms:int=5*1000):
1010
self.conn = conn
1111
self.mapper_manager = MapperManager()
1212

1313
if cache_memory_limit is not None:
14-
self.cache = Cache(cache_memory_limit)
14+
self.cache = Cache(cache_memory_limit, cache_max_live_ms)
1515
else:
16-
self.cache = Cache(0)
16+
self.cache = Cache(0, cache_max_live_ms)
1717

1818
mapper_file_name_l = [name for name in os.listdir(mapper_path) if name.endswith(".xml")]
1919
for file_name in mapper_file_name_l:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name='mybatis',
5-
version='0.0.6',
5+
version='0.0.7',
66
description='A python ORM like mybatis.',
77
long_description=open('README.md').read(),
88
long_description_content_type='text/markdown', # 如果你使用的是Markdown格式的README

test/test_cache.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import time
2+
13
import pytest
24
from mybatis import Cache, CacheKey
35

46
def test_basic():
5-
cache = Cache(memory_limit=555) # 50MB
7+
cache = Cache(memory_limit=555, max_live_ms=10*1000) # 50MB, 10sec
68
cache.put(CacheKey("a", [1, 'a', None]), [{"a1": 1}, {"a2": 2}])
79
cache.put(CacheKey("b", [2, 'b', None]), "2")
810
cache.put(CacheKey("c", [3, 'c', None]), "3")
@@ -42,3 +44,18 @@ def test_basic():
4244

4345
assert l[2][0] == '{"sql": "d", "param_list": [4, "d", null]}'
4446
assert l[2][1] == None
47+
48+
def test_timeout():
49+
cache = Cache(memory_limit=555, max_live_ms=1 * 1000) # 50MB, 10sec
50+
cache.put(CacheKey("a", [1, 'a', None]), [{"a1": 1}, {"a2": 2}])
51+
cache.put(CacheKey("b", [2, 'b', None]), "2")
52+
cache.put(CacheKey("c", [3, 'c', None]), "3")
53+
cache.put(CacheKey("d", [4, 'd', None]), None)
54+
55+
time.sleep(2)
56+
assert cache.get(CacheKey("a", [1, 'a', None])) == None
57+
assert cache.get(CacheKey("b", [2, 'b', None])) == None
58+
assert cache.get(CacheKey("c", [3, 'c', None])) == None
59+
assert cache.get(CacheKey("d", [4, 'd', None])) == None
60+
61+
assert cache.memory_used == 0

0 commit comments

Comments
 (0)