On delete, always set promotions == -2 and node == nil

Also, item.promotions doesn't need to be loaded/stored using atomic. Once upon a
time it did. Cache was updated long ago to not use atomic operations on it, but
LayeredCache wasn't. They are both consistent now (they don't use atomic
operations).

Fixes: https://github.com/karlseguin/ccache/issues/76
This commit is contained in:
Karl Seguin
2022-12-13 20:33:58 +08:00
parent 3452e4e261
commit ece93bf87d
4 changed files with 9 additions and 5 deletions

View File

@@ -394,6 +394,8 @@ func (c *Cache[T]) doDelete(item *Item[T]) {
c.onDelete(item) c.onDelete(item)
} }
c.list.Remove(item.node) c.list.Remove(item.node)
item.node = nil
item.promotions = -2
} }
} }

View File

@@ -332,7 +332,7 @@ func Test_CachePrune(t *testing.T) {
cache.Set(key, key, 5*time.Minute) cache.Set(key, key, 5*time.Minute)
} }
if epoch%500 == 0 { if epoch%500 == 0 {
assert.True(t, cache.GetSize() < 500) assert.True(t, cache.GetSize() <= 500)
} }
} }
} }

View File

@@ -266,13 +266,15 @@ func (c *LayeredCache[T]) worker() {
} }
deleteItem := func(item *Item[T]) { deleteItem := func(item *Item[T]) {
if item.node == nil { if item.node == nil {
atomic.StoreInt32(&item.promotions, -2) item.promotions = -2
} else { } else {
c.size -= item.size c.size -= item.size
if c.onDelete != nil { if c.onDelete != nil {
c.onDelete(item) c.onDelete(item)
} }
c.list.Remove(item.node) c.list.Remove(item.node)
item.node = nil
item.promotions = -2
} }
} }
for { for {
@@ -318,13 +320,13 @@ func (c *LayeredCache[T]) worker() {
func (c *LayeredCache[T]) doPromote(item *Item[T]) bool { func (c *LayeredCache[T]) doPromote(item *Item[T]) bool {
// deleted before it ever got promoted // deleted before it ever got promoted
if atomic.LoadInt32(&item.promotions) == -2 { if item.promotions == -2 {
return false return false
} }
if item.node != nil { //not a new item if item.node != nil { //not a new item
if item.shouldPromote(c.getsPerPromote) { if item.shouldPromote(c.getsPerPromote) {
c.list.MoveToFront(item.node) c.list.MoveToFront(item.node)
atomic.StoreInt32(&item.promotions, 0) item.promotions = 0
} }
return false return false
} }

View File

@@ -391,7 +391,7 @@ func Test_LayeredCachePrune(t *testing.T) {
cache.Set(key, key, key, 5*time.Minute) cache.Set(key, key, key, 5*time.Minute)
} }
if epoch%500 == 0 { if epoch%500 == 0 {
assert.True(t, cache.GetSize() < 500) assert.True(t, cache.GetSize() <= 500)
} }
} }
} }