lrucache.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from heapq import heappush, heapify, heapreplace, heappop
  2. import unittest
  3. class LRUCache(dict):
  4. def __init__(self, capacity):
  5. super(LRUCache, self).__init__()
  6. self._lru = []
  7. self._capacity = capacity
  8. def __setitem__(self, key, value):
  9. try:
  10. self._lru.remove(key)
  11. except ValueError:
  12. pass
  13. self._lru.append(key)
  14. while len(self._lru) > self._capacity:
  15. del self[self._lru[0]]
  16. return super(LRUCache, self).__setitem__(key, value)
  17. def __getitem__(self, key):
  18. try:
  19. self._lru.remove(key)
  20. self._lru.append(key)
  21. except ValueError:
  22. pass
  23. return super(LRUCache, self).__getitem__(key)
  24. def __delitem__(self, key):
  25. try:
  26. self._lru.remove(key)
  27. except ValueError:
  28. pass
  29. return super(LRUCache, self).__delitem__(key)
  30. def pop(self, key, default=None):
  31. try:
  32. self._lru.remove(key)
  33. except ValueError:
  34. pass
  35. return super(LRUCache, self).pop(key, default)
  36. def _not_implemented(self, *args, **kw):
  37. raise NotImplementedError
  38. popitem = setdefault = update = _not_implemented
  39. class LRUCacheTestCase(unittest.TestCase):
  40. def test(self):
  41. c = LRUCache(2)
  42. self.assertEqual(len(c), 0)
  43. for i, x in enumerate('abc'):
  44. c[x] = i
  45. self.assertEqual(len(c), 2)
  46. self.assertEqual(set(c), set(['b', 'c']))
  47. self.assertEqual(set(c.items()), set([('b', 1), ('c', 2)]))
  48. self.assertEqual(False, 'a' in c)
  49. self.assertEqual(True, 'b' in c)
  50. self.assertRaises(KeyError, lambda: c['a'])
  51. self.assertEqual(c['b'], 1)
  52. self.assertEqual(c['c'], 2)
  53. c['d'] = 3
  54. self.assertEqual(len(c), 2)
  55. self.assertEqual(c['c'], 2)
  56. self.assertEqual(c['d'], 3)
  57. c['c'] = 22
  58. c['e'] = 4
  59. self.assertEqual(len(c), 2)
  60. self.assertRaises(KeyError, lambda: c['d'])
  61. self.assertEqual(c['c'], 22)
  62. self.assertEqual(c['e'], 4)
  63. del c['c']
  64. self.assertEqual(len(c), 1)
  65. self.assertRaises(KeyError, lambda: c['c'])
  66. self.assertEqual(c['e'], 4)
  67. def test_pop(self):
  68. c = LRUCache(2)
  69. c[1] = 1
  70. c[2] = 2
  71. c.pop(1)
  72. c[3] = 3
  73. def suite():
  74. return unittest.TestLoader().loadTestsFromTestCase(LRUCacheTestCase)
  75. if __name__ == '__main__':
  76. unittest.main()