aboutsummaryrefslogtreecommitdiff
path: root/decaymap
diff options
context:
space:
mode:
authorJason Cameron <git@jasoncameron.dev>2025-03-29 23:24:06 -0400
committerGitHub <noreply@github.com>2025-03-29 23:24:06 -0400
commit0f41388bd78668ceae6d5c12b05868bd0ca8fd1f (patch)
treee60f01da1b446e8ec98aa66a70da2969a7f4e9ad /decaymap
parent052316ba25c86d5dcc870cd5b4c045ea67110562 (diff)
downloadanubis-0f41388bd78668ceae6d5c12b05868bd0ca8fd1f.tar.xz
anubis-0f41388bd78668ceae6d5c12b05868bd0ca8fd1f.zip
Add periodic cleanup job for DecayMap (#8) (#158)
* Add periodic cleanup job for DecayMap see https://github.com/TecharoHQ/anubis/issues/8 * Refactor: Improve DecayMap cleanup tests and add Len method - Refactored DecayMap cleanup tests to use the new Len method for more precise assertions. - Added a Len method to DecayMap to retrieve the number of entries. - Simplified conditional checks in Get method. * chore(changelog): add entry * fix(tests): Use Impl.expire for decaymap cleanup Signed-off-by: Jason Cameron <git@jasoncameron.dev> --------- Signed-off-by: Jason Cameron <git@jasoncameron.dev>
Diffstat (limited to 'decaymap')
-rw-r--r--decaymap/decaymap.go20
-rw-r--r--decaymap/decaymap_test.go29
2 files changed, 49 insertions, 0 deletions
diff --git a/decaymap/decaymap.go b/decaymap/decaymap.go
index 7498bb5..57ee6c2 100644
--- a/decaymap/decaymap.go
+++ b/decaymap/decaymap.go
@@ -85,3 +85,23 @@ func (m *Impl[K, V]) Set(key K, value V, ttl time.Duration) {
expiry: time.Now().Add(ttl),
}
}
+
+// Cleanup removes all expired entries from the DecayMap.
+func (m *Impl[K, V]) Cleanup() {
+ m.lock.Lock()
+ defer m.lock.Unlock()
+
+ now := time.Now()
+ for key, entry := range m.data {
+ if now.After(entry.expiry) {
+ delete(m.data, key)
+ }
+ }
+}
+
+// Len returns the number of entries in the DecayMap.
+func (m *Impl[K, V]) Len() int {
+ m.lock.RLock()
+ defer m.lock.RUnlock()
+ return len(m.data)
+}
diff --git a/decaymap/decaymap_test.go b/decaymap/decaymap_test.go
index c930e08..c1830ed 100644
--- a/decaymap/decaymap_test.go
+++ b/decaymap/decaymap_test.go
@@ -29,3 +29,32 @@ func TestImpl(t *testing.T) {
t.Error("got value even though it was supposed to be expired")
}
}
+
+func TestCleanup(t *testing.T) {
+ dm := New[string, string]()
+
+ dm.Set("test1", "hi1", 1*time.Second)
+ dm.Set("test2", "hi2", 2*time.Second)
+ dm.Set("test3", "hi3", 3*time.Second)
+
+ dm.expire("test1") // Force expire test1
+ dm.expire("test2") // Force expire test2
+
+ dm.Cleanup()
+
+ finalLen := dm.Len() // Get the length after cleanup
+
+ if finalLen != 1 { // "test3" should be the only one left
+ t.Errorf("Cleanup failed to remove expired entries. Expected length 1, got %d", finalLen)
+ }
+
+ if _, ok := dm.Get("test1"); ok { // Verify Get still behaves correctly after Cleanup
+ t.Error("test1 should not be found after cleanup")
+ }
+ if _, ok := dm.Get("test2"); ok {
+ t.Error("test2 should not be found after cleanup")
+ }
+ if val, ok := dm.Get("test3"); !ok || val != "hi3" {
+ t.Error("test3 should still be found after cleanup")
+ }
+}