-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refac(storage); simplify MemBackend (#523)
Split MemBackend into MapBackend and SyncBackend. Makes it easy to write test cases where a storage backend is pre-filled with some files.
- Loading branch information
Showing
8 changed files
with
143 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package storage | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"sort" | ||
"strings" | ||
) | ||
|
||
// MapBackend is an in-memory implementation of [Backend] backed by a map. | ||
// | ||
// This is NOT thread safe. Use [SyncBackend] to make it so. | ||
type MapBackend map[string][]byte | ||
|
||
var _ Backend = (MapBackend)(nil) | ||
|
||
// Get retrieves a value from the store. | ||
func (m MapBackend) Get(ctx context.Context, key string, dst any) error { | ||
v, ok := m[key] | ||
if !ok { | ||
return ErrNotExist | ||
} | ||
|
||
return json.Unmarshal(v, dst) | ||
} | ||
|
||
// Update applies a batch of changes to the store. | ||
// MapBackend ignores the message associated with the update. | ||
func (m MapBackend) Update(ctx context.Context, req UpdateRequest) error { | ||
for i, set := range req.Sets { | ||
v, err := json.Marshal(set.Value) | ||
if err != nil { | ||
return fmt.Errorf("marshal [%d]: %w", i, err) | ||
} | ||
m[set.Key] = v | ||
} | ||
|
||
for _, key := range req.Deletes { | ||
delete(m, key) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Clear clears all keys in the store. | ||
func (m MapBackend) Clear(context.Context, string) error { | ||
clear(m) | ||
return nil | ||
} | ||
|
||
// Keys returns a list of keys in the store. | ||
func (m MapBackend) Keys(ctx context.Context, dir string) ([]string, error) { | ||
if dir != "" && !strings.HasSuffix(dir, "/") { | ||
dir += "/" | ||
} | ||
|
||
keys := make([]string, 0, len(m)) | ||
for k := range m { | ||
if rest, ok := strings.CutPrefix(k, dir); ok { | ||
keys = append(keys, rest) | ||
} | ||
} | ||
sort.Strings(keys) | ||
return keys, nil | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package storage | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
) | ||
|
||
// SyncBackend adds mutex-based synchronization around all operations | ||
// of the given backend to make it thread-safe. | ||
// | ||
// Use it with [MapBackend]. | ||
func SyncBackend(b Backend) Backend { | ||
return &syncBackend{b: b} | ||
} | ||
|
||
type syncBackend struct { | ||
mu sync.RWMutex | ||
b Backend | ||
} | ||
|
||
var _ Backend = (*syncBackend)(nil) | ||
|
||
func (s *syncBackend) Clear(ctx context.Context, msg string) error { | ||
s.mu.Lock() | ||
defer s.mu.Unlock() | ||
|
||
return s.b.Clear(ctx, msg) | ||
} | ||
|
||
func (s *syncBackend) Get(ctx context.Context, key string, dst any) error { | ||
s.mu.RLock() | ||
defer s.mu.RUnlock() | ||
|
||
return s.b.Get(ctx, key, dst) | ||
} | ||
|
||
func (s *syncBackend) Keys(ctx context.Context, dir string) ([]string, error) { | ||
s.mu.RLock() | ||
defer s.mu.RUnlock() | ||
|
||
return s.b.Keys(ctx, dir) | ||
} | ||
|
||
func (s *syncBackend) Update(ctx context.Context, req UpdateRequest) error { | ||
s.mu.Lock() | ||
defer s.mu.Unlock() | ||
|
||
return s.b.Update(ctx, req) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.