| | |
| | |
| | |
| |
|
| | package bcache |
| |
|
| | import ( |
| | "fmt" |
| | "runtime" |
| | "sync" |
| | "sync/atomic" |
| | "testing" |
| | ) |
| |
|
| | var registeredCache Cache[int, int32] |
| |
|
| | func init() { |
| | registeredCache.Register() |
| | } |
| |
|
| | var seq atomic.Uint32 |
| |
|
| | func next[T int | int32]() *T { |
| | x := new(T) |
| | *x = T(seq.Add(1)) |
| | return x |
| | } |
| |
|
| | func str[T int | int32](x *T) string { |
| | if x == nil { |
| | return "nil" |
| | } |
| | return fmt.Sprint(*x) |
| | } |
| |
|
| | func TestCache(t *testing.T) { |
| | |
| | |
| | c := new(Cache[int, int32]) |
| |
|
| | |
| | m := make(map[*int]*int32) |
| | for i := 0; i < 10000; i++ { |
| | k := next[int]() |
| | v := next[int32]() |
| | m[k] = v |
| | c.Put(k, v) |
| | } |
| |
|
| | |
| | n := 0 |
| | for k := range m { |
| | v := next[int32]() |
| | m[k] = v |
| | c.Put(k, v) |
| | if n++; n >= 2000 { |
| | break |
| | } |
| | } |
| |
|
| | |
| | for k, v := range m { |
| | if cv := c.Get(k); cv != v { |
| | t.Fatalf("c.Get(%v) = %v, want %v", str(k), str(cv), str(v)) |
| | } |
| | } |
| |
|
| | c.Clear() |
| | for k := range m { |
| | if cv := c.Get(k); cv != nil { |
| | t.Fatalf("after GC, c.Get(%v) = %v, want nil", str(k), str(cv)) |
| | } |
| | } |
| |
|
| | |
| | c = ®isteredCache |
| | for k, v := range m { |
| | c.Put(k, v) |
| | } |
| | runtime.GC() |
| | for k := range m { |
| | if cv := c.Get(k); cv != nil { |
| | t.Fatalf("after Clear, c.Get(%v) = %v, want nil", str(k), str(cv)) |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | c = new(Cache[int, int32]) |
| | var barrier, wg sync.WaitGroup |
| | const N = 100 |
| | barrier.Add(N) |
| | wg.Add(N) |
| | var lost int32 |
| | for i := 0; i < N; i++ { |
| | go func() { |
| | defer wg.Done() |
| |
|
| | m := make(map[*int]*int32) |
| | for j := 0; j < cacheSize; j++ { |
| | k, v := next[int](), next[int32]() |
| | m[k] = v |
| | c.Put(k, v) |
| | } |
| | barrier.Done() |
| | barrier.Wait() |
| |
|
| | for k, v := range m { |
| | if cv := c.Get(k); cv != v { |
| | t.Errorf("c.Get(%v) = %v, want %v", str(k), str(cv), str(v)) |
| | atomic.AddInt32(&lost, +1) |
| | } |
| | } |
| | }() |
| | } |
| | wg.Wait() |
| | if lost != 0 { |
| | t.Errorf("lost %d entries", lost) |
| | } |
| | } |
| |
|