##// END OF EJS Templates
util: lower water mark when removing nodes after cost limit reached...
Gregory Szorc -
r39606:f296c0b3 default
parent child Browse files
Show More
@@ -1472,11 +1472,21 b' class lrucachedict(object):'
1472 1472 # to walk the linked list and doing this in a loop would be
1473 1473 # quadratic. So we find the first non-empty node and then
1474 1474 # walk nodes until we free up enough capacity.
1475 #
1476 # If we only removed the minimum number of nodes to free enough
1477 # cost at insert time, chances are high that the next insert would
1478 # also require pruning. This would effectively constitute quadratic
1479 # behavior for insert-heavy workloads. To mitigate this, we set a
1480 # target cost that is a percentage of the max cost. This will tend
1481 # to free more nodes when the high water mark is reached, which
1482 # lowers the chances of needing to prune on the subsequent insert.
1483 targetcost = int(self.maxcost * 0.75)
1484
1475 1485 n = self._head.prev
1476 1486 while n.key is _notset:
1477 1487 n = n.prev
1478 1488
1479 while len(self) > 1 and self.totalcost > self.maxcost:
1489 while len(self) > 1 and self.totalcost > targetcost:
1480 1490 del self._cache[n.key]
1481 1491 self.totalcost -= n.cost
1482 1492 n.markempty()
@@ -314,10 +314,10 b' class testlrucachedict(unittest.TestCase'
314 314 # Inserting new element should free multiple elements so we hit
315 315 # low water mark.
316 316 d.insert('e', 'vd', cost=25)
317 self.assertEqual(len(d), 3)
317 self.assertEqual(len(d), 2)
318 318 self.assertNotIn('a', d)
319 319 self.assertNotIn('b', d)
320 self.assertIn('c', d)
320 self.assertNotIn('c', d)
321 321 self.assertIn('d', d)
322 322 self.assertIn('e', d)
323 323
General Comments 0
You need to be logged in to leave comments. Login now