Skip to content

Commit 975fa5e

Browse files
committed
Domain __eq__: only cache 10 domains
1 parent f37cd59 commit 975fa5e

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

Orange/data/domain.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def __init__(self, attributes, class_vars=None, metas=None, source=None):
170170
self.anonymous = False
171171

172172
self._hash = None # cache for __hash__()
173-
self._eq_cache = IDWeakrefCache({}) # cache for __eq__()
173+
self._eq_cache = IDWeakrefCache(_LRS10Dict()) # cache for __eq__()
174174

175175
def _ensure_indices(self):
176176
if self._indices is None:
@@ -536,3 +536,12 @@ def __hash__(self):
536536
if self._hash is None:
537537
self._hash = hash(self.attributes) ^ hash(self.class_vars) ^ hash(self.metas)
538538
return self._hash
539+
540+
541+
class _LRS10Dict(dict):
542+
""" A small "least recently stored" (not LRU) dict """
543+
544+
def __setitem__(self, key, value):
545+
if len(self) >= 10:
546+
del self[next(iter(self))]
547+
super().__setitem__(key, value)

Orange/tests/test_domain.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,25 @@ def __hash__(self):
488488
domain1._eq_cache[(domain2,)] = False # pylint: disable=protected-access
489489
self.assertFalse(domain1 == domain2)
490490

491+
def test_eq_cache_not_grow(self):
492+
var = ContinuousVariable('var')
493+
domain = Domain([var])
494+
domains = [Domain([var]) for _ in range(10)]
495+
for d in domains:
496+
self.assertTrue(domain == d)
497+
498+
# __eq__ results to all ten domains should be cached
499+
for d in domains:
500+
domain._eq_cache[(d,)] # pylint: disable=protected-access
501+
502+
dn = Domain([var])
503+
self.assertTrue(domain == dn)
504+
# the last compared domain should be cached
505+
domain._eq_cache[(dn,)] # pylint: disable=protected-access
506+
# but the first compared should be lost in cache
507+
with self.assertRaises(KeyError):
508+
domain._eq_cache[(domains[0],)] # pylint: disable=protected-access
509+
491510
def test_domain_conversion_is_fast_enough(self):
492511
attrs = [ContinuousVariable("f%i" % i) for i in range(10000)]
493512
class_vars = [ContinuousVariable("c%i" % i) for i in range(10)]

0 commit comments

Comments
 (0)