63 lines
1.4 KiB
Go
63 lines
1.4 KiB
Go
package check
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
// memKV is a bucket in memory with the revisions a real one gives.
|
|
type memKV struct {
|
|
mu sync.Mutex
|
|
vals map[string][]byte
|
|
revs map[string]uint64
|
|
next uint64
|
|
// creates counts the creates that succeeded, by key.
|
|
creates map[string]int
|
|
}
|
|
|
|
func newMemKV() *memKV {
|
|
return &memKV{vals: map[string][]byte{}, revs: map[string]uint64{}, creates: map[string]int{}}
|
|
}
|
|
|
|
func (m *memKV) Get(_ context.Context, key string) ([]byte, uint64, bool, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
v, ok := m.vals[key]
|
|
return v, m.revs[key], ok, nil
|
|
}
|
|
|
|
func (m *memKV) Create(_ context.Context, key string, value []byte) (uint64, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
if _, ok := m.vals[key]; ok {
|
|
return 0, ErrConflict
|
|
}
|
|
m.next++
|
|
m.vals[key], m.revs[key] = append([]byte(nil), value...), m.next
|
|
m.creates[key]++
|
|
return m.next, nil
|
|
}
|
|
|
|
func (m *memKV) Update(_ context.Context, key string, value []byte, revision uint64) (uint64, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
if _, ok := m.vals[key]; !ok || m.revs[key] != revision {
|
|
return 0, ErrConflict
|
|
}
|
|
m.next++
|
|
m.vals[key], m.revs[key] = append([]byte(nil), value...), m.next
|
|
return m.next, nil
|
|
}
|
|
|
|
func (m *memKV) Keys(context.Context) ([]string, error) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
keys := make([]string, 0, len(m.vals))
|
|
for k := range m.vals {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
return keys, nil
|
|
}
|