Jiri Simsa | d7616c9 | 2015-03-24 23:44:30 -0700 | [diff] [blame] | 1 | // 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 | |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 5 | // Package memstore provides a simple, in-memory implementation of server.Store. |
| 6 | // Since it's a prototype implementation, it doesn't bother with entry-level |
| 7 | // locking. |
| 8 | package memstore |
| 9 | |
| 10 | import ( |
| 11 | "strconv" |
| 12 | "sync" |
| 13 | |
Todd Wang | 2d85b15 | 2015-04-06 15:38:22 -0700 | [diff] [blame] | 14 | "v.io/x/ref/services/groups/internal/server" |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 15 | ) |
| 16 | |
| 17 | type entry struct { |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 18 | v interface{} |
| 19 | version int |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 20 | } |
| 21 | |
| 22 | type memstore struct { |
| 23 | mu sync.Mutex |
| 24 | data map[string]*entry |
| 25 | } |
| 26 | |
| 27 | var _ server.Store = (*memstore)(nil) |
| 28 | |
| 29 | func New() server.Store { |
| 30 | return &memstore{data: map[string]*entry{}} |
| 31 | } |
| 32 | |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 33 | func (st *memstore) Get(k string) (v interface{}, version string, err error) { |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 34 | st.mu.Lock() |
| 35 | defer st.mu.Unlock() |
| 36 | e, ok := st.data[k] |
| 37 | if !ok { |
| 38 | return nil, "", &server.ErrUnknownKey{Key: k} |
| 39 | } |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 40 | return e.v, strconv.Itoa(e.version), nil |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | func (st *memstore) Insert(k string, v interface{}) error { |
| 44 | st.mu.Lock() |
| 45 | defer st.mu.Unlock() |
| 46 | if _, ok := st.data[k]; ok { |
| 47 | return &server.ErrKeyAlreadyExists{Key: k} |
| 48 | } |
| 49 | st.data[k] = &entry{v: v} |
| 50 | return nil |
| 51 | } |
| 52 | |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 53 | func (st *memstore) Update(k string, v interface{}, version string) error { |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 54 | st.mu.Lock() |
| 55 | defer st.mu.Unlock() |
| 56 | e, ok := st.data[k] |
| 57 | if !ok { |
| 58 | return &server.ErrUnknownKey{Key: k} |
| 59 | } |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 60 | if err := e.checkVersion(version); err != nil { |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 61 | return err |
| 62 | } |
| 63 | e.v = v |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 64 | e.version++ |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 65 | return nil |
| 66 | } |
| 67 | |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 68 | func (st *memstore) Delete(k string, version string) error { |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 69 | st.mu.Lock() |
| 70 | defer st.mu.Unlock() |
| 71 | e, ok := st.data[k] |
| 72 | if !ok { |
| 73 | return &server.ErrUnknownKey{Key: k} |
| 74 | } |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 75 | if err := e.checkVersion(version); err != nil { |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 76 | return err |
| 77 | } |
| 78 | delete(st.data, k) |
| 79 | return nil |
| 80 | } |
| 81 | |
Adam Sadovsky | b1f9e3c | 2015-04-08 11:03:49 -0700 | [diff] [blame] | 82 | func (e *entry) checkVersion(version string) error { |
| 83 | newVersion := strconv.Itoa(e.version) |
| 84 | if version != newVersion { |
| 85 | return &server.ErrBadVersion{} |
Adam Sadovsky | 491fb2c | 2015-02-11 11:25:14 -0800 | [diff] [blame] | 86 | } |
| 87 | return nil |
| 88 | } |