NodeIdManagerRegistry.java
package net.bmahe.genetics4j.neat;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.Validate;
import net.bmahe.genetics4j.neat.spec.NeatNodeLayout;
/**
* Maintains one population-scoped {@link NodeIdManager} per semantic node layout.
*
* <p>Layouts are keyed by their ordered input IDs, ordered output IDs, and hidden-node range rather than their concrete
* implementation class. Semantically equivalent layout implementations therefore share allocation history.
*/
public class NodeIdManagerRegistry {
private record LayoutKey(List<Integer> inputNodeIds, List<Integer> outputNodeIds, long hiddenStart, long hiddenEnd) {
private LayoutKey(final NeatNodeLayout layout) {
this(List.copyOf(layout.inputNodeIds()),
List.copyOf(layout.outputNodeIds()),
layout.hiddenNodeIdStartInclusive(),
layout.hiddenNodeIdEndExclusive());
}
}
private final ConcurrentHashMap<LayoutKey, NodeIdManager> managers = new ConcurrentHashMap<>();
/**
* Returns the shared node-ID manager for a layout, creating it when first requested.
*
* @param nodeLayout node layout used by a population
* @return the shared manager for the layout's semantic key
* @throws NullPointerException if {@code nodeLayout} is {@code null}
*/
public NodeIdManager managerFor(final NeatNodeLayout nodeLayout) {
Validate.notNull(nodeLayout);
return managers.computeIfAbsent(new LayoutKey(nodeLayout), ignored -> new NodeIdManager(nodeLayout));
}
}