Skip to content

Commit 2847c4b

Browse files
committed
libnetwork/networkdb: switch to go-immutable-radix v2
Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 50c3d19 commit 2847c4b

3 files changed

Lines changed: 42 additions & 45 deletions

File tree

libnetwork/networkdb/cluster.go

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -396,18 +396,17 @@ func (nDB *NetworkDB) reapTableEntries() {
396396
// The lock is taken at the beginning of the cycle and the deletion is inline
397397
for _, nid := range nodeNetworks {
398398
nDB.Lock()
399-
nDB.indexes[byNetwork].Root().WalkPrefix([]byte("/"+nid), func(path []byte, v interface{}) bool {
399+
nDB.indexes[byNetwork].Root().WalkPrefix([]byte("/"+nid), func(path []byte, v *entry) bool {
400400
// timeCompensation compensate in case the lock took some time to be released
401401
timeCompensation := time.Since(cycleStart)
402-
entry, ok := v.(*entry)
403-
if !ok || !entry.deleting {
402+
if !v.deleting {
404403
return false
405404
}
406405

407406
// In this check we are adding an extra 1 second to guarantee that when the number is truncated to int32 to fit the packet
408407
// for the tableEvent the number is always strictly > 1 and never 0
409-
if entry.reapTime > reapPeriod+timeCompensation+time.Second {
410-
entry.reapTime -= reapPeriod + timeCompensation
408+
if v.reapTime > reapPeriod+timeCompensation+time.Second {
409+
v.reapTime -= reapPeriod + timeCompensation
411410
return false
412411
}
413412

@@ -629,28 +628,23 @@ func (nDB *NetworkDB) bulkSyncNode(networks []string, node string, unsolicited b
629628
}
630629

631630
for _, nid := range networks {
632-
nDB.indexes[byNetwork].Root().WalkPrefix([]byte("/"+nid), func(path []byte, v interface{}) bool {
633-
entry, ok := v.(*entry)
634-
if !ok {
635-
return false
636-
}
637-
631+
nDB.indexes[byNetwork].Root().WalkPrefix([]byte("/"+nid), func(path []byte, v *entry) bool {
638632
eType := TableEventTypeCreate
639-
if entry.deleting {
633+
if v.deleting {
640634
eType = TableEventTypeDelete
641635
}
642636

643637
params := strings.Split(string(path[1:]), "/")
644638
tEvent := TableEvent{
645639
Type: eType,
646-
LTime: entry.ltime,
647-
NodeName: entry.node,
640+
LTime: v.ltime,
641+
NodeName: v.node,
648642
NetworkID: nid,
649643
TableName: params[1],
650644
Key: params[2],
651-
Value: entry.value,
645+
Value: v.value,
652646
// The duration in second is a float that below would be truncated
653-
ResidualReapTime: int32(entry.reapTime.Seconds()),
647+
ResidualReapTime: int32(v.reapTime.Seconds()),
654648
}
655649

656650
msg, err := encodeMessage(MessageTypeTableEvent, &tEvent)

libnetwork/networkdb/networkdb.go

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"github.com/docker/docker/libnetwork/types"
1616
"github.com/docker/docker/pkg/stringid"
1717
"github.com/docker/go-events"
18-
iradix "github.com/hashicorp/go-immutable-radix"
18+
iradix "github.com/hashicorp/go-immutable-radix/v2"
1919
"github.com/hashicorp/memberlist"
2020
"github.com/hashicorp/serf/serf"
2121
)
@@ -44,7 +44,7 @@ type NetworkDB struct {
4444

4545
// All the tree index (byTable, byNetwork) that we maintain
4646
// the db.
47-
indexes map[int]*iradix.Tree
47+
indexes map[int]*iradix.Tree[*entry]
4848

4949
// Memberlist we use to drive the cluster.
5050
memberlist *memberlist.Memberlist
@@ -256,7 +256,7 @@ func New(c *Config) (*NetworkDB, error) {
256256

257257
nDB := &NetworkDB{
258258
config: c,
259-
indexes: make(map[int]*iradix.Tree),
259+
indexes: make(map[int]*iradix.Tree[*entry]),
260260
networks: make(map[string]map[string]*network),
261261
nodes: make(map[string]*node),
262262
failedNodes: make(map[string]*node),
@@ -266,8 +266,8 @@ func New(c *Config) (*NetworkDB, error) {
266266
broadcaster: events.NewBroadcaster(),
267267
}
268268

269-
nDB.indexes[byTable] = iradix.New()
270-
nDB.indexes[byNetwork] = iradix.New()
269+
nDB.indexes[byTable] = iradix.New[*entry]()
270+
nDB.indexes[byNetwork] = iradix.New[*entry]()
271271

272272
log.G(context.TODO()).Infof("New memberlist node - Node:%v will use memberlist nodeID:%v with config:%+v", c.Hostname, c.NodeID, c)
273273
if err := nDB.clusterInit(); err != nil {
@@ -337,15 +337,19 @@ func (nDB *NetworkDB) Peers(nid string) []PeerInfo {
337337
func (nDB *NetworkDB) GetEntry(tname, nid, key string) ([]byte, error) {
338338
nDB.RLock()
339339
defer nDB.RUnlock()
340-
entry, err := nDB.getEntry(tname, nid, key)
340+
v, err := nDB.getEntry(tname, nid, key)
341341
if err != nil {
342342
return nil, err
343343
}
344-
if entry != nil && entry.deleting {
344+
if v != nil && v.deleting {
345345
return nil, types.NotFoundErrorf("entry in table %s network id %s and key %s deleted and pending garbage collection", tname, nid, key)
346346
}
347347

348-
return entry.value, nil
348+
// note: this panics if a nil entry was stored in the table; after
349+
// discussion, we decided to not gracefully handle this situation as
350+
// this would be an unexpected situation;
351+
// see https://github.com/moby/moby/pull/48157#discussion_r1674428635
352+
return v.value, nil
349353
}
350354

351355
func (nDB *NetworkDB) getEntry(tname, nid, key string) (*entry, error) {
@@ -354,7 +358,7 @@ func (nDB *NetworkDB) getEntry(tname, nid, key string) (*entry, error) {
354358
return nil, types.NotFoundErrorf("could not get entry in table %s with network id %s and key %s", tname, nid, key)
355359
}
356360

357-
return e.(*entry), nil
361+
return e, nil
358362
}
359363

360364
// CreateEntry creates a table entry in NetworkDB for given (network,
@@ -423,14 +427,13 @@ type TableElem struct {
423427
// returns a map of keys and values
424428
func (nDB *NetworkDB) GetTableByNetwork(tname, nid string) map[string]*TableElem {
425429
entries := make(map[string]*TableElem)
426-
nDB.indexes[byTable].Root().WalkPrefix([]byte(fmt.Sprintf("/%s/%s", tname, nid)), func(k []byte, v interface{}) bool {
427-
entry := v.(*entry)
428-
if entry.deleting {
430+
nDB.indexes[byTable].Root().WalkPrefix([]byte(fmt.Sprintf("/%s/%s", tname, nid)), func(k []byte, v *entry) bool {
431+
if v.deleting {
429432
return false
430433
}
431434
key := string(k)
432435
key = key[strings.LastIndex(key, "/")+1:]
433-
entries[key] = &TableElem{Value: entry.value, owner: entry.node}
436+
entries[key] = &TableElem{Value: v.value, owner: v.node}
434437
return false
435438
})
436439
return entries
@@ -502,8 +505,8 @@ func (nDB *NetworkDB) deleteNodeNetworkEntries(nid, node string) {
502505
isNodeLocal := node == nDB.config.NodeID
503506

504507
nDB.indexes[byNetwork].Root().WalkPrefix([]byte("/"+nid),
505-
func(path []byte, v interface{}) bool {
506-
oldEntry := v.(*entry)
508+
func(path []byte, v *entry) bool {
509+
oldEntry := v
507510
params := strings.Split(string(path[1:]), "/")
508511
nid := params[0]
509512
tname := params[1]
@@ -521,7 +524,7 @@ func (nDB *NetworkDB) deleteNodeNetworkEntries(nid, node string) {
521524
return false
522525
}
523526

524-
entry := &entry{
527+
newEntry := &entry{
525528
ltime: oldEntry.ltime,
526529
node: oldEntry.node,
527530
value: oldEntry.value,
@@ -536,11 +539,11 @@ func (nDB *NetworkDB) deleteNodeNetworkEntries(nid, node string) {
536539
if isNodeLocal {
537540
// TODO fcrisciani: this can be removed if there is no way to leave the network
538541
// without doing a delete of all the objects
539-
entry.ltime++
542+
newEntry.ltime++
540543
}
541544

542545
if !oldEntry.deleting {
543-
nDB.createOrUpdateEntry(nid, tname, key, entry)
546+
nDB.createOrUpdateEntry(nid, tname, key, newEntry)
544547
}
545548
} else {
546549
// the local node is leaving the network, all the entries of remote nodes can be safely removed
@@ -549,15 +552,15 @@ func (nDB *NetworkDB) deleteNodeNetworkEntries(nid, node string) {
549552

550553
// Notify to the upper layer only entries not already marked for deletion
551554
if !oldEntry.deleting {
552-
nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, entry.value))
555+
nDB.broadcaster.Write(makeEvent(opDelete, tname, nid, key, newEntry.value))
553556
}
554557
return false
555558
})
556559
}
557560

558561
func (nDB *NetworkDB) deleteNodeTableEntries(node string) {
559-
nDB.indexes[byTable].Root().Walk(func(path []byte, v interface{}) bool {
560-
oldEntry := v.(*entry)
562+
nDB.indexes[byTable].Root().Walk(func(path []byte, v *entry) bool {
563+
oldEntry := v
561564
if oldEntry.node != node {
562565
return false
563566
}
@@ -581,8 +584,8 @@ func (nDB *NetworkDB) deleteNodeTableEntries(node string) {
581584
// value. The walk stops if the passed function returns a true.
582585
func (nDB *NetworkDB) WalkTable(tname string, fn func(string, string, []byte, bool) bool) error {
583586
nDB.RLock()
584-
values := make(map[string]interface{})
585-
nDB.indexes[byTable].Root().WalkPrefix([]byte("/"+tname), func(path []byte, v interface{}) bool {
587+
values := make(map[string]*entry)
588+
nDB.indexes[byTable].Root().WalkPrefix([]byte("/"+tname), func(path []byte, v *entry) bool {
586589
values[string(path)] = v
587590
return false
588591
})
@@ -592,7 +595,7 @@ func (nDB *NetworkDB) WalkTable(tname string, fn func(string, string, []byte, bo
592595
params := strings.Split(k[1:], "/")
593596
nid := params[1]
594597
key := params[2]
595-
if fn(nid, key, v.(*entry).value, v.(*entry).deleting) {
598+
if fn(nid, key, v.value, v.deleting) {
596599
return nil
597600
}
598601
}
@@ -754,9 +757,9 @@ func (nDB *NetworkDB) updateLocalNetworkTime() {
754757

755758
// createOrUpdateEntry this function handles the creation or update of entries into the local
756759
// tree store. It is also used to keep in sync the entries number of the network (all tables are aggregated)
757-
func (nDB *NetworkDB) createOrUpdateEntry(nid, tname, key string, entry interface{}) (okTable bool, okNetwork bool) {
758-
nDB.indexes[byTable], _, okTable = nDB.indexes[byTable].Insert([]byte(fmt.Sprintf("/%s/%s/%s", tname, nid, key)), entry)
759-
nDB.indexes[byNetwork], _, okNetwork = nDB.indexes[byNetwork].Insert([]byte(fmt.Sprintf("/%s/%s/%s", nid, tname, key)), entry)
760+
func (nDB *NetworkDB) createOrUpdateEntry(nid, tname, key string, v *entry) (okTable bool, okNetwork bool) {
761+
nDB.indexes[byTable], _, okTable = nDB.indexes[byTable].Insert([]byte(fmt.Sprintf("/%s/%s/%s", tname, nid, key)), v)
762+
nDB.indexes[byNetwork], _, okNetwork = nDB.indexes[byNetwork].Insert([]byte(fmt.Sprintf("/%s/%s/%s", nid, tname, key)), v)
760763
if !okNetwork {
761764
// Add only if it is an insert not an update
762765
n, ok := nDB.networks[nDB.config.NodeID][nid]

vendor.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ require (
5252
github.com/google/go-cmp v0.6.0
5353
github.com/google/uuid v1.6.0
5454
github.com/gorilla/mux v1.8.1
55-
github.com/hashicorp/go-immutable-radix v1.3.1
55+
github.com/hashicorp/go-immutable-radix/v2 v2.1.0
5656
github.com/hashicorp/go-memdb v1.3.2
5757
github.com/hashicorp/go-multierror v1.1.1
5858
github.com/hashicorp/memberlist v0.4.0
@@ -171,7 +171,7 @@ require (
171171
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
172172
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
173173
github.com/hashicorp/errwrap v1.1.0 // indirect
174-
github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
174+
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
175175
github.com/hashicorp/go-msgpack v0.5.5 // indirect
176176
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
177177
github.com/hashicorp/golang-lru v0.5.4 // indirect

0 commit comments

Comments
 (0)