25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

80 satır
2.2 KiB

  1. cdef object _LRU_MARKER = object()
  2. @cython.final
  3. cdef class LruCache:
  4. cdef:
  5. object _dict
  6. int _maxsize
  7. object _dict_move_to_end
  8. object _dict_get
  9. # We use an OrderedDict for LRU implementation. Operations:
  10. #
  11. # * We use a simple `__setitem__` to push a new entry:
  12. # `entries[key] = new_entry`
  13. # That will push `new_entry` to the *end* of the entries dict.
  14. #
  15. # * When we have a cache hit, we call
  16. # `entries.move_to_end(key, last=True)`
  17. # to move the entry to the *end* of the entries dict.
  18. #
  19. # * When we need to remove entries to maintain `max_size`, we call
  20. # `entries.popitem(last=False)`
  21. # to remove an entry from the *beginning* of the entries dict.
  22. #
  23. # So new entries and hits are always promoted to the end of the
  24. # entries dict, whereas the unused one will group in the
  25. # beginning of it.
  26. def __init__(self, *, maxsize):
  27. if maxsize <= 0:
  28. raise ValueError(
  29. f'maxsize is expected to be greater than 0, got {maxsize}')
  30. self._dict = col_OrderedDict()
  31. self._dict_move_to_end = self._dict.move_to_end
  32. self._dict_get = self._dict.get
  33. self._maxsize = maxsize
  34. cdef get(self, key, default):
  35. o = self._dict_get(key, _LRU_MARKER)
  36. if o is _LRU_MARKER:
  37. return default
  38. self._dict_move_to_end(key) # last=True
  39. return o
  40. cdef inline needs_cleanup(self):
  41. return len(self._dict) > self._maxsize
  42. cdef inline cleanup_one(self):
  43. k, _ = self._dict.popitem(last=False)
  44. return k
  45. def __getitem__(self, key):
  46. o = self._dict[key]
  47. self._dict_move_to_end(key) # last=True
  48. return o
  49. def __setitem__(self, key, o):
  50. if key in self._dict:
  51. self._dict[key] = o
  52. self._dict_move_to_end(key) # last=True
  53. else:
  54. self._dict[key] = o
  55. while self.needs_cleanup():
  56. self.cleanup_one()
  57. def __delitem__(self, key):
  58. del self._dict[key]
  59. def __contains__(self, key):
  60. return key in self._dict
  61. def __len__(self):
  62. return len(self._dict)
  63. def __iter__(self):
  64. return iter(self._dict)