mirror of
https://github.com/kopia/kopia.git
synced 2026-03-13 11:46:55 -04:00
108 lines
2.1 KiB
Go
108 lines
2.1 KiB
Go
package storagetesting
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/kopia/kopia/storage"
|
|
)
|
|
|
|
type mapStorage struct {
|
|
data map[string][]byte
|
|
keyTime map[string]time.Time
|
|
timeNow func() time.Time
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
func (s *mapStorage) GetBlock(ctx context.Context, id string, offset, length int64) ([]byte, error) {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
|
|
data, ok := s.data[id]
|
|
if ok {
|
|
data = append([]byte(nil), data...)
|
|
if length < 0 {
|
|
return data, nil
|
|
}
|
|
|
|
data = data[offset:]
|
|
if int(length) > len(data) {
|
|
return data, nil
|
|
}
|
|
return data[0:length], nil
|
|
}
|
|
|
|
return nil, storage.ErrBlockNotFound
|
|
}
|
|
|
|
func (s *mapStorage) PutBlock(ctx context.Context, id string, data []byte) error {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
|
|
if _, ok := s.data[id]; ok {
|
|
return nil
|
|
}
|
|
|
|
s.keyTime[id] = s.timeNow()
|
|
s.data[id] = append([]byte{}, data...)
|
|
return nil
|
|
}
|
|
|
|
func (s *mapStorage) DeleteBlock(ctx context.Context, id string) error {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
|
|
delete(s.data, id)
|
|
return nil
|
|
}
|
|
|
|
func (s *mapStorage) ListBlocks(ctx context.Context, prefix string, callback func(storage.BlockMetadata) error) error {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
|
|
keys := []string{}
|
|
for k := range s.data {
|
|
if strings.HasPrefix(k, prefix) {
|
|
keys = append(keys, k)
|
|
}
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
v := s.data[k]
|
|
if err := callback(storage.BlockMetadata{
|
|
BlockID: k,
|
|
Length: int64(len(v)),
|
|
Timestamp: s.keyTime[k],
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *mapStorage) Close(ctx context.Context) error {
|
|
return nil
|
|
}
|
|
|
|
func (s *mapStorage) ConnectionInfo() storage.ConnectionInfo {
|
|
// unsupported
|
|
return storage.ConnectionInfo{}
|
|
}
|
|
|
|
// NewMapStorage returns an implementation of Storage backed by the contents of given map.
|
|
// Used primarily for testing.
|
|
func NewMapStorage(data map[string][]byte, keyTime map[string]time.Time, timeNow func() time.Time) storage.Storage {
|
|
if keyTime == nil {
|
|
keyTime = make(map[string]time.Time)
|
|
}
|
|
if timeNow == nil {
|
|
timeNow = time.Now
|
|
}
|
|
return &mapStorage{data: data, keyTime: keyTime, timeNow: timeNow}
|
|
}
|