Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up on length call to give accurate dictionary length based on expiration #40

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Clean up on length call to give accurate dictionary length based on e…
…xpiration
chanchiem committed Aug 2, 2019
commit 444502bc1b1f5811c69e34687aad3cbeff85d946
13 changes: 13 additions & 0 deletions expiringdict/__init__.py
Original file line number Diff line number Diff line change
@@ -55,6 +55,19 @@ def __init__(self, max_len, max_age_seconds, items=None):
else:
raise ValueError('can not unpack items')

def __len__(self):
current_key = iter(self)
for k in current_key:
item = OrderedDict.__getitem__(self, k)
time_added = item[1]
item_age = time.time() - time_added
if item_age > self.max_age:
del self[k]
else:
break

return super(ExpiringDict, self).__len__()

def __contains__(self, key):
""" Return True if the dict has a key, else return False. """
try:
45 changes: 44 additions & 1 deletion tests/expiringdict_test.py
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ def test_repr():
d['a'] = 'x'
eq_(str(d), "ExpiringDict([('a', 'x')])")
sleep(0.01)
eq_(str(d), "ExpiringDict([])")
eq_(str(d), "ExpiringDict()")


def test_iter():
@@ -122,3 +122,46 @@ def test_not_implemented():
assert_raises(NotImplementedError, d.viewitems)
assert_raises(NotImplementedError, d.viewkeys)
assert_raises(NotImplementedError, d.viewvalues)


def test_cleanup_on_length():
d = ExpiringDict(max_len=10, max_age_seconds=0.01)
d['a'] = 'x'
eq_(1, len(d))
sleep(0.01)
eq_(0, len(d))

d = ExpiringDict(max_len=10, max_age_seconds=0.02)
d['a'] = 1
sleep(0.01)
eq_(1, len(d))
d['b'] = 2
sleep(0.01)
eq_(1, len(d))
d['c'] = 3
sleep(0.01)
eq_(1, len(d))
d['d'] = 4
sleep(0.01)
eq_(1, len(d))

d = ExpiringDict(max_len=1000, max_age_seconds=.5)
d[1] = 1
d[2] = 2
d[3] = 3
d[4] = 4

ok_(1 in d)
ok_(2 in d)
ok_(3 in d)
ok_(4 in d)
eq_(4, len(d))

sleep(.25)
d[1] = 1
d[2] = 2
sleep(.40)
ok_(1 in d)
ok_(2 in d)
ok_(3 not in d)
ok_(4 not in d)