1
0
mirror of https://github.com/alice-lg/alice-lg.git synced 2024-05-11 05:55:03 +00:00
2022-02-10 18:38:32 +01:00

170 lines
3.4 KiB
Go

package memory
import (
"context"
"strings"
"sync"
"github.com/alice-lg/alice-lg/pkg/api"
"github.com/alice-lg/alice-lg/pkg/sources"
)
// 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(map[string]api.LookupRoutes),
}
}
// 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()
// Remove details from routes
for _, r := range routes {
r.Route.Details = nil
}
r.routes[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
}
var (
imported uint = 0
filtered uint = 0
)
for _, route := range routes {
if route.State == api.RouteStateFiltered {
filtered++
}
if route.State == api.RouteStateImported {
imported++
}
}
return imported, filtered, nil
}
// FindByNeighbors will return the prefixes for a
// list of neighbors identified by ID.
func (r *RoutesBackend) FindByNeighbors(
ctx context.Context,
neighborIDs []string,
) (api.LookupRoutes, error) {
r.Lock()
defer r.Unlock()
result := api.LookupRoutes{}
for _, rs := range r.routes {
for _, route := range rs {
if isMemberOf(neighborIDs, route.NeighborID) {
result = append(result, route)
}
}
}
return result, nil
}
// FindByPrefix will return the prefixes matching a pattern
func (r *RoutesBackend) FindByPrefix(
ctx context.Context,
prefix string,
) (api.LookupRoutes, error) {
r.Lock()
defer r.Unlock()
// We make our compare case insensitive
prefix = strings.ToLower(prefix)
result := api.LookupRoutes{}
for _, rs := range r.routes {
for _, route := range rs {
// Naiive string filtering:
if strings.HasPrefix(strings.ToLower(route.Network), prefix) {
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(neighborIDs, route.NeighborID) {
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
}