erigon-pulse/cl/freezer/mem_freezer.go
a 21625652f3
[caplin] record mode (#7651)
interface for recording things
2023-06-04 03:13:58 +02:00

73 lines
1.6 KiB
Go

package freezer
import (
"bytes"
"io"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
"sync"
)
type InMemory struct {
blob sync.Map
mu sync.RWMutex
}
func (f *InMemory) save(name string, b io.Reader) {
buf := new(bytes.Buffer)
buf.ReadFrom(b)
f.blob.Store(name, buf)
}
func (f *InMemory) get(name string) (*bytes.Buffer, error) {
val, ok := f.blob.Load(name)
if !ok {
return nil, fs.ErrNotExist
}
cast, ok := val.(*bytes.Buffer)
if !ok {
panic("incorrect item in sync map... this should never happen")
}
return cast, nil
}
func (f *InMemory) resolveFileName(namespace string, object string, id string, extra ...string) (string, error) {
j := filepath.Join("inmem", namespace, object, id)
if !strings.HasPrefix(j, "inmem") {
return "", os.ErrInvalid
}
return j, nil
}
func (f *InMemory) Get(namespace string, object string, id string, extra ...string) (data io.ReadCloser, sidecar []byte, err error) {
infoPath, err := f.resolveFileName(namespace, object, id)
if err != nil {
return nil, nil, err
}
fp, err := f.get(path.Join(infoPath, RootPathDataFile))
if err != nil {
return nil, nil, err
}
blob, err := f.get(path.Join(infoPath, RootPathSidecarFile))
if err == nil {
sidecar = blob.Bytes()
}
return io.NopCloser(fp), sidecar, nil
}
func (f *InMemory) Put(data io.Reader, sidecar []byte, namespace string, object string, id string, extra ...string) error {
infoPath, err := f.resolveFileName(namespace, object, id)
if err != nil {
return err
}
f.save(path.Join(infoPath, RootPathDataFile), data)
if sidecar != nil {
f.save(path.Join(infoPath, RootPathSidecarFile), bytes.NewBuffer(sidecar))
}
return nil
}