90 lines
2.0 KiB
Go
90 lines
2.0 KiB
Go
package blossom
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"iter"
|
|
"slices"
|
|
|
|
"fiatjaf.com/nostr"
|
|
"github.com/puzpuzpuz/xsync/v3"
|
|
)
|
|
|
|
type ownedBlob struct {
|
|
blob BlobDescriptor
|
|
owners []nostr.PubKey
|
|
}
|
|
|
|
type MemoryBlobIndex struct {
|
|
m *xsync.MapOf[string, ownedBlob]
|
|
}
|
|
|
|
func NewMemoryBlobIndex() MemoryBlobIndex {
|
|
return MemoryBlobIndex{
|
|
m: xsync.NewMapOf[string, ownedBlob](),
|
|
}
|
|
}
|
|
|
|
func (x MemoryBlobIndex) Keep(ctx context.Context, blob BlobDescriptor, pubkey nostr.PubKey) error {
|
|
x.m.Compute(blob.SHA256, func(oldValue ownedBlob, loaded bool) (newValue ownedBlob, delete bool) {
|
|
if loaded {
|
|
newValue = oldValue
|
|
if !slices.Contains(newValue.owners, pubkey) {
|
|
newValue.owners = append(newValue.owners, pubkey)
|
|
}
|
|
} else {
|
|
newValue = ownedBlob{
|
|
blob: blob,
|
|
owners: []nostr.PubKey{pubkey},
|
|
}
|
|
}
|
|
|
|
return newValue, false
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func (x MemoryBlobIndex) List(ctx context.Context, pubkey nostr.PubKey) iter.Seq[BlobDescriptor] {
|
|
return func(yield func(BlobDescriptor) bool) {
|
|
x.m.Range(func(key string, value ownedBlob) bool {
|
|
if value.blob.Owner == value.owners[0] {
|
|
if !yield(value.blob) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
}
|
|
|
|
func (x MemoryBlobIndex) Get(ctx context.Context, sha256 string) (*BlobDescriptor, error) {
|
|
if val, ok := x.m.Load(sha256); ok {
|
|
val.blob.Owner = val.owners[0]
|
|
return &val.blob, nil
|
|
}
|
|
return nil, errors.New("not found")
|
|
}
|
|
|
|
func (x MemoryBlobIndex) Delete(ctx context.Context, sha256 string, pubkey nostr.PubKey) error {
|
|
x.m.Compute(sha256, func(oldValue ownedBlob, loaded bool) (newValue ownedBlob, delete bool) {
|
|
if loaded {
|
|
if idx := slices.Index(oldValue.owners, pubkey); idx != -1 {
|
|
if len(oldValue.owners) == 1 {
|
|
// this is the only owner, remove the blob
|
|
return oldValue, true
|
|
} else {
|
|
// remove this owner
|
|
oldValue.owners[idx] = oldValue.owners[len(oldValue.owners)-1]
|
|
oldValue.owners = oldValue.owners[0 : len(oldValue.owners)-1]
|
|
return oldValue, false
|
|
}
|
|
}
|
|
}
|
|
|
|
return oldValue, true
|
|
})
|
|
|
|
return nil
|
|
}
|