Skip to content

Commit

Permalink
sync: optimize svs map
Browse files Browse the repository at this point in the history
  • Loading branch information
pulsejet committed Feb 1, 2025
1 parent b014c1d commit f3bf02b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 18 deletions.
36 changes: 18 additions & 18 deletions std/sync/svs_map.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package sync

import (
"cmp"
"iter"
"sort"
"slices"

enc "github.com/named-data/ndnd/std/encoding"
"github.com/named-data/ndnd/std/log"
Expand All @@ -18,34 +19,33 @@ type SvMapVal[V any] struct {
Value V
}

func (*SvMapVal[V]) Cmp(a, b SvMapVal[V]) int {
return cmp.Compare(a.Boot, b.Boot)
}

// Create a new state vector map.
func NewSvMap[V any](size int) SvMap[V] {
return make(SvMap[V], size)
}

// Get seq entry for a bootstrap time.
func (m SvMap[V]) Get(hash string, boot uint64) (value V) {
// TODO: binary search - this is sorted
for _, entry := range m[hash] {
if entry.Boot == boot {
return entry.Value
}
entry := SvMapVal[V]{boot, value}
i, match := slices.BinarySearchFunc(m[hash], entry, entry.Cmp)
if match {
return m[hash][i].Value
}
return value
}

func (m SvMap[V]) Set(hash string, boot uint64, value V) {
for i, entry := range m[hash] {
if entry.Boot == boot {
m[hash][i].Value = value
return
}
entry := SvMapVal[V]{boot, value}
i, match := slices.BinarySearchFunc(m[hash], entry, entry.Cmp)
if match {
m[hash][i] = entry
return
}

m[hash] = append(m[hash], SvMapVal[V]{boot, value})
sort.Slice(m[hash], func(i, j int) bool {
return m[hash][i].Boot < m[hash][j].Boot
})
m[hash] = slices.Insert(m[hash], i, entry)
}

// Check if a SvMap is newer than another.
Expand Down Expand Up @@ -96,8 +96,8 @@ func (m SvMap[V]) Encode(seq func(V) uint64) *spec_svs.StateVector {
}

// Sort entries by in the NDN canonical order
sort.Slice(sv.Entries, func(i, j int) bool {
return sv.Entries[i].Name.Compare(sv.Entries[j].Name) < 0
slices.SortFunc(sv.Entries, func(a, b *spec_svs.StateVectorEntry) int {
return a.Name.Compare(b.Name)
})

return sv
Expand Down
22 changes: 22 additions & 0 deletions std/sync/svs_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ func TestSvMapBasic(t *testing.T) {
require.Equal(t, uint64(138), m.Get("/ndn/alice", 100))
}

func TestSvMapSet(t *testing.T) {
tu.SetT(t)

m := makeSvMap()

// Set new
m.Set("/ndn/alice", 120, 138)
require.Equal(t, uint64(138), m.Get("/ndn/alice", 120))

// Set existing
m.Set("/ndn/alice", 120, 190)
require.Equal(t, uint64(190), m.Get("/ndn/alice", 120))

// Set ordering
m.Set("/ndn/alice", 110, 138)
require.Equal(t, uint64(138), m.Get("/ndn/alice", 110))
boots := []uint64{100, 110, 120, 200}
for i, entry := range m["/ndn/alice"] {
require.Equal(t, boots[i], entry.Boot)
}
}

func TestSvMapNewer(t *testing.T) {
tu.SetT(t)

Expand Down

0 comments on commit f3bf02b

Please sign in to comment.