D4500: util: ability to change capacity when copying lrucachedict

2018-09-12 Thread indygreg (Gregory Szorc)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG2dcc68c7d25b: util: ability to change capacity when copying 
lrucachedict (authored by indygreg, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4500?vs=10819=10939

REVISION DETAIL
  https://phab.mercurial-scm.org/D4500

AFFECTED FILES
  mercurial/util.py
  tests/test-lrucachedict.py

CHANGE DETAILS

diff --git a/tests/test-lrucachedict.py b/tests/test-lrucachedict.py
--- a/tests/test-lrucachedict.py
+++ b/tests/test-lrucachedict.py
@@ -118,5 +118,59 @@
 for key in ('a', 'b', 'c', 'd'):
 self.assertEqual(d[key], 'v%s' % key)
 
+def testcopydecreasecapacity(self):
+d = util.lrucachedict(5)
+d['a'] = 'va'
+d['b'] = 'vb'
+d['c'] = 'vc'
+d['d'] = 'vd'
+
+dc = d.copy(2)
+for key in ('a', 'b'):
+self.assertNotIn(key, dc)
+for key in ('c', 'd'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+dc['e'] = 've'
+self.assertNotIn('c', dc)
+for key in ('d', 'e'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+# Original should remain unchanged.
+for key in ('a', 'b', 'c', 'd'):
+self.assertIn(key, d)
+self.assertEqual(d[key], 'v%s' % key)
+
+def testcopyincreasecapacity(self):
+d = util.lrucachedict(5)
+d['a'] = 'va'
+d['b'] = 'vb'
+d['c'] = 'vc'
+d['d'] = 'vd'
+
+dc = d.copy(6)
+for key in ('a', 'b', 'c', 'd'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+dc['e'] = 've'
+dc['f'] = 'vf'
+for key in ('a', 'b', 'c', 'd', 'e', 'f'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+dc['g'] = 'vg'
+self.assertNotIn('a', dc)
+for key in ('b', 'c', 'd', 'e', 'f', 'g'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+# Original should remain unchanged.
+for key in ('a', 'b', 'c', 'd'):
+self.assertIn(key, d)
+self.assertEqual(d[key], 'v%s' % key)
+
 if __name__ == '__main__':
 silenttestrunner.main(__name__)
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1311,8 +1311,19 @@
 
 self._cache.clear()
 
-def copy(self):
-result = lrucachedict(self.capacity)
+def copy(self, capacity=None):
+"""Create a new cache as a copy of the current one.
+
+By default, the new cache has the same capacity as the existing one.
+But, the cache capacity can be changed as part of performing the
+copy.
+
+Items in the copy have an insertion/access order matching this
+instance.
+"""
+
+capacity = capacity or self.capacity
+result = lrucachedict(capacity)
 
 # We copy entries by iterating in oldest-to-newest order so the copy
 # has the correct ordering.
@@ -1322,6 +1333,8 @@
 while n.key is _notset and n is not self._head:
 n = n.prev
 
+# We could potentially skip the first N items when decreasing capacity.
+# But let's keep it simple unless it is a performance problem.
 for i in range(len(self._cache)):
 result[n.key] = n.value
 n = n.prev



To: indygreg, #hg-reviewers
Cc: mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D4500: util: ability to change capacity when copying lrucachedict

2018-09-06 Thread indygreg (Gregory Szorc)
indygreg created this revision.
Herald added subscribers: mercurial-devel, mjpieters.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This will allow us to easily replace an lrucachedict with one
  with a higher or lower capacity as consumers deem necessary.
  
  IMO it is easier to just create a new cache instance than to
  muck with the capacity of an existing cache. Mutating an existing
  cache's capacity feels more prone to bugs.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D4500

AFFECTED FILES
  mercurial/util.py
  tests/test-lrucachedict.py

CHANGE DETAILS

diff --git a/tests/test-lrucachedict.py b/tests/test-lrucachedict.py
--- a/tests/test-lrucachedict.py
+++ b/tests/test-lrucachedict.py
@@ -118,5 +118,59 @@
 for key in ('a', 'b', 'c', 'd'):
 self.assertEqual(d[key], 'v%s' % key)
 
+def testcopydecreasecapacity(self):
+d = util.lrucachedict(5)
+d['a'] = 'va'
+d['b'] = 'vb'
+d['c'] = 'vc'
+d['d'] = 'vd'
+
+dc = d.copy(2)
+for key in ('a', 'b'):
+self.assertNotIn(key, dc)
+for key in ('c', 'd'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+dc['e'] = 've'
+self.assertNotIn('c', dc)
+for key in ('d', 'e'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+# Original should remain unchanged.
+for key in ('a', 'b', 'c', 'd'):
+self.assertIn(key, d)
+self.assertEqual(d[key], 'v%s' % key)
+
+def testcopyincreasecapacity(self):
+d = util.lrucachedict(5)
+d['a'] = 'va'
+d['b'] = 'vb'
+d['c'] = 'vc'
+d['d'] = 'vd'
+
+dc = d.copy(6)
+for key in ('a', 'b', 'c', 'd'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+dc['e'] = 've'
+dc['f'] = 'vf'
+for key in ('a', 'b', 'c', 'd', 'e', 'f'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+dc['g'] = 'vg'
+self.assertNotIn('a', dc)
+for key in ('b', 'c', 'd', 'e', 'f', 'g'):
+self.assertIn(key, dc)
+self.assertEqual(dc[key], 'v%s' % key)
+
+# Original should remain unchanged.
+for key in ('a', 'b', 'c', 'd'):
+self.assertIn(key, d)
+self.assertEqual(d[key], 'v%s' % key)
+
 if __name__ == '__main__':
 silenttestrunner.main(__name__)
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1311,8 +1311,19 @@
 
 self._cache.clear()
 
-def copy(self):
-result = lrucachedict(self.capacity)
+def copy(self, capacity=None):
+"""Create a new cache as a copy of the current one.
+
+By default, the new cache has the same capacity as the existing one.
+But, the cache capacity can be changed as part of performing the
+copy.
+
+Items in the copy have an insertion/access order matching this
+instance.
+"""
+
+capacity = capacity or self.capacity
+result = lrucachedict(capacity)
 
 # We copy entries by iterating in oldest-to-newest order so the copy
 # has the correct ordering.
@@ -1322,6 +1333,8 @@
 while n.key is _notset and n is not self._head:
 n = n.prev
 
+# We could potentially skip the first N items when decreasing capacity.
+# But let's keep it simple unless it is a performance problem.
 for i in range(len(self._cache)):
 result[n.key] = n.value
 n = n.prev



To: indygreg, #hg-reviewers
Cc: mjpieters, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel