aboutsummaryrefslogtreecommitdiff
path: root/pkg/storage/memstore/memstore.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/storage/memstore/memstore.go')
-rw-r--r--pkg/storage/memstore/memstore.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/pkg/storage/memstore/memstore.go b/pkg/storage/memstore/memstore.go
new file mode 100644
index 0000000..f0c60f5
--- /dev/null
+++ b/pkg/storage/memstore/memstore.go
@@ -0,0 +1,77 @@
+// Package memstore implements in-memory storage for atlas.
+package memstore
+
+import (
+ "bytes"
+ "compress/gzip"
+ "crypto/sha256"
+ "io"
+ "sync"
+)
+
+// PdataStore stores pdata in-memory, with optional compression.
+type PdataStore struct {
+ gzip bool
+ pdata sync.Map
+}
+
+type pdataStoreEntry struct {
+ Hash [sha256.Size]byte
+ Data []byte
+}
+
+// NewPdataStore creates a new MemoryPdataStore.
+func NewPdataStore(compress bool) *PdataStore {
+ return &PdataStore{
+ gzip: compress,
+ }
+}
+
+func (m *PdataStore) GetPdataCached(uid uint64, sha [sha256.Size]byte) ([]byte, bool, error) {
+ v, ok := m.pdata.Load(uid)
+ if !ok {
+ return nil, ok, nil
+ }
+ e := v.(pdataStoreEntry)
+ if sha != [sha256.Size]byte{} && sha == e.Hash {
+ return nil, ok, nil
+ }
+ var b []byte
+ if m.gzip {
+ r, err := gzip.NewReader(bytes.NewReader(e.Data))
+ if err != nil {
+ return nil, ok, err
+ }
+ b, err = io.ReadAll(r)
+ if err != nil {
+ return nil, ok, err
+ }
+ } else {
+ b = make([]byte, len(e.Data))
+ copy(b, e.Data)
+ }
+ return b, ok, nil
+}
+
+func (m *PdataStore) SetPdata(uid uint64, buf []byte) error {
+ var b []byte
+ if m.gzip {
+ var f bytes.Buffer
+ w := gzip.NewWriter(&f)
+ if _, err := w.Write(buf); err != nil {
+ return err
+ }
+ if err := w.Close(); err != nil {
+ return err
+ }
+ b = f.Bytes()
+ } else {
+ b = make([]byte, len(buf))
+ copy(b, buf)
+ }
+ m.pdata.Store(uid, pdataStoreEntry{
+ Hash: sha256.Sum256(buf),
+ Data: b,
+ })
+ return nil
+}