lrucache.py 2.1 KB

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