mirror of
https://github.com/kopia/kopia.git
synced 2026-02-07 21:23:52 -05:00
100 lines
1.7 KiB
Go
100 lines
1.7 KiB
Go
package blob
|
|
|
|
import (
|
|
"io"
|
|
"io/ioutil"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type mapStorage struct {
|
|
data map[string][]byte
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
func (s *mapStorage) Configuration() StorageConfiguration {
|
|
return StorageConfiguration{}
|
|
}
|
|
|
|
func (s *mapStorage) BlockExists(id BlockID) (bool, error) {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
_, ok := s.data[string(id)]
|
|
return ok, nil
|
|
}
|
|
|
|
func (s *mapStorage) GetBlock(id BlockID) ([]byte, error) {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
|
|
data, ok := s.data[string(id)]
|
|
if ok {
|
|
return data, nil
|
|
}
|
|
|
|
return nil, ErrBlockNotFound
|
|
}
|
|
|
|
func (s *mapStorage) PutBlock(id BlockID, data io.ReadCloser, options PutOptions) error {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
|
|
c, err := ioutil.ReadAll(data)
|
|
data.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.data[string(id)] = c
|
|
return nil
|
|
}
|
|
|
|
func (s *mapStorage) DeleteBlock(id BlockID) error {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
|
|
delete(s.data, string(id))
|
|
return nil
|
|
}
|
|
|
|
func (s *mapStorage) ListBlocks(prefix BlockID) chan (BlockMetadata) {
|
|
ch := make(chan (BlockMetadata))
|
|
fixedTime := time.Now()
|
|
go func() {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
|
|
keys := []string{}
|
|
for k := range s.data {
|
|
if strings.HasPrefix(k, string(prefix)) {
|
|
keys = append(keys, k)
|
|
}
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
v := s.data[k]
|
|
ch <- BlockMetadata{
|
|
BlockID: BlockID(k),
|
|
Length: uint64(len(v)),
|
|
TimeStamp: fixedTime,
|
|
}
|
|
}
|
|
close(ch)
|
|
}()
|
|
return ch
|
|
}
|
|
|
|
func (s *mapStorage) Flush() error {
|
|
return nil
|
|
}
|
|
|
|
// NewMapStorage returns an implementation of Storage backed by the contents of given map.
|
|
// Used primarily for testing.
|
|
func NewMapStorage(data map[string][]byte) Storage {
|
|
return &mapStorage{data: data}
|
|
}
|