package com.bigdata.bop.fed.shards;
import java.util.LinkedList;
import org.apache.log4j.Logger;
import com.bigdata.bop.IBindingSet;
import com.bigdata.mdi.PartitionLocator;
import com.bigdata.relation.accesspath.IBuffer;
import com.bigdata.service.Split;
import com.bigdata.service.ndx.AbstractSplitter;
import com.bigdata.service.ndx.ISplitter;
import com.bigdata.striterator.IKeyOrder;
/**
* When the asBound predicates are known to be fully bound, then the
* {@link AbstractSplitter} can be used. This approach is quite efficient.
*/
class Algorithm_FullyBoundPredicate<E extends IBindingSet, F> implements
IShardMapper<E, F> {
static transient private final Logger log = Logger
.getLogger(Algorithm_FullyBoundPredicate.class);
private final MapBindingSetsOverShardsBuffer<E, F> op;
private final IKeyOrder keyOrder;
private final ISplitter splitter;
/**
*
* @param op
* @param keyOrder
* The key order which will be used for the predicate when it is
* fully bound.
*/
public Algorithm_FullyBoundPredicate(
final MapBindingSetsOverShardsBuffer<E, F> op,
final IKeyOrder<F> keyOrder) {
this.op = op;
this.keyOrder = keyOrder;
this.splitter = new Splitter(op.getMetadataIndex(keyOrder));
}
public void mapOverShards(final Bundle<F>[] bundles) {
/*
* Construct a byte[][] out of the sorted fromKeys and then generate
* slices (Splits) which group the binding sets based on the target
* shard.
*/
final LinkedList<Split> splits;
{
final byte[][] keys = new byte[bundles.length][];
for (int i = 0; i < bundles.length; i++) {
keys[i] = bundles[i].fromKey;
}
splits = splitter.splitKeys(op.timestamp, 0/* fromIndex */,
bundles.length/* toIndex */, keys);
}
if (log.isTraceEnabled())
log.trace("nsplits=" + splits.size() + ", pred=" + op.pred);
/*
* For each split, write the binding sets in that split onto the
* corresponding buffer.
*/
for (Split split : splits) {
// Note: pmd is a PartitionLocator, so this cast is valid.
final IBuffer<IBindingSet[]> sink = op
.getBuffer((PartitionLocator) split.pmd);
final IBindingSet[] slice = new IBindingSet[split.ntuples];
for (int j = 0, i = split.fromIndex; i < split.toIndex; i++, j++) {
final IBindingSet bset = bundles[i].bindingSet;
slice[j] = bset;
if (log.isTraceEnabled())
log.trace("Mapping: keyOrder=" + keyOrder + ", bset="
+ bset + " onto partitionId="
+ split.pmd.getPartitionId());
}
sink.add(slice);
}
}
}