Browse Source

Fix bugs in core:container/lru

hanabi1224 3 years ago
parent
commit
4247ba67ed
1 changed files with 15 additions and 6 deletions
  1. 15 6
      core/container/lru/lru_cache.odin

+ 15 - 6
core/container/lru/lru_cache.odin

@@ -60,6 +60,8 @@ clear :: proc(c: ^$C/Cache($Key, $Value), call_on_remove: bool) {
 set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Allocator_Error {
 	if e, ok := c.entries[key]; ok {
 		e.value = value
+		_pop_node(c, e)
+		_push_front_node(c, e)
 		return nil
 	}
 
@@ -67,10 +69,14 @@ set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Alloc
 	e.key = key
 	e.value = value
 
-	_push_front_node(c, e)
-	if c.count > c.capacity {
+	assert(c.count <= c.capacity)
+	if c.count == c.capacity {
 		_remove_node(c, c.tail)
 	}
+	else {
+		c.count += 1
+	}
+	_push_front_node(c, e)
 
 	c.entries[key] = e
 	return nil
@@ -122,6 +128,7 @@ remove :: proc(c: ^$C/Cache($Key, $Value), key: Key) -> bool {
 		return false
 	}
 	_remove_node(c, e)
+	c.count -= 1
 	return true
 }
 
@@ -143,8 +150,6 @@ _remove_node :: proc(c: ^$C/Cache($Key, $Value), node: ^Node(Key, Value)) {
 	node.prev = nil
 	node.next = nil
 
-	c.count -= 1
-
 	delete_key(&c.entries, node.key)
 
 	_call_on_remove(c, node)
@@ -171,8 +176,6 @@ _push_front_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) {
 		c.tail = e
 	}
 	e.prev = nil
-
-	c.count += 1
 }
 
 @(private)
@@ -180,6 +183,12 @@ _pop_node :: proc(c: ^$C/Cache($Key, $Value), e: ^Node(Key, Value)) {
 	if e == nil {
 		return
 	}
+	if c.head == e {
+		c.head = e.next
+	}
+	if c.tail == e {
+		c.tail = e.prev
+	}
 	if e.prev != nil {
 		e.prev.next = e.next
 	}