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 }