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