memory.go

v1.3.5
Doc Versions Source
1
package storage
2
3
import (
4
	"context"
5
	"fmt"
6
	"sync"
7
)
8
9
type memItem struct {
10
	data        []byte
11
	contentType string
12
}
13
14
// MemoryStorage is an in-memory storage backend for development and testing.
15
type MemoryStorage struct {
16
	mu       sync.RWMutex
17
	items    map[string]memItem
18
	size     int64
19
	maxBytes int64
20
}
21
22
// NewMemoryStorage creates an in-memory storage. maxBytes=0 means unlimited.
23
func NewMemoryStorage(maxBytes int64) *MemoryStorage {
24
	return &MemoryStorage{
25
		items:    make(map[string]memItem),
26
		maxBytes: maxBytes,
27
	}
28
}
29
30
func (m *MemoryStorage) Get(_ context.Context, key string) ([]byte, string, error) {
31
	m.mu.RLock()
32
	defer m.mu.RUnlock()
33
34
	item, ok := m.items[key]
35
	if !ok {
36
		return nil, "", ErrNotFound
37
	}
38
39
	return item.data, item.contentType, nil
40
}
41
42
func (m *MemoryStorage) Put(_ context.Context, key string, data []byte, contentType string) error {
43
	m.mu.Lock()
44
	defer m.mu.Unlock()
45
46
	newSize := int64(len(data))
47
48
	// Account for replacing an existing key.
49
	if old, ok := m.items[key]; ok {
50
		newSize -= int64(len(old.data))
51
	}
52
53
	if m.maxBytes > 0 && m.size+newSize > m.maxBytes {
54
		return fmt.Errorf("memory storage: would exceed max size (%d bytes)", m.maxBytes)
55
	}
56
57
	m.items[key] = memItem{data: data, contentType: contentType}
58
	m.size += newSize
59
	return nil
60
}
61
62
func (m *MemoryStorage) BucketStats(_ context.Context) (objects int64, sizeBytes int64, err error) {
63
	m.mu.RLock()
64
	defer m.mu.RUnlock()
65
66
	return int64(len(m.items)), m.size, nil
67
}
68

Source Files