computeRoutes method

RoutingTable<T> computeRoutes(
  1. Map<T, Map<T, num>> network,
  2. T sourceNode, {
  3. int maxHops = _maxHops,
})

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,
  );
}