public ShardProjectorChain(int numShards, List<Projection> projections, ProjectionToProjectorVisitor nodeProjectorVisitor) {
this.projections = projections;
nodeProjectors = new ArrayList<>();
if (projections.size() == 0) {
firstNodeProjector = new CollectingProjector();
lastProjector = (ResultProvider) firstNodeProjector;
nodeProjectors.add(firstNodeProjector);
shardProjectors = ImmutableList.of();
return;
}
int idx = 0;
for (Projection projection : projections) {
if (projection.requiredGranularity() == RowGranularity.SHARD) {
shardProjectionsIndex = idx;
break; // we can quit here since currently
// there can be only 1 projection on the shard
}
idx++;
}
Projector previousProjector = null;
// create the node level projectors
for (int i = shardProjectionsIndex + 1; i < projections.size(); i++) {
Projector projector = nodeProjectorVisitor.process(projections.get(i));
nodeProjectors.add(projector);
if (previousProjector != null) {
previousProjector.downstream(projector);
} else {
firstNodeProjector = projector;
}
previousProjector = projector;
}
if (shardProjectionsIndex >= 0) {
shardProjectors = new ArrayList<>((shardProjectionsIndex + 1) * numShards);
// shardprojector will be created later
if (nodeProjectors.isEmpty()) {
// no node projectors
previousProjector = firstNodeProjector = new CollectingProjector();
}
} else {
shardProjectors = ImmutableList.of();
}
assert previousProjector != null;
if (previousProjector instanceof ResultProvider) {
lastProjector = (ResultProvider) previousProjector;
} else {
lastProjector = new CollectingProjector();
previousProjector.downstream((Projector) lastProjector);
}
}