mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-11-15 08:37:11 +01:00
82 lines
1.6 KiB
Go
82 lines
1.6 KiB
Go
package negentropy
|
|
|
|
import (
|
|
"errors"
|
|
"sort"
|
|
)
|
|
|
|
type Vector struct {
|
|
items []Item
|
|
}
|
|
|
|
func NewVector() *Vector {
|
|
return &Vector{
|
|
items: make([]Item, 0, 30),
|
|
}
|
|
}
|
|
|
|
func (v *Vector) Insert(createdAt uint64, id string) error {
|
|
// fmt.Fprintln(os.Stderr, "Insert", createdAt, id)
|
|
if len(id) != IDSize*2 {
|
|
return errors.New("bad id size for added item")
|
|
}
|
|
item := NewItem(createdAt, id)
|
|
|
|
v.items = append(v.items, *item)
|
|
return nil
|
|
}
|
|
|
|
func (v *Vector) Seal() error {
|
|
sort.Slice(v.items, func(i, j int) bool {
|
|
return v.items[i].LessThan(v.items[j])
|
|
})
|
|
|
|
for i := 1; i < len(v.items); i++ {
|
|
if v.items[i-1].Equals(v.items[i]) {
|
|
return errors.New("duplicate item inserted")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *Vector) Size() int {
|
|
return len(v.items)
|
|
}
|
|
|
|
func (v *Vector) GetItem(i uint64) (Item, error) {
|
|
if i >= uint64(len(v.items)) {
|
|
return Item{}, errors.New("index out of bounds")
|
|
}
|
|
return v.items[i], nil
|
|
}
|
|
|
|
func (v *Vector) Iterate(begin, end int, cb func(Item, int) bool) error {
|
|
for i := begin; i < end; i++ {
|
|
if !cb(v.items[i], i) {
|
|
break
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (v *Vector) FindLowerBound(begin, end int, bound Bound) (int, error) {
|
|
i := sort.Search(len(v.items[begin:end]), func(i int) bool {
|
|
return !v.items[begin+i].LessThan(bound.Item)
|
|
})
|
|
return begin + i, nil
|
|
}
|
|
|
|
func (v *Vector) Fingerprint(begin, end int) (Fingerprint, error) {
|
|
var out Accumulator
|
|
out.SetToZero()
|
|
|
|
if err := v.Iterate(begin, end, func(item Item, _ int) bool {
|
|
out.AddItem(item)
|
|
return true
|
|
}); err != nil {
|
|
return Fingerprint{}, err
|
|
}
|
|
|
|
return out.GetFingerprint(end - begin), nil
|
|
}
|