Skip to content

Commit 467de6c

Browse files
committed
implement max_items in memoization.cached
1 parent ecc9a98 commit 467de6c

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

memoization.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import collections
12
import inspect
23
import warnings
34
from functools import wraps
@@ -10,13 +11,15 @@ def decorator(func):
1011
# type checks
1112
if not _is_function(func):
1213
raise TypeError('Unable to do memoization on non-function object ' + str(func))
14+
if max_items is not None and (not isinstance(max_items, int) or max_items <= 0):
15+
raise ValueError('Illegal max_items <' + str(max_items) + '>: must be a positive integer')
1316
arg_spec = inspect.getargspec(func)
1417
if len(arg_spec.args) == 0 and arg_spec.varargs is None and arg_spec.keywords is None:
1518
warnings.warn('It\'s meaningless to do memoization on a function with no arguments', SyntaxWarning)
1619

1720
# init cache for func
1821
initial_function_id = id(func)
19-
_cache[initial_function_id] = {}
22+
_cache[initial_function_id] = {} if max_items is None else collections.OrderedDict()
2023

2124
@wraps(func)
2225
def wrapper(*args, **kwargs):
@@ -29,6 +32,8 @@ def wrapper(*args, **kwargs):
2932
return cache_unit['result']
3033
else: # not yet cached
3134
output = func(*args, **kwargs) # execute func
35+
if max_items is not None and _size_explicit(function_id) >= max_items:
36+
specified_cache.popitem(last=False)
3237
specified_cache[input_args] = {'result': output, 'access_count': 0} # make cache
3338
return output
3439
return wrapper
@@ -65,6 +70,10 @@ def size(func=None):
6570
return len(_cache[_retrieve_safe_function_id(func)])
6671

6772

73+
def _size_explicit(func_id):
74+
return len(_cache[func_id])
75+
76+
6877
def _hashable_args(args, kwargs):
6978
kwargs_str = ''
7079
for key, value in kwargs:

0 commit comments

Comments
 (0)