diff --git a/driver.go b/driver.go index f4dd4e9..9a38f30 100644 --- a/driver.go +++ b/driver.go @@ -4,6 +4,7 @@ import ( "context" "io/ioutil" "path" + "sync" "time" "go.etcd.io/bbolt" @@ -16,6 +17,60 @@ type Driver interface { Set(context.Context, string, string, []byte) error } +type RAM struct { + m map[string]map[string][]byte + lock *sync.RWMutex +} + +func NewRAM() RAM { + return RAM{ + m: make(map[string]map[string][]byte), + lock: &sync.RWMutex{}, + } +} + +func (ram RAM) Close() error { + return nil +} + +func (ram RAM) ForEach(ctx context.Context, ns string, cb func(string, []byte) error) error { + ram.lock.RLock() + defer ram.lock.RUnlock() + + for k, v := range ram.m[ns] { + if ctx.Err() != nil { + break + } + if err := cb(k, v); err != nil { + return err + } + } + return ctx.Err() +} + +func (ram RAM) Get(_ context.Context, ns, id string) ([]byte, error) { + ram.lock.RLock() + defer ram.lock.RUnlock() + + if _, ok := ram.m[ns]; !ok { + return nil, nil + } + + return ram.m[ns][id], nil +} + +func (ram RAM) Set(_ context.Context, ns, id string, v []byte) error { + ram.lock.Lock() + defer ram.lock.Unlock() + + if _, ok := ram.m[ns]; !ok { + ram.m[ns] = map[string][]byte{} + } + ram.m[ns][id] = v + + return nil +} + type BBolt struct { db *bbolt.DB } diff --git a/driver_test.go b/driver_test.go index cc1c62b..025b536 100644 --- a/driver_test.go +++ b/driver_test.go @@ -7,6 +7,10 @@ import ( "testing" ) +func TestDriverRAM(t *testing.T) { + testDriver(t, NewRAM()) +} + func TestDriverBBolt(t *testing.T) { testDriver(t, NewTestDBIn(t.TempDir())) }