Merge pull request #10085 from hashicorp/dnephin/ttlcache-never-decrease-expiry
lib/ttlcache: never decrease the expiry on update
This commit is contained in:
commit
2619dcd949
|
@ -76,8 +76,10 @@ func (h *ExpiryHeap) Add(key string, expiry time.Duration) *Entry {
|
||||||
return entry
|
return entry
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the entry that is currently at idx with the new expiry time. The heap
|
// Update the entry that is currently at idx with the new expiry time, if the new
|
||||||
// will be rebalanced after the entry is updated.
|
// expiry time is further into the future. The heap will be rebalanced after the
|
||||||
|
// entry is updated. If the new expiry time is earlier than the existing expiry
|
||||||
|
// time than the expiry is not modified.
|
||||||
//
|
//
|
||||||
// Must be synchronized by the caller.
|
// Must be synchronized by the caller.
|
||||||
func (h *ExpiryHeap) Update(idx int, expiry time.Duration) {
|
func (h *ExpiryHeap) Update(idx int, expiry time.Duration) {
|
||||||
|
@ -86,11 +88,15 @@ func (h *ExpiryHeap) Update(idx int, expiry time.Duration) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
entry := h.entries[idx]
|
entry := h.entries[idx]
|
||||||
entry.expiry = time.Now().Add(expiry)
|
newExpiry := time.Now().Add(expiry)
|
||||||
|
|
||||||
|
// Ignore the new expiry if the time is earlier than the existing expiry.
|
||||||
|
if entry.expiry.After(newExpiry) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
entry.expiry = newExpiry
|
||||||
heap.Fix((*entryHeap)(h), idx)
|
heap.Fix((*entryHeap)(h), idx)
|
||||||
|
|
||||||
// If the previous index and current index are both zero then Fix did not
|
|
||||||
// swap the entry, and notify must be called here.
|
|
||||||
if idx == 0 || entry.heapIndex == 0 {
|
if idx == 0 || entry.heapIndex == 0 {
|
||||||
h.notify()
|
h.notify()
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,8 @@ func TestExpiryHeap(t *testing.T) {
|
||||||
testNoMessage(t, ch)
|
testNoMessage(t, ch)
|
||||||
})
|
})
|
||||||
|
|
||||||
runStep(t, "update entry3 to expire first", func(t *testing.T) {
|
runStep(t, "update so that entry3 expires first", func(t *testing.T) {
|
||||||
h.Update(entry3.heapIndex, 10*time.Millisecond)
|
h.Update(entry.heapIndex, 2000*time.Millisecond)
|
||||||
assert.Equal(t, 1, entry.heapIndex)
|
assert.Equal(t, 1, entry.heapIndex)
|
||||||
assert.Equal(t, 0, entry3.heapIndex)
|
assert.Equal(t, 0, entry3.heapIndex)
|
||||||
testMessage(t, ch)
|
testMessage(t, ch)
|
||||||
|
@ -56,12 +56,19 @@ func TestExpiryHeap(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
runStep(t, "0th element change triggers a notify", func(t *testing.T) {
|
runStep(t, "0th element change triggers a notify", func(t *testing.T) {
|
||||||
h.Update(entry3.heapIndex, 20)
|
h.Update(entry3.heapIndex, 1500*time.Millisecond)
|
||||||
assert.Equal(t, 1, entry.heapIndex) // no move
|
assert.Equal(t, 1, entry.heapIndex) // no move
|
||||||
assert.Equal(t, 0, entry3.heapIndex)
|
assert.Equal(t, 0, entry3.heapIndex)
|
||||||
testMessage(t, ch)
|
testMessage(t, ch)
|
||||||
testNoMessage(t, ch) // one message
|
testNoMessage(t, ch) // one message
|
||||||
})
|
})
|
||||||
|
|
||||||
|
runStep(t, "update can not decrease expiry time", func(t *testing.T) {
|
||||||
|
h.Update(entry.heapIndex, 100*time.Millisecond)
|
||||||
|
assert.Equal(t, 1, entry.heapIndex) // no move
|
||||||
|
assert.Equal(t, 0, entry3.heapIndex)
|
||||||
|
testNoMessage(t, ch) // no notify, because no change in the heap
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testNoMessage(t *testing.T, ch <-chan struct{}) {
|
func testNoMessage(t *testing.T, ch <-chan struct{}) {
|
||||||
|
|
Loading…
Reference in New Issue