computeRoutes method
Computes complete routing table for a source node
network - Network topology as adjacency list
sourceNode - Source node for routing table computation
maxHops - Maximum hop count (default: 15 for RIP)
Returns a complete routing table with all reachable destinations
Throws ArgumentError if source node doesn't exist in network
Implementation
RoutingTable<T> computeRoutes(
Map<T, Map<T, num>> network,
T sourceNode, {
int maxHops = _maxHops,
}) {
// Input validation
if (!network.containsKey(sourceNode)) {
throw ArgumentError('Source node $sourceNode not found in network');
}
// Initialize routing table with direct connections
final routes = <T, RouteEntry<T>>{};
final now = DateTime.now();
// Add source node to itself
routes[sourceNode] = RouteEntry<T>(
destination: sourceNode,
nextHop: null,
cost: 0,
lastUpdate: now,
isDirectlyConnected: true,
);
// Add directly connected neighbors
final directNeighbors = network[sourceNode]!;
for (final neighbor in directNeighbors.keys) {
routes[neighbor] = RouteEntry<T>(
destination: neighbor,
nextHop: neighbor,
cost: 1,
lastUpdate: now,
isDirectlyConnected: true,
);
}
// Bellman-Ford iterations for route discovery
for (int iteration = 0; iteration < maxIterations; iteration++) {
bool hasChanges = false;
// Process each node in the network
for (final node in network.keys) {
if (node == sourceNode) continue;
final neighbors = network[node]!;
for (final neighbor in neighbors.keys) {
// Skip if neighbor is not in our routing table
if (!routes.containsKey(neighbor)) continue;
final neighborRoute = routes[neighbor]!;
final linkCost = neighbors[neighbor]!;
final newCost = neighborRoute.cost + linkCost.toInt();
// Check if we found a better route
if (!routes.containsKey(node) || newCost < routes[node]!.cost) {
if (newCost <= maxHops) {
routes[node] = RouteEntry<T>(
destination: node,
nextHop: neighbor,
cost: newCost,
lastUpdate: now,
isDirectlyConnected: false,
);
hasChanges = true;
}
}
}
}
// If no changes in this iteration, we've converged
if (!hasChanges) break;
}
return RoutingTable<T>(
sourceNode: sourceNode,
routes: Map.unmodifiable(routes),
lastUpdate: now,
);
}