blob: e246fc43b2feffeb67589cc17ea5d2171a47c021 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package memstore provides a simple, in-memory implementation of store.Store.
// Since it's a prototype implementation, it makes no attempt to be performant.
package memstore
import (
"sync"
"v.io/syncbase/x/ref/services/syncbase/store"
"v.io/v23/verror"
)
type memstore struct {
mu sync.Mutex
node *store.ResourceNode
data map[string][]byte
err error
// Most recent sequence number handed out.
lastSeq uint64
// Value of lastSeq at the time of the most recent commit.
lastCommitSeq uint64
}
var _ store.Store = (*memstore)(nil)
// New creates a new memstore.
func New() store.Store {
return &memstore{
data: map[string][]byte{},
node: store.NewResourceNode(),
}
}
// Close implements the store.Store interface.
func (st *memstore) Close() error {
st.mu.Lock()
defer st.mu.Unlock()
if st.err != nil {
return convertError(st.err)
}
st.node.Close()
st.err = verror.New(verror.ErrCanceled, nil, store.ErrMsgClosedStore)
return nil
}
// Get implements the store.StoreReader interface.
func (st *memstore) Get(key, valbuf []byte) ([]byte, error) {
st.mu.Lock()
defer st.mu.Unlock()
if st.err != nil {
return valbuf, convertError(st.err)
}
value, ok := st.data[string(key)]
if !ok {
return valbuf, verror.New(store.ErrUnknownKey, nil, string(key))
}
return store.CopyBytes(valbuf, value), nil
}
// Scan implements the store.StoreReader interface.
func (st *memstore) Scan(start, limit []byte) store.Stream {
st.mu.Lock()
defer st.mu.Unlock()
if st.err != nil {
return &store.InvalidStream{Error: st.err}
}
// TODO(sadovsky): Close snapshot once stream is closed or canceled.
return newSnapshot(st, st.node).Scan(start, limit)
}
// Put implements the store.StoreWriter interface.
func (st *memstore) Put(key, value []byte) error {
return store.RunInTransaction(st, func(tx store.Transaction) error {
return tx.Put(key, value)
})
}
// Delete implements the store.StoreWriter interface.
func (st *memstore) Delete(key []byte) error {
return store.RunInTransaction(st, func(tx store.Transaction) error {
return tx.Delete(key)
})
}
// NewTransaction implements the store.Store interface.
func (st *memstore) NewTransaction() store.Transaction {
st.mu.Lock()
defer st.mu.Unlock()
if st.err != nil {
return &store.InvalidTransaction{Error: st.err}
}
st.lastSeq++
return newTransaction(st, st.node, st.lastSeq)
}
// NewSnapshot implements the store.Store interface.
func (st *memstore) NewSnapshot() store.Snapshot {
st.mu.Lock()
defer st.mu.Unlock()
if st.err != nil {
return &store.InvalidSnapshot{Error: st.err}
}
return newSnapshot(st, st.node)
}