diff --git a/router/default.go b/router/default.go index 8e1b1e94..2b525570 100644 --- a/router/default.go +++ b/router/default.go @@ -48,24 +48,24 @@ func (r *router) Options() Options { // Add adds new entry into routing table with given options. // It returns error if the entry could not be added. -func (r *router) Add(e Entry) error { +func (r *router) Add(e Route) error { return r.table.Add(e) } // Remove removes entry from the routing table. // It returns error if either the entry could not be removed or it does not exist. -func (r *router) Remove(e Entry) error { +func (r *router) Remove(e Route) error { return r.table.Remove(e) } // Update updates an entry in the router's routing table // It returns error if the entry was not found or it failed to be updated. -func (r *router) Update(opts ...EntryOption) error { +func (r *router) Update(opts ...RouteOption) error { return r.table.Update(opts...) } // Lookup makes a query lookup and returns all matching entries -func (r *router) Lookup(q Query) ([]*Entry, error) { +func (r *router) Lookup(q Query) ([]*Route, error) { return nil, ErrNotImplemented } diff --git a/router/entry.go b/router/entry.go index 1aee4d65..e37bbfd3 100644 --- a/router/entry.go +++ b/router/entry.go @@ -4,14 +4,14 @@ package router type AddPolicy int const ( - // Override overrides existing routing table entry + // Override overrides existing routing table route OverrideIfExists AddPolicy = iota - // ErrIfExists returns error if the entry already exists + // ErrIfExists returns error if the route already exists ErrIfExists ) -// EntryOptions defines micro network routing table entry options -type EntryOptions struct { +// RouteOptions defines micro network routing table route options +type RouteOptions struct { // DestAddr is destination address DestAddr string // Hop is the next route hop @@ -21,69 +21,69 @@ type EntryOptions struct { SrcAddr string // Metric is route cost metric Metric int - // Policy defines entry addition policy + // Policy defines route addition policy Policy AddPolicy } // DestAddr sets destination address -func DestAddr(a string) EntryOption { - return func(o *EntryOptions) { +func DestAddr(a string) RouteOption { + return func(o *RouteOptions) { o.DestAddr = a } } -// Hop allows to set the route entry options -func Hop(r Router) EntryOption { - return func(o *EntryOptions) { +// Hop allows to set the route route options +func Hop(r Router) RouteOption { + return func(o *RouteOptions) { o.Hop = r } } // SrcAddr sets source address -func SrcAddr(a string) EntryOption { - return func(o *EntryOptions) { +func SrcAddr(a string) RouteOption { + return func(o *RouteOptions) { o.SrcAddr = a } } -// Metric sets entry metric -func Metric(m int) EntryOption { - return func(o *EntryOptions) { +// Metric sets route metric +func Metric(m int) RouteOption { + return func(o *RouteOptions) { o.Metric = m } } -// AddEntryPolicy sets add entry policy -func AddEntryPolicy(p AddPolicy) EntryOption { - return func(o *EntryOptions) { +// RoutePolicy sets add route policy +func RoutePolicy(p AddPolicy) RouteOption { + return func(o *RouteOptions) { o.Policy = p } } -// Entry is routing table entry -type Entry interface { - // Options returns entry options - Options() EntryOptions +// Route is routing table route +type Route interface { + // Options returns route options + Options() RouteOptions } -type entry struct { - opts EntryOptions +type route struct { + opts RouteOptions } -// NewEntry returns new routing table entry -func NewEntry(opts ...EntryOption) Entry { - eopts := EntryOptions{} +// NewRoute returns new routing table route +func NewRoute(opts ...RouteOption) Route { + eopts := RouteOptions{} for _, o := range opts { o(&eopts) } - return &entry{ + return &route{ opts: eopts, } } -// Options returns entry options -func (e *entry) Options() EntryOptions { - return e.opts +// Options returns route options +func (r *route) Options() RouteOptions { + return r.opts } diff --git a/router/query.go b/router/query.go index 677e2575..68298740 100644 --- a/router/query.go +++ b/router/query.go @@ -13,7 +13,7 @@ const ( // QueryOptions allow to define routing table query options type QueryOptions struct { // Route allows to set route options - Route *EntryOptions + Route *RouteOptions // Service is micro service name Service string // Policy defines query lookup policy @@ -22,8 +22,8 @@ type QueryOptions struct { Count int } -// EntryOpts allows to set the route query options -func EntryOpts(r *EntryOptions) QueryOption { +// RouteOpts allows to set the route query options +func RouteOpts(r *RouteOptions) QueryOption { return func(o *QueryOptions) { o.Route = r } @@ -36,8 +36,8 @@ func Service(s string) QueryOption { } } -// QueryLookupPolicy allows to define query lookup policy -func QueryLookupPolicy(p LookupPolicy) QueryOption { +// QueryPolicy allows to define query lookup policy +func QueryPolicy(p LookupPolicy) QueryOption { return func(o *QueryOptions) { o.Policy = p } diff --git a/router/router.go b/router/router.go index ef3b8117..17b6324e 100644 --- a/router/router.go +++ b/router/router.go @@ -8,13 +8,13 @@ type Router interface { // Options returns Router options Options() Options // Add adds new entry into routing table - Add(Entry) error + Add(Route) error // Remove removes entry from the routing table - Remove(Entry) error + Remove(Route) error // Update updates entry in the routing table - Update(...EntryOption) error + Update(...RouteOption) error // Lookup queries the routing table and returns matching entries - Lookup(Query) ([]*Entry, error) + Lookup(Query) ([]*Route, error) // Table returns routing table Table() Table // Address returns the router bind adddress @@ -34,8 +34,8 @@ type RIB interface { // Option used by the router type Option func(*Options) -// EntryOption is used to define routing entry options -type EntryOption func(*EntryOptions) +// RouteOption is used to define routing table entry options +type RouteOption func(*RouteOptions) // QueryOption is used to define query options type QueryOption func(*QueryOptions) diff --git a/router/table.go b/router/table.go index 9039bb1e..b674797b 100644 --- a/router/table.go +++ b/router/table.go @@ -3,6 +3,7 @@ package router import ( "errors" "fmt" + "hash" "hash/fnv" "strings" "sync" @@ -22,13 +23,13 @@ var ( // Table is routing table type Table interface { // Add adds new route to the table - Add(Entry) error + Add(Route) error // Remove removes route from the table - Remove(Entry) error + Remove(Route) error // Update updates route in the table - Update(...EntryOption) error + Update(...RouteOption) error // Lookup looks up routes in the table - Lookup(Query) ([]Entry, error) + Lookup(Query) ([]Route, error) // Size returns the size of the table Size() int // String prints the routing table @@ -39,35 +40,37 @@ type Table interface { // It maps service name to routes type table struct { // m stores routing table map - m map[string]map[uint64]Entry + m map[uint64]Route + // h is a hasher hashes route entries + h hash.Hash64 sync.RWMutex } // NewTable creates new routing table and returns it func NewTable() Table { + h := fnv.New64() + h.Reset() + return &table{ - m: make(map[string]map[uint64]Entry), + m: make(map[uint64]Route), + h: h, } } // Add adds new routing entry -func (t *table) Add(e Entry) error { +func (t *table) Add(r Route) error { t.Lock() defer t.Unlock() - destAddr := e.Options().DestAddr - h := fnv.New64() - h.Write([]byte(e.Options().DestAddr + e.Options().Hop.Address())) + sum := t.hash(r) - if _, ok := t.m[destAddr]; !ok { - // create new map for DestAddr routes - t.m[destAddr] = make(map[uint64]Entry) - t.m[destAddr][h.Sum64()] = e + if _, ok := t.m[sum]; !ok { + t.m[sum] = r return nil } - if _, ok := t.m[destAddr][h.Sum64()]; ok && e.Options().Policy == OverrideIfExists { - t.m[destAddr][h.Sum64()] = e + if _, ok := t.m[sum]; ok && r.Options().Policy == OverrideIfExists { + t.m[sum] = r return nil } @@ -75,41 +78,36 @@ func (t *table) Add(e Entry) error { } // Remove removes entry from the routing table -func (t *table) Remove(e Entry) error { +func (t *table) Remove(r Route) error { t.Lock() defer t.Unlock() - destAddr := e.Options().DestAddr - h := fnv.New64() - h.Write([]byte(e.Options().DestAddr + e.Options().Hop.Address())) + sum := t.hash(r) - if _, ok := t.m[destAddr]; !ok { + if _, ok := t.m[sum]; !ok { return ErrRouteNotFound - } else { - delete(t.m[destAddr], h.Sum64()) - return nil } + delete(t.m, sum) + return nil } // Update updates routing entry -func (t *table) Update(opts ...EntryOption) error { +func (t *table) Update(opts ...RouteOption) error { t.Lock() defer t.Unlock() - e := NewEntry(opts...) + r := NewRoute(opts...) - destAddr := e.Options().DestAddr - h := fnv.New64() - h.Write([]byte(e.Options().DestAddr + e.Options().Hop.Address())) + sum := t.hash(r) - if _, ok := t.m[destAddr]; !ok { + if _, ok := t.m[sum]; !ok { return ErrRouteNotFound } - if _, ok := t.m[destAddr][h.Sum64()]; ok { - t.m[destAddr][h.Sum64()] = e + if _, ok := t.m[sum]; ok { + t.m[sum] = r return nil } @@ -117,7 +115,7 @@ func (t *table) Update(opts ...EntryOption) error { } // Lookup looks up entry in the routing table -func (t *table) Lookup(q Query) ([]Entry, error) { +func (t *table) Lookup(q Query) ([]Route, error) { return nil, ErrNotImplemented } @@ -141,25 +139,26 @@ func (t *table) String() string { table := tablewriter.NewWriter(sb) table.SetHeader([]string{"Dest", "Hop", "Src", "Metric"}) - var destAddr, prevAddr string - - for _, entries := range t.m { - for _, entry := range entries { - destAddr = entry.Options().DestAddr - // we want to avoid printing the same dest address - if prevAddr == destAddr { - destAddr = "" - } - strEntry := []string{ - destAddr, - entry.Options().Hop.Address(), - fmt.Sprintf("%d", entry.Options().SrcAddr), - fmt.Sprintf("%d", entry.Options().Metric), - } - table.Append(strEntry) - prevAddr = destAddr + for _, route := range t.m { + strRoute := []string{ + route.Options().DestAddr, + route.Options().Hop.Address(), + fmt.Sprintf("%d", route.Options().SrcAddr), + fmt.Sprintf("%d", route.Options().Metric), } + table.Append(strRoute) } return sb.String() } + +func (t *table) hash(r Route) uint64 { + srcAddr := r.Options().SrcAddr + destAddr := r.Options().DestAddr + routerAddr := r.Options().Hop.Address() + + t.h.Reset() + t.h.Write([]byte(srcAddr + destAddr + routerAddr)) + + return t.h.Sum64() +}