blob: 15a298876b00635045e9afa62236028cd582166d [file] [log] [blame]
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package memstore provides a simple, in-memory implementation of store.Store.
6// Since it's a prototype implementation, it makes no attempt to be performant.
7package memstore
8
9import (
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070010 "fmt"
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070011 "sync"
12
13 "v.io/syncbase/x/ref/services/syncbase/store"
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070014 "v.io/syncbase/x/ref/services/syncbase/store/transactions"
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070015 "v.io/v23/verror"
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070016)
17
18type memstore struct {
19 mu sync.Mutex
Sergey Rogulenko95baa662015-05-22 15:07:06 -070020 node *store.ResourceNode
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070021 data map[string][]byte
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070022 err error
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070023}
24
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070025// New creates a new memstore.
26func New() store.Store {
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070027 return transactions.Wrap(&memstore{
Sergey Rogulenko95baa662015-05-22 15:07:06 -070028 data: map[string][]byte{},
29 node: store.NewResourceNode(),
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070030 })
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070031}
32
33// Close implements the store.Store interface.
34func (st *memstore) Close() error {
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070035 st.mu.Lock()
36 defer st.mu.Unlock()
37 if st.err != nil {
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070038 return store.ConvertError(st.err)
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070039 }
Sergey Rogulenko95baa662015-05-22 15:07:06 -070040 st.node.Close()
Adam Sadovsky8db74432015-05-29 17:37:32 -070041 st.err = verror.New(verror.ErrCanceled, nil, store.ErrMsgClosedStore)
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070042 return nil
43}
44
45// Get implements the store.StoreReader interface.
46func (st *memstore) Get(key, valbuf []byte) ([]byte, error) {
47 st.mu.Lock()
48 defer st.mu.Unlock()
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070049 if st.err != nil {
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070050 return valbuf, store.ConvertError(st.err)
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070051 }
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070052 value, ok := st.data[string(key)]
53 if !ok {
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070054 return valbuf, verror.New(store.ErrUnknownKey, nil, string(key))
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070055 }
56 return store.CopyBytes(valbuf, value), nil
57}
58
59// Scan implements the store.StoreReader interface.
Sergey Rogulenkodef3b302015-05-20 17:33:24 -070060func (st *memstore) Scan(start, limit []byte) store.Stream {
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070061 st.mu.Lock()
62 defer st.mu.Unlock()
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070063 if st.err != nil {
Jiri Simsad88e9ad2015-08-14 10:12:27 -070064 return &store.InvalidStream{Error: st.err}
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070065 }
Adam Sadovsky8db74432015-05-29 17:37:32 -070066 // TODO(sadovsky): Close snapshot once stream is closed or canceled.
Sergey Rogulenko95baa662015-05-22 15:07:06 -070067 return newSnapshot(st, st.node).Scan(start, limit)
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070068}
69
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070070// NewSnapshot implements the store.Store interface.
71func (st *memstore) NewSnapshot() store.Snapshot {
72 st.mu.Lock()
73 defer st.mu.Unlock()
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070074 if st.err != nil {
Sergey Rogulenko1068b1a2015-08-03 16:53:27 -070075 return &store.InvalidSnapshot{Error: st.err}
Sergey Rogulenkoa53e60f2015-05-22 11:05:01 -070076 }
Sergey Rogulenko95baa662015-05-22 15:07:06 -070077 return newSnapshot(st, st.node)
Adam Sadovskyc18c8ca2015-05-08 18:05:46 -070078}
Sergey Rogulenko054b4db2015-08-20 11:06:52 -070079
80// WriteBatch implements the transactions.BatchStore interface.
81func (st *memstore) WriteBatch(batch ...transactions.WriteOp) error {
82 st.mu.Lock()
83 defer st.mu.Unlock()
84 if st.err != nil {
85 return store.ConvertError(st.err)
86 }
87 for _, write := range batch {
88 switch write.T {
89 case transactions.PutOp:
90 st.data[string(write.Key)] = write.Value
91 case transactions.DeleteOp:
92 delete(st.data, string(write.Key))
93 default:
94 panic(fmt.Sprintf("unknown write operation type: %v", write.T))
95 }
96 }
97 return nil
98}