diff --git a/routingtable/table.go b/routingtable/table.go index fce8a4f1a26ac25ca5b124ec2b17810c698fe3ec..9ccb10161cde2c6f1424c0fbce851a0d1bda19dc 100644 --- a/routingtable/table.go +++ b/routingtable/table.go @@ -2,6 +2,7 @@ package routingtable import ( "sync" + "sync/atomic" "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/route" @@ -9,8 +10,9 @@ import ( // RoutingTable is a binary trie that stores prefixes and their paths type RoutingTable struct { - root *node - mu sync.RWMutex + routeCount int64 + root *node + mu sync.RWMutex } // NewRoutingTable creates a new routing table @@ -18,6 +20,11 @@ func NewRoutingTable() *RoutingTable { return &RoutingTable{} } +// GetRouteCount gets the amount of stored routes +func (rt *RoutingTable) GetRouteCount() int64 { + return atomic.LoadInt64(&rt.routeCount) +} + // AddPath adds a path to the routing table func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error { rt.mu.Lock() @@ -29,6 +36,7 @@ func (rt *RoutingTable) AddPath(pfx net.Prefix, p *route.Path) error { func (rt *RoutingTable) addPath(pfx net.Prefix, p *route.Path) error { if rt.root == nil { rt.root = newNode(pfx, p, pfx.Pfxlen(), false) + atomic.AddInt64(&rt.routeCount, 1) return nil } @@ -55,11 +63,13 @@ func (rt *RoutingTable) ReplacePath(pfx net.Prefix, p *route.Path) []*route.Path } // RemovePath removes a path from the trie -func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) bool { +func (rt *RoutingTable) RemovePath(pfx net.Prefix, p *route.Path) { rt.mu.Lock() defer rt.mu.Unlock() - return rt.removePath(pfx, p) + if rt.removePath(pfx, p) { + atomic.AddInt64(&rt.routeCount, -1) + } } func (rt *RoutingTable) removePath(pfx net.Prefix, p *route.Path) bool { diff --git a/routingtable/trie.go b/routingtable/trie.go index 730d10155284863b49c475185e34fc9db3ca0798..6fe5f4853cd4bd795c21926f6835ca5e711eeced 100644 --- a/routingtable/trie.go +++ b/routingtable/trie.go @@ -27,7 +27,7 @@ func newNode(pfx net.Prefix, path *route.Path, skip uint8, dummy bool) *node { return n } -func (n *node) removePath(pfx net.Prefix, p *route.Path) (success bool) { +func (n *node) removePath(pfx net.Prefix, p *route.Path) (final bool) { if n == nil { return false } @@ -37,14 +37,13 @@ func (n *node) removePath(pfx net.Prefix, p *route.Path) (success bool) { return } - nPaths := len(n.route.Paths()) nPathsAfterDel := n.route.RemovePath(p) if len(n.route.Paths()) == 0 { // FIXME: Can this node actually be removed from the trie entirely? n.dummy = true } - return nPathsAfterDel < nPaths + return nPathsAfterDel == 0 } b := getBitUint32(pfx.Addr(), n.route.Pfxlen()+1)