Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -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 | |
| 5 | package memstore |
| 6 | |
| 7 | import ( |
| 8 | "sort" |
| 9 | "sync" |
| 10 | |
| 11 | "v.io/syncbase/x/ref/services/syncbase/store" |
Sergey Rogulenko | a53e60f | 2015-05-22 11:05:01 -0700 | [diff] [blame] | 12 | "v.io/v23/verror" |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 13 | ) |
| 14 | |
| 15 | type stream struct { |
| 16 | mu sync.Mutex |
Sergey Rogulenko | 95baa66 | 2015-05-22 15:07:06 -0700 | [diff] [blame] | 17 | node *store.ResourceNode |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 18 | sn *snapshot |
| 19 | keys []string |
| 20 | currIndex int |
| 21 | currKey *string |
| 22 | err error |
| 23 | } |
| 24 | |
| 25 | var _ store.Stream = (*stream)(nil) |
| 26 | |
Sergey Rogulenko | 95baa66 | 2015-05-22 15:07:06 -0700 | [diff] [blame] | 27 | func newStream(sn *snapshot, parent *store.ResourceNode, start, limit []byte) *stream { |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 28 | keys := []string{} |
| 29 | for k := range sn.data { |
Adam Sadovsky | f437f33 | 2015-05-19 23:03:22 -0700 | [diff] [blame] | 30 | if k >= string(start) && (len(limit) == 0 || k < string(limit)) { |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 31 | keys = append(keys, k) |
| 32 | } |
| 33 | } |
| 34 | sort.Strings(keys) |
Sergey Rogulenko | 95baa66 | 2015-05-22 15:07:06 -0700 | [diff] [blame] | 35 | s := &stream{ |
| 36 | node: store.NewResourceNode(), |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 37 | sn: sn, |
| 38 | keys: keys, |
| 39 | currIndex: -1, |
| 40 | } |
Sergey Rogulenko | 95baa66 | 2015-05-22 15:07:06 -0700 | [diff] [blame] | 41 | parent.AddChild(s.node, func() { |
| 42 | s.Cancel() |
| 43 | }) |
| 44 | return s |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | // Advance implements the store.Stream interface. |
| 48 | func (s *stream) Advance() bool { |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 49 | s.mu.Lock() |
| 50 | defer s.mu.Unlock() |
| 51 | if s.err != nil { |
| 52 | s.currKey = nil |
| 53 | } else { |
| 54 | s.currIndex++ |
| 55 | if s.currIndex < len(s.keys) { |
| 56 | s.currKey = &s.keys[s.currIndex] |
| 57 | } else { |
| 58 | s.currKey = nil |
| 59 | } |
| 60 | } |
| 61 | return s.currKey != nil |
| 62 | } |
| 63 | |
| 64 | // Key implements the store.Stream interface. |
| 65 | func (s *stream) Key(keybuf []byte) []byte { |
| 66 | s.mu.Lock() |
| 67 | defer s.mu.Unlock() |
| 68 | if s.currKey == nil { |
| 69 | panic("nothing staged") |
| 70 | } |
| 71 | return store.CopyBytes(keybuf, []byte(*s.currKey)) |
| 72 | } |
| 73 | |
| 74 | // Value implements the store.Stream interface. |
| 75 | func (s *stream) Value(valbuf []byte) []byte { |
| 76 | s.mu.Lock() |
| 77 | defer s.mu.Unlock() |
| 78 | if s.currKey == nil { |
| 79 | panic("nothing staged") |
| 80 | } |
| 81 | return store.CopyBytes(valbuf, s.sn.data[*s.currKey]) |
| 82 | } |
| 83 | |
| 84 | // Err implements the store.Stream interface. |
| 85 | func (s *stream) Err() error { |
| 86 | s.mu.Lock() |
| 87 | defer s.mu.Unlock() |
Adam Sadovsky | a3fc33c | 2015-06-02 18:44:46 -0700 | [diff] [blame^] | 88 | return convertError(s.err) |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | // Cancel implements the store.Stream interface. |
| 92 | func (s *stream) Cancel() { |
| 93 | s.mu.Lock() |
| 94 | defer s.mu.Unlock() |
Sergey Rogulenko | a53e60f | 2015-05-22 11:05:01 -0700 | [diff] [blame] | 95 | if s.err != nil { |
| 96 | return |
| 97 | } |
Sergey Rogulenko | 95baa66 | 2015-05-22 15:07:06 -0700 | [diff] [blame] | 98 | s.node.Close() |
Adam Sadovsky | 8db7443 | 2015-05-29 17:37:32 -0700 | [diff] [blame] | 99 | s.err = verror.New(verror.ErrCanceled, nil, store.ErrMsgCanceledStream) |
Adam Sadovsky | c18c8ca | 2015-05-08 18:05:46 -0700 | [diff] [blame] | 100 | } |