During the development and review process of the disk health indicator we noticed that it was hard to understand. Since we learnt a lot from the first round of development we want to go through the code one more time and restructure it.
server/src/main/java/org/elasticsearch/cluster/routing/RoutingNode.java
switch (shard.state()) {
                case INITIALIZING -> shardRoutingsInitializing.add(shard);
                case RELOCATING -> shardRoutingsRelocating.add(shard);
                case STARTED -> shardRoutingsStarted.add(shard);
            }
            shardRoutingsByIndex.computeIfAbsent(shard.index(), k -> new HashSet<>(10)).add(shard);
        }
        assert initializingShards.size() == shardRoutingsInitializing.size() && initializingShards.containsAll(shardRoutingsInitializing);
        assert relocatingShards.size() == shardRoutingsRelocating.size() && relocatingShards.containsAll(shardRoutingsRelocating);
        assert startedShards.size() == shardRoutingsStarted.size() && startedShards.containsAll(shardRoutingsStarted);
        assert shardRoutingsByIndex.equals(shardsByIndex);
        return true;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        RoutingNode that = (RoutingNode) o;
        return nodeId.equals(that.nodeId) && Objects.equals(node, that.node) && shards.equals(that.shards);
    }
    @Override
    public int hashCode() {
        return Objects.hash(nodeId, node, shards);
    }
}