Skip to content

Commit e190cfe

Browse files
committed
WIP
1 parent 101ad64 commit e190cfe

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

aiomisc/cache/lfu.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
from dataclasses import dataclass
22
from threading import RLock
3-
from typing import Any, Hashable, Optional
3+
from typing import Any, Hashable, Optional, Set
44

5-
from llist import dllistnode, dllist
5+
6+
@dataclass(unsafe_hash=True)
7+
class Node:
8+
prev: Optional["Node"]
9+
next: Optional["Node"]
10+
items: Set["Item"]
611

712

813
@dataclass(frozen=True)
9-
class FrequencyItem:
10-
node: dllistnode
14+
class Item:
15+
node: Node
1116
key: Hashable
1217
value: Any
1318

@@ -28,48 +33,53 @@ class LFUCache:
2833

2934
def __init__(self, max_size: int = 0):
3035
self.cache = dict()
31-
self.usages = dllist()
36+
self.usages: Node = Node(prev=None, next=None, items=set())
3237
self.lock = RLock()
3338
self.size = 0
3439
self.max_size = max_size
3540

36-
def _create_node(self) -> dllistnode:
37-
return self.usages.append(set([]))
41+
def _create_node(self) -> Node:
42+
node = Node(prev=self.usages, next=None, items=set())
43+
self.usages.next = node
44+
return node
3845

39-
def _update_usage(self, item: FrequencyItem):
46+
def _update_usage(self, item: Item):
4047
with self.lock:
4148
old_node = item.node
4249
new_node = item.node.next
4350

4451
if new_node is None:
4552
new_node = self._create_node()
4653

47-
old_node.value.remove(item)
48-
item = FrequencyItem(
54+
old_node.items.remove(item)
55+
item = Item(
4956
node=new_node,
5057
key=item.key,
5158
value=item.value,
5259
)
53-
new_node.value.add(item)
60+
new_node.items.add(item)
5461
self.cache[item.key] = item
5562

56-
if not old_node.value:
57-
self.usages.remove(old_node)
63+
if not old_node.items:
64+
old_node.next = None
65+
old_node.prev = None
66+
self.usages = new_node
67+
self.usages.prev = None
5868

5969
def get(self, key: Hashable):
60-
item: FrequencyItem = self.cache[key]
70+
item: Item = self.cache[key]
6171
self._update_usage(item)
6272
return item.value
6373

6474
def set(self, key: Hashable, value: Any):
6575
with self.lock:
66-
node: Optional[dllistnode] = self.usages.first
76+
node: Optional[Node] = self.usages
6777

6878
if node is None:
6979
node = self._create_node()
7080

71-
item = FrequencyItem(node=node, key=key, value=value)
72-
node.value.add(item)
81+
item = Item(node=node, key=key, value=value)
82+
node.items.add(item)
7383
self.cache[key] = item
7484

7585
def __contains__(self, key) -> Any:

0 commit comments

Comments
 (0)