Skip to content

Commit b87741e

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

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,27 @@ 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+
# pylint: disable=protected-access,pointless-statement
499+
500+
# __eq__ results to all ten domains should be cached
501+
for d in domains:
502+
domain._eq_cache[(d,)]
503+
504+
dn = Domain([var])
505+
self.assertTrue(domain == dn)
506+
# the last compared domain should be cached
507+
domain._eq_cache[(dn,)]
508+
# but the first compared should be lost in cache
509+
with self.assertRaises(KeyError):
510+
domain._eq_cache[(domains[0],)]
511+
491512
def test_domain_conversion_is_fast_enough(self):
492513
attrs = [ContinuousVariable("f%i" % i) for i in range(10000)]
493514
class_vars = [ContinuousVariable("c%i" % i) for i in range(10)]

0 commit comments

Comments
 (0)