Skip to content

Commit 8dc15ce

Browse files
Thomas StrombergThomas Stromberg
authored andcommitted
memory optimization
1 parent 38320da commit 8dc15ce

File tree

7 files changed

+209
-129
lines changed

7 files changed

+209
-129
lines changed

benchmarks/runner.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,10 +625,12 @@ func validateCompetitive(res, prev *Results, testsFilter, suitesFilter string) e
625625

626626
// For partial suite runs, only validate relevant placements.
627627
var fails []string
628+
headerPrinted := false
628629

629630
// Score validation only for full runs.
630631
if fullRun {
631632
fmt.Println("\n=== Final Validation ===")
633+
headerPrinted = true
632634
if mc.Score >= minMulticacheScore {
633635
fmt.Printf("✓ multicache score: %d (goal: ≥%d)\n", mc.Score, minMulticacheScore)
634636
} else {
@@ -672,9 +674,9 @@ func validateCompetitive(res, prev *Results, testsFilter, suitesFilter string) e
672674

673675
for _, r := range cat.Rankings {
674676
if r.Name == "multicache" {
675-
// Print header if we haven't yet (partial suite run).
676-
if !fullRun {
677+
if !headerPrinted {
677678
fmt.Println("\n=== Final Validation ===")
679+
headerPrinted = true
678680
}
679681
if r.Rank <= maxPlace {
680682
fmt.Printf("✓ %s placement: %d (goal: ≤%d)\n", cat.Name, r.Rank, maxPlace)

memory.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (c *Cache[K, V]) Set(key K, value V) {
6464
c.memory.set(key, value, 0)
6565
return
6666
}
67-
c.memory.set(key, value, timeToNano(c.expiry(0)))
67+
c.memory.set(key, value, timeToSec(c.expiry(0)))
6868
}
6969

7070
// SetTTL stores a value with an explicit TTL.
@@ -74,7 +74,7 @@ func (c *Cache[K, V]) SetTTL(key K, value V, ttl time.Duration) {
7474
c.memory.set(key, value, 0)
7575
return
7676
}
77-
c.memory.set(key, value, time.Now().Add(ttl).UnixNano())
77+
c.memory.set(key, value, uint32(time.Now().Add(ttl).Unix()))
7878
}
7979

8080
// Delete removes a key from the cache.

memory_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ func TestCache_Basic(t *testing.T) {
4040
func TestCache_WithTTL(t *testing.T) {
4141
cache := New[string, string]()
4242

43-
// Set with short TTL
44-
cache.SetTTL("temp", "value", 50*time.Millisecond)
43+
// Set with short TTL (minimum 1 second granularity)
44+
cache.SetTTL("temp", "value", 1*time.Second)
4545

4646
// Should be available immediately
4747
val, found := cache.Get("temp")
@@ -50,7 +50,7 @@ func TestCache_WithTTL(t *testing.T) {
5050
}
5151

5252
// Wait for expiration
53-
time.Sleep(100 * time.Millisecond)
53+
time.Sleep(2 * time.Second)
5454

5555
// Should be expired
5656
_, found = cache.Get("temp")
@@ -60,7 +60,7 @@ func TestCache_WithTTL(t *testing.T) {
6060
}
6161

6262
func TestCache_DefaultTTL(t *testing.T) {
63-
cache := New[string, int](TTL(50 * time.Millisecond))
63+
cache := New[string, int](TTL(1 * time.Second))
6464

6565
// Set without explicit TTL (ttl=0 uses default)
6666
cache.Set("key", 100)
@@ -72,7 +72,7 @@ func TestCache_DefaultTTL(t *testing.T) {
7272
}
7373

7474
// Wait for default TTL expiration
75-
time.Sleep(100 * time.Millisecond)
75+
time.Sleep(2 * time.Second)
7676

7777
// Should be expired
7878
_, found = cache.Get("key")
@@ -236,11 +236,11 @@ func TestCache_EvictFromMain(t *testing.T) {
236236
func TestCache_GetExpired(t *testing.T) {
237237
cache := New[string, int]()
238238

239-
// Set with very short TTL
240-
cache.SetTTL("key1", 42, 1*time.Millisecond)
239+
// Set with short TTL (1 second granularity)
240+
cache.SetTTL("key1", 42, 1*time.Second)
241241

242242
// Wait for expiration
243-
time.Sleep(10 * time.Millisecond)
243+
time.Sleep(2 * time.Second)
244244

245245
// Get should return not found
246246
_, found := cache.Get("key1")
@@ -368,8 +368,8 @@ func TestCache_SetTTL(t *testing.T) {
368368
t.Error("default-ttl should be found")
369369
}
370370

371-
// SetTTL uses explicit short TTL
372-
cache.SetTTL("short-ttl", 2, 50*time.Millisecond)
371+
// SetTTL uses explicit short TTL (1 second granularity)
372+
cache.SetTTL("short-ttl", 2, 1*time.Second)
373373
if _, found := cache.Get("short-ttl"); !found {
374374
t.Error("short-ttl should be found immediately")
375375
}
@@ -387,7 +387,7 @@ func TestCache_SetTTL(t *testing.T) {
387387
}
388388

389389
// Wait for short TTL to expire
390-
time.Sleep(100 * time.Millisecond)
390+
time.Sleep(2 * time.Second)
391391

392392
// short-ttl should be expired, others should still exist
393393
if _, found := cache.Get("short-ttl"); found {
@@ -411,7 +411,7 @@ func TestCache_Set_NoDefaultTTL(t *testing.T) {
411411
cache.Set("no-expiry", 42)
412412

413413
// Wait a bit
414-
time.Sleep(50 * time.Millisecond)
414+
time.Sleep(100 * time.Millisecond)
415415

416416
// Should still exist
417417
val, found := cache.Get("no-expiry")
@@ -531,8 +531,8 @@ func TestCache_GetSet_WithTTL(t *testing.T) {
531531
return loaderCalls * 10, nil
532532
}
533533

534-
// First call with short TTL
535-
val, err := cache.GetSetTTL("key1", loader, 50*time.Millisecond)
534+
// First call with short TTL (1 second granularity)
535+
val, err := cache.GetSetTTL("key1", loader, 1*time.Second)
536536
if err != nil {
537537
t.Fatalf("GetSet error: %v", err)
538538
}
@@ -541,10 +541,10 @@ func TestCache_GetSet_WithTTL(t *testing.T) {
541541
}
542542

543543
// Wait for TTL to expire
544-
time.Sleep(100 * time.Millisecond)
544+
time.Sleep(2 * time.Second)
545545

546546
// Second call - should call loader again (cache expired)
547-
val, err = cache.GetSetTTL("key1", loader, 50*time.Millisecond)
547+
val, err = cache.GetSetTTL("key1", loader, 1*time.Second)
548548
if err != nil {
549549
t.Fatalf("GetSet error: %v", err)
550550
}

persistent.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (c *TieredCache[K, V]) Get(ctx context.Context, key K) (V, bool, error) {
6262
return zero, false, nil
6363
}
6464

65-
c.memory.set(key, val, timeToNano(expiry))
65+
c.memory.set(key, val, timeToSec(expiry))
6666
return val, true, nil
6767
}
6868

@@ -85,7 +85,7 @@ func (c *TieredCache[K, V]) SetTTL(ctx context.Context, key K, value V, ttl time
8585
return err
8686
}
8787

88-
c.memory.set(key, value, timeToNano(expiry))
88+
c.memory.set(key, value, timeToSec(expiry))
8989

9090
if err := c.Store.Set(ctx, key, value, expiry); err != nil {
9191
return fmt.Errorf("persistence store failed: %w", err)
@@ -108,7 +108,7 @@ func (c *TieredCache[K, V]) SetAsyncTTL(ctx context.Context, key K, value V, ttl
108108
return err
109109
}
110110

111-
c.memory.set(key, value, timeToNano(expiry))
111+
c.memory.set(key, value, timeToSec(expiry))
112112

113113
go func() {
114114
storeCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), asyncTimeout)
@@ -148,7 +148,7 @@ func (c *TieredCache[K, V]) getSet(ctx context.Context, key K, loader func(conte
148148
return zero, fmt.Errorf("persistence load: %w", err)
149149
}
150150
if found {
151-
c.memory.set(key, val, timeToNano(expiry))
151+
c.memory.set(key, val, timeToSec(expiry))
152152
return val, nil
153153
}
154154

@@ -178,7 +178,7 @@ func (c *TieredCache[K, V]) getSet(ctx context.Context, key K, loader func(conte
178178
return zero, call.err
179179
}
180180
if found {
181-
c.memory.set(key, val, timeToNano(expiry))
181+
c.memory.set(key, val, timeToSec(expiry))
182182
call.val = val
183183
c.flights.Delete(key)
184184
call.wg.Done()
@@ -194,7 +194,7 @@ func (c *TieredCache[K, V]) getSet(ctx context.Context, key K, loader func(conte
194194
}
195195

196196
exp := c.expiry(ttl)
197-
c.memory.set(key, val, timeToNano(exp))
197+
c.memory.set(key, val, timeToSec(exp))
198198

199199
if err := c.Store.Set(ctx, key, val, exp); err != nil {
200200
slog.Warn("GetSet persistence failed", "key", key, "error", err)

persistent_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,8 @@ func TestTieredCache_Set_VariadicTTL(t *testing.T) {
829829
t.Error("default-ttl should be found")
830830
}
831831

832-
// Set with explicit short TTL
833-
if err := cache.SetTTL(ctx, "short-ttl", 2, 50*time.Millisecond); err != nil {
832+
// Set with explicit short TTL (1 second granularity)
833+
if err := cache.SetTTL(ctx, "short-ttl", 2, 1*time.Second); err != nil {
834834
t.Fatalf("Set: %v", err)
835835
}
836836
_, found, err = cache.Get(ctx, "short-ttl")
@@ -842,7 +842,7 @@ func TestTieredCache_Set_VariadicTTL(t *testing.T) {
842842
}
843843

844844
// Wait for short TTL to expire
845-
time.Sleep(100 * time.Millisecond)
845+
time.Sleep(2 * time.Second)
846846

847847
// short-ttl should be expired in memory, default-ttl should still exist
848848
_, found, err = cache.Get(ctx, "short-ttl")
@@ -1057,8 +1057,8 @@ func TestNew_InvalidSize(t *testing.T) {
10571057
}
10581058

10591059
func TestNew_TTL_Behavior(t *testing.T) {
1060-
// Test that TTL option is correctly applied as default
1061-
defaultTTL := 100 * time.Millisecond
1060+
// Test that TTL option is correctly applied as default (1 second granularity)
1061+
defaultTTL := 1 * time.Second
10621062
cache := New[string, int](TTL(defaultTTL))
10631063

10641064
// Set without explicit TTL -> uses default
@@ -1068,7 +1068,7 @@ func TestNew_TTL_Behavior(t *testing.T) {
10681068
cache.SetTTL("longer", 2, 1*time.Hour)
10691069

10701070
// Wait for default to expire
1071-
time.Sleep(defaultTTL + 10*time.Millisecond)
1071+
time.Sleep(2 * time.Second)
10721072

10731073
if _, ok := cache.Get("default"); ok {
10741074
t.Error("Item with default TTL should have expired")
@@ -1080,7 +1080,7 @@ func TestNew_TTL_Behavior(t *testing.T) {
10801080

10811081
func TestNewTiered_WithTTL_Behavior(t *testing.T) {
10821082
store := newMockStore[string, int]()
1083-
defaultTTL := 100 * time.Millisecond
1083+
defaultTTL := 1 * time.Second
10841084
cache, err := NewTiered[string, int](store, TTL(defaultTTL))
10851085
if err != nil {
10861086
t.Fatalf("NewTiered failed: %v", err)
@@ -1104,7 +1104,7 @@ func TestNewTiered_WithTTL_Behavior(t *testing.T) {
11041104
}
11051105

11061106
// Wait for default to expire
1107-
time.Sleep(defaultTTL + 10*time.Millisecond)
1107+
time.Sleep(2 * time.Second)
11081108

11091109
// Check memory first (using Get)
11101110
if _, ok := cache.memory.get("default"); ok {
@@ -1300,8 +1300,8 @@ func TestTieredCache_GetSet_WithTTL(t *testing.T) {
13001300
return loaderCalls * 10, nil
13011301
}
13021302

1303-
// First call with short TTL
1304-
val, err := cache.GetSetTTL(ctx, "key1", loader, 50*time.Millisecond)
1303+
// First call with short TTL (1 second granularity)
1304+
val, err := cache.GetSetTTL(ctx, "key1", loader, 1*time.Second)
13051305
if err != nil {
13061306
t.Fatalf("GetSet error: %v", err)
13071307
}
@@ -1310,10 +1310,10 @@ func TestTieredCache_GetSet_WithTTL(t *testing.T) {
13101310
}
13111311

13121312
// Wait for TTL to expire
1313-
time.Sleep(100 * time.Millisecond)
1313+
time.Sleep(2 * time.Second)
13141314

13151315
// Second call - should call loader again (cache expired)
1316-
val, err = cache.GetSetTTL(ctx, "key1", loader, 50*time.Millisecond)
1316+
val, err = cache.GetSetTTL(ctx, "key1", loader, 1*time.Second)
13171317
if err != nil {
13181318
t.Fatalf("GetSet error: %v", err)
13191319
}

0 commit comments

Comments
 (0)