@@ -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 {
337337func (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
351355func (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
424428func (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
558561func (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.
582585func (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 ]
0 commit comments