mirror of
https://github.com/alice-lg/alice-lg.git
synced 2024-05-11 05:55:03 +00:00
137 lines
2.9 KiB
Go
137 lines
2.9 KiB
Go
package memory
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/alice-lg/alice-lg/pkg/api"
|
|
"github.com/alice-lg/alice-lg/pkg/config"
|
|
"github.com/alice-lg/alice-lg/pkg/sources"
|
|
)
|
|
|
|
// A RoutesMap is a mapping between a source ID and a
|
|
// routes response.
|
|
type RoutesMap [string]*api.RoutesResponse
|
|
|
|
// RoutesBackend implements an in memory backend
|
|
// for the routes store.
|
|
type RoutesBackend struct {
|
|
routes map[string]api.LookupRoutes
|
|
sync.Mutex
|
|
}
|
|
|
|
// NewRoutesBackend creates a new instance
|
|
func NewRoutesBackend() *RoutesBackend {
|
|
return &RoutesBackend{
|
|
routes: make(RoutesMap),
|
|
}
|
|
}
|
|
|
|
// SetRoutes implements the RoutesStoreBackend interface
|
|
// function for setting all routes of a source identified
|
|
// by ID.
|
|
func (r *RoutesBackend) SetRoutes(
|
|
ctx context.Context,
|
|
sourceID string,
|
|
routes api.LookupRoutes,
|
|
) error {
|
|
r.Lock()
|
|
defer r.Unlock()
|
|
r.routesMap[sourceID] = routes
|
|
return nil
|
|
}
|
|
|
|
// CountRoutesAt returns the number of filtered and imported
|
|
// routes and implements the RoutesStoreBackend interface.
|
|
func (r *RoutesBackend) CountRoutesAt(
|
|
ctx context.Context,
|
|
sourceID string,
|
|
) (uint, uint, error) {
|
|
r.Lock()
|
|
defer r.Unlock()
|
|
routes, ok := r.routes[sourceID]
|
|
if !ok {
|
|
return 0, 0, sources.ErrSourceNotFound
|
|
}
|
|
|
|
imported := len(routes.Imported)
|
|
filtered := len(routes.Filtered)
|
|
|
|
return imported, filtered, nil
|
|
}
|
|
|
|
// GetNeighborsPrefixesAt retrieves the announced
|
|
// prefixes of a set of neighbor ids.
|
|
func (r *RoutesBackend) GetNeighborsPrefixesAt(
|
|
ctx context.Context,
|
|
sourceID string,
|
|
neighborIDs []string,
|
|
) (api.LookupRoutes, error) {
|
|
r.Lock()
|
|
defer r.Unlock()
|
|
|
|
result := api.LookupRoutes{}
|
|
routes, ok := s.routes[sourceID]
|
|
if !ok {
|
|
return nil, sources.ErrSourceNotFound
|
|
}
|
|
|
|
for _, route := range routes {
|
|
if isMemberOf(route.NeighborID, neighborIDs) {
|
|
result = append(result, route)
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// Routes filter
|
|
func filterRoutesByPrefix(
|
|
nStore *NeighborsStore,
|
|
source *config.SourceConfig,
|
|
routes api.Routes,
|
|
prefix string,
|
|
state string,
|
|
) api.LookupRoutes {
|
|
results := api.LookupRoutes{}
|
|
for _, route := range routes {
|
|
// Naiive filtering:
|
|
if strings.HasPrefix(strings.ToLower(route.Network), prefix) {
|
|
lookup := routeToLookupRoute(nStore, source, state, route)
|
|
results = append(results, lookup)
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
func filterRoutesByNeighborIDs(
|
|
nStore *NeighborsStore,
|
|
source *config.SourceConfig,
|
|
routes api.Routes,
|
|
neighborIDs []string,
|
|
state string,
|
|
) api.LookupRoutes {
|
|
|
|
results := api.LookupRoutes{}
|
|
for _, route := range routes {
|
|
// Filtering:
|
|
if isMemberOf(route.NeighborID, neighborIDs) {
|
|
lookup := routeToLookupRoute(nStore, source, state, route)
|
|
results = append(results, lookup)
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
|
|
// isMemberOf checks if a key is present in
|
|
// a list of strings.
|
|
func isMemberOf(list []string, key string) bool {
|
|
for _, v := range list {
|
|
if v == key {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|