use of com.datatorrent.api.DefaultPartition in project apex-core by apache.
the class PhysicalPlanTest method testDefaultRepartitioning.
@Test
public void testDefaultRepartitioning() {
List<PartitionKeys> twoBitPartitionKeys = Arrays.asList(newPartitionKeys("11", "00"), newPartitionKeys("11", "10"), newPartitionKeys("11", "01"), newPartitionKeys("11", "11"));
GenericTestOperator operator = new GenericTestOperator();
Set<PartitionKeys> initialPartitionKeys = Sets.newHashSet(newPartitionKeys("1", "0"), newPartitionKeys("1", "1"));
final ArrayList<Partition<Operator>> partitions = new ArrayList<>();
for (PartitionKeys pks : initialPartitionKeys) {
Map<InputPort<?>, PartitionKeys> p1Keys = new HashMap<>();
p1Keys.put(operator.inport1, pks);
partitions.add(new DefaultPartition<Operator>(operator, p1Keys, 1, null));
}
ArrayList<Partition<Operator>> lowLoadPartitions = new ArrayList<>();
for (Partition<Operator> p : partitions) {
lowLoadPartitions.add(new DefaultPartition<>(p.getPartitionedInstance(), p.getPartitionKeys(), -1, null));
}
// merge to single partition
List<Partition<Operator>> newPartitions = Lists.newArrayList();
Collection<Partition<Operator>> tempNewPartitions = StatelessPartitioner.repartition(lowLoadPartitions);
newPartitions.addAll(tempNewPartitions);
Assert.assertEquals("" + newPartitions, 1, newPartitions.size());
Assert.assertEquals("" + newPartitions.get(0).getPartitionKeys(), 0, newPartitions.get(0).getPartitionKeys().values().iterator().next().mask);
List<Partition<Operator>> tempList = Collections.singletonList((Partition<Operator>) new DefaultPartition<Operator>(operator, newPartitions.get(0).getPartitionKeys(), -1, null));
tempNewPartitions = StatelessPartitioner.repartition(tempList);
newPartitions.clear();
newPartitions.addAll(tempNewPartitions);
Assert.assertEquals("" + newPartitions, 1, newPartitions.size());
// split back into two
tempList = Collections.singletonList((Partition<Operator>) new DefaultPartition<Operator>(operator, newPartitions.get(0).getPartitionKeys(), 1, null));
tempNewPartitions = StatelessPartitioner.repartition(tempList);
newPartitions.clear();
newPartitions.addAll(tempNewPartitions);
Assert.assertEquals("" + newPartitions, 2, newPartitions.size());
// split partitions
tempNewPartitions = StatelessPartitioner.repartition(partitions);
newPartitions.clear();
newPartitions.addAll(tempNewPartitions);
Assert.assertEquals("" + newPartitions, 4, newPartitions.size());
Set<PartitionKeys> expectedPartitionKeys = Sets.newHashSet(twoBitPartitionKeys);
for (Partition<?> p : newPartitions) {
Assert.assertEquals("" + p.getPartitionKeys(), 1, p.getPartitionKeys().size());
Assert.assertEquals("" + p.getPartitionKeys(), operator.inport1, p.getPartitionKeys().keySet().iterator().next());
PartitionKeys pks = p.getPartitionKeys().values().iterator().next();
expectedPartitionKeys.remove(pks);
}
Assert.assertTrue("" + expectedPartitionKeys, expectedPartitionKeys.isEmpty());
// partition merge
List<HashSet<PartitionKeys>> expectedKeysSets = Arrays.asList(Sets.newHashSet(newPartitionKeys("11", "00"), newPartitionKeys("11", "10"), newPartitionKeys("1", "1")), Sets.newHashSet(newPartitionKeys("1", "0"), newPartitionKeys("11", "01"), newPartitionKeys("11", "11")));
for (Set<PartitionKeys> expectedKeys : expectedKeysSets) {
List<Partition<Operator>> clonePartitions = Lists.newArrayList();
for (PartitionKeys pks : twoBitPartitionKeys) {
Map<InputPort<?>, PartitionKeys> p1Keys = new HashMap<>();
p1Keys.put(operator.inport1, pks);
int load = expectedKeys.contains(pks) ? 0 : -1;
clonePartitions.add(new DefaultPartition<Operator>(operator, p1Keys, load, null));
}
tempNewPartitions = StatelessPartitioner.repartition(clonePartitions);
newPartitions.clear();
newPartitions.addAll(tempNewPartitions);
Assert.assertEquals("" + newPartitions, 3, newPartitions.size());
for (Partition<?> p : newPartitions) {
Assert.assertEquals("" + p.getPartitionKeys(), 1, p.getPartitionKeys().size());
Assert.assertEquals("" + p.getPartitionKeys(), operator.inport1, p.getPartitionKeys().keySet().iterator().next());
PartitionKeys pks = p.getPartitionKeys().values().iterator().next();
expectedKeys.remove(pks);
}
Assert.assertTrue("" + expectedKeys, expectedKeys.isEmpty());
}
// merge 2 into single partition
lowLoadPartitions = Lists.newArrayList();
for (Partition<?> p : partitions) {
lowLoadPartitions.add(new DefaultPartition<Operator>(operator, p.getPartitionKeys(), -1, null));
}
tempNewPartitions = StatelessPartitioner.repartition(lowLoadPartitions);
newPartitions.clear();
newPartitions.addAll(tempNewPartitions);
Assert.assertEquals("" + newPartitions, 1, newPartitions.size());
for (Partition<?> p : newPartitions) {
Assert.assertEquals("" + p.getPartitionKeys(), 1, p.getPartitionKeys().size());
PartitionKeys pks = p.getPartitionKeys().values().iterator().next();
Assert.assertEquals("" + pks, 0, pks.mask);
Assert.assertEquals("" + pks, Sets.newHashSet(0), pks.partitions);
}
}
use of com.datatorrent.api.DefaultPartition in project apex-core by apache.
the class PhysicalPlanTest method testMxNPartitioning.
/**
* MxN partitioning. When source and sink of a stream are partitioned, a
* separate unifier is created container local with each downstream partition.
*/
@Test
public void testMxNPartitioning() {
LogicalPlan dag = new LogicalPlan();
TestGeneratorInputOperator o1 = dag.addOperator("o1", TestGeneratorInputOperator.class);
TestPartitioner<TestGeneratorInputOperator> o1Partitioner = new TestPartitioner<>();
o1Partitioner.setPartitionCount(2);
dag.setOperatorAttribute(o1, OperatorContext.PARTITIONER, o1Partitioner);
dag.setOperatorAttribute(o1, OperatorContext.STATS_LISTENERS, Lists.newArrayList((StatsListener) new PartitioningTest.PartitionLoadWatch()));
OperatorMeta o1Meta = dag.getMeta(o1);
GenericTestOperator o2 = dag.addOperator("o2", GenericTestOperator.class);
dag.setOperatorAttribute(o2, OperatorContext.PARTITIONER, new StatelessPartitioner<TestGeneratorInputOperator>(3));
dag.setOperatorAttribute(o2, OperatorContext.STATS_LISTENERS, Arrays.asList(new StatsListener[] { new PartitioningTest.PartitionLoadWatch() }));
OperatorMeta o2Meta = dag.getMeta(o2);
dag.addStream("o1.outport1", o1.outport, o2.inport1);
TestPlanContext ctx = new TestPlanContext();
dag.setAttribute(OperatorContext.STORAGE_AGENT, ctx);
PhysicalPlan plan = new PhysicalPlan(dag, ctx);
Assert.assertEquals("number of containers", 5, plan.getContainers().size());
List<PTOperator> inputOperators = new ArrayList<>();
for (int i = 0; i < 2; i++) {
PTContainer container = plan.getContainers().get(i);
Assert.assertEquals("number operators " + container, 1, container.getOperators().size());
Assert.assertEquals("operators " + container, o1Meta.getName(), container.getOperators().get(0).getOperatorMeta().getName());
inputOperators.add(container.getOperators().get(0));
}
for (int i = 2; i < 5; i++) {
PTContainer container = plan.getContainers().get(i);
Assert.assertEquals("number operators " + container, 2, container.getOperators().size());
Assert.assertEquals("operators " + container, o2Meta.getName(), container.getOperators().get(0).getOperatorMeta().getName());
Set<String> expectedLogicalNames = Sets.newHashSet(o1Meta.getMeta(o1.outport).getUnifierMeta().getName(), o2Meta.getName());
Map<String, PTOperator> actualOperators = new HashMap<>();
for (PTOperator p : container.getOperators()) {
actualOperators.put(p.getOperatorMeta().getName(), p);
}
Assert.assertEquals("", expectedLogicalNames, actualOperators.keySet());
PTOperator pUnifier = actualOperators.get(o1Meta.getMeta(o1.outport).getUnifierMeta().getName());
Assert.assertNotNull("" + pUnifier, pUnifier.getContainer());
Assert.assertTrue("" + pUnifier, pUnifier.isUnifier());
// input from each upstream partition
Assert.assertEquals("" + pUnifier, 2, pUnifier.getInputs().size());
int numberPartitionKeys = (i == 2) ? 2 : 1;
for (int inputIndex = 0; inputIndex < pUnifier.getInputs().size(); inputIndex++) {
PTInput input = pUnifier.getInputs().get(inputIndex);
Assert.assertEquals("" + pUnifier, "outport", input.source.portName);
Assert.assertEquals("" + pUnifier, inputOperators.get(inputIndex), input.source.source);
Assert.assertEquals("partition keys " + input.partitions, numberPartitionKeys, input.partitions.partitions.size());
}
// output to single downstream partition
Assert.assertEquals("" + pUnifier, 1, pUnifier.getOutputs().size());
Assert.assertTrue("" + actualOperators.get(o2Meta.getName()).getOperatorMeta().getOperator(), actualOperators.get(o2Meta.getName()).getOperatorMeta().getOperator() instanceof GenericTestOperator);
PTOperator p = actualOperators.get(o2Meta.getName());
Assert.assertEquals("partition inputs " + p.getInputs(), 1, p.getInputs().size());
Assert.assertEquals("partition inputs " + p.getInputs(), pUnifier, p.getInputs().get(0).source.source);
Assert.assertEquals("input partition keys " + p.getInputs(), null, p.getInputs().get(0).partitions);
Assert.assertTrue("partitioned unifier container local " + p.getInputs().get(0).source, p.getInputs().get(0).source.isDownStreamInline());
}
// scale down N from 3 to 2 and then from 2 to 1
for (int i = 0; i < 2; i++) {
List<PTOperator> ptos = plan.getOperators(o2Meta);
Set<PTOperator> expUndeploy = Sets.newHashSet(ptos);
for (PTOperator ptOperator : ptos) {
expUndeploy.addAll(ptOperator.upstreamMerge.values());
PartitioningTest.PartitionLoadWatch.put(ptOperator, -1);
plan.onStatusUpdate(ptOperator);
}
ctx.backupRequests = 0;
ctx.events.remove(0).run();
Set<PTOperator> expDeploy = Sets.newHashSet(plan.getOperators(o2Meta));
// Either unifiers for each partition or single unifier for single partition is expected to be deployed
expDeploy.addAll(plan.getMergeOperators(o1Meta));
for (PTOperator ptOperator : plan.getOperators(o2Meta)) {
expDeploy.addAll(ptOperator.upstreamMerge.values());
}
Assert.assertEquals("number of containers", 4 - i, plan.getContainers().size());
Assert.assertEquals("number of operators", 2 - i, plan.getOperators(o2Meta).size());
Assert.assertEquals("undeployed operators " + ctx.undeploy, expUndeploy, ctx.undeploy);
Assert.assertEquals("deployed operators " + ctx.deploy, expDeploy, ctx.deploy);
}
// scale up N from 1 to 2 and then from 2 to 3
for (int i = 0; i < 2; i++) {
List<PTOperator> unChangedOps = new LinkedList<>(plan.getOperators(o2Meta));
PTOperator o2p1 = unChangedOps.remove(0);
Set<PTOperator> expUndeploy = Sets.newHashSet(o2p1);
// Either single unifier for one partition or merged unifiers for each partition is expected to be undeployed
expUndeploy.addAll(plan.getMergeOperators(o1Meta));
expUndeploy.addAll(o2p1.upstreamMerge.values());
List<PTOperator> nOps = new LinkedList<>();
for (Iterator<PTOperator> iterator = unChangedOps.iterator(); iterator.hasNext(); ) {
PTOperator ptOperator = iterator.next();
nOps.addAll(ptOperator.upstreamMerge.values());
}
unChangedOps.addAll(nOps);
PartitioningTest.PartitionLoadWatch.put(o2p1, 1);
plan.onStatusUpdate(o2p1);
Assert.assertEquals("repartition event", 1, ctx.events.size());
ctx.backupRequests = 0;
ctx.events.remove(0).run();
Assert.assertEquals("N partitions after scale up " + o2Meta, 2 + i, plan.getOperators(o2Meta).size());
Assert.assertTrue("no unifiers", plan.getMergeOperators(o1Meta).isEmpty());
for (PTOperator o : plan.getOperators(o2Meta)) {
Assert.assertNotNull(o.container);
PTOperator unifier = o.upstreamMerge.values().iterator().next();
Assert.assertNotNull(unifier.container);
Assert.assertSame("unifier in same container", o.container, unifier.container);
Assert.assertEquals("container operators " + o.container, Sets.newHashSet(o.container.getOperators()), Sets.newHashSet(o, unifier));
}
Set<PTOperator> expDeploy = Sets.newHashSet(plan.getOperators(o2Meta));
for (PTOperator ptOperator : plan.getOperators(o2Meta)) {
expDeploy.addAll(ptOperator.upstreamMerge.values());
}
expDeploy.removeAll(unChangedOps);
Assert.assertEquals("number of containers", 4 + i, plan.getContainers().size());
Assert.assertEquals("undeployed operators" + ctx.undeploy, expUndeploy, ctx.undeploy);
Assert.assertEquals("deployed operators" + ctx.deploy, expDeploy, ctx.deploy);
}
// scale down M to 1
{
Set<PTOperator> expUndeploy = Sets.newHashSet();
Set<PTOperator> expDeploy = Sets.newHashSet();
for (PTOperator o2p : plan.getOperators(o2Meta)) {
expUndeploy.addAll(o2p.upstreamMerge.values());
expUndeploy.add(o2p);
expDeploy.add(o2p);
}
for (PTOperator o1p : plan.getOperators(o1Meta)) {
expUndeploy.add(o1p);
PartitioningTest.PartitionLoadWatch.put(o1p, -1);
plan.onStatusUpdate(o1p);
}
Assert.assertEquals("repartition event", 1, ctx.events.size());
ctx.events.remove(0).run();
Assert.assertEquals("M partitions after scale down " + o1Meta, 1, plan.getOperators(o1Meta).size());
expUndeploy.removeAll(plan.getOperators(o1Meta));
for (PTOperator o2p : plan.getOperators(o2Meta)) {
Assert.assertTrue("merge unifier " + o2p + " " + o2p.upstreamMerge, o2p.upstreamMerge.isEmpty());
}
Assert.assertEquals("undeploy", expUndeploy, ctx.undeploy);
Assert.assertEquals("deploy", expDeploy, ctx.deploy);
}
// scale up M to 2
Assert.assertEquals("M partitions " + o1Meta, 1, plan.getOperators(o1Meta).size());
{
Set<PTOperator> expUndeploy = Sets.newHashSet();
Set<PTOperator> expDeploy = Sets.newHashSet();
for (PTOperator o1p : plan.getOperators(o1Meta)) {
PartitioningTest.PartitionLoadWatch.put(o1p, 1);
plan.onStatusUpdate(o1p);
}
Assert.assertEquals("repartition event", 1, ctx.events.size());
o1Partitioner.extraPartitions.add(new DefaultPartition<>(o1));
ctx.events.remove(0).run();
o1Partitioner.extraPartitions.clear();
List<PTOperator> o1Partitions = plan.getOperators(o1Meta);
List<PTOperator> o2Partitions = plan.getOperators(o2Meta);
Assert.assertEquals("M partitions after scale up " + o1Meta, 2, o1Partitions.size());
// previous partition unchanged
expDeploy.add(o1Partitions.get(1));
for (PTOperator o1p : o1Partitions) {
Assert.assertEquals("outputs " + o1p, 1, o1p.getOutputs().size());
Assert.assertEquals("sinks " + o1p, o2Partitions.size(), o1p.getOutputs().get(0).sinks.size());
}
for (PTOperator o2p : plan.getOperators(o2Meta)) {
expUndeploy.add(o2p);
expDeploy.add(o2p);
Assert.assertEquals("merge unifier " + o2p + " " + o2p.upstreamMerge, 1, o2p.upstreamMerge.size());
expDeploy.addAll(o2p.upstreamMerge.values());
}
Assert.assertEquals("undeploy", expUndeploy, ctx.undeploy);
Assert.assertEquals("deploy", expDeploy, ctx.deploy);
}
}
use of com.datatorrent.api.DefaultPartition in project apex-core by apache.
the class PhysicalPlan method redoPartitions.
private void redoPartitions(PMapping currentMapping, String note) {
Partitioner<Operator> partitioner = getPartitioner(currentMapping);
if (partitioner == null) {
LOG.warn("No partitioner for {}", currentMapping.logicalOperator);
return;
}
RepartitionContext mainPC = new RepartitionContext(partitioner, currentMapping, 0);
if (mainPC.newPartitions.isEmpty()) {
LOG.warn("Empty partition list after repartition: {}", currentMapping.logicalOperator);
return;
}
int memoryPerPartition = currentMapping.logicalOperator.getValue(OperatorContext.MEMORY_MB);
for (Map.Entry<OutputPortMeta, StreamMeta> stream : currentMapping.logicalOperator.getOutputStreams().entrySet()) {
if (stream.getValue().getLocality() != Locality.THREAD_LOCAL && stream.getValue().getLocality() != Locality.CONTAINER_LOCAL) {
memoryPerPartition += stream.getKey().getValue(PortContext.BUFFER_MEMORY_MB);
}
}
for (OperatorMeta pp : currentMapping.parallelPartitions) {
for (Map.Entry<OutputPortMeta, StreamMeta> stream : pp.getOutputStreams().entrySet()) {
if (stream.getValue().getLocality() != Locality.THREAD_LOCAL && stream.getValue().getLocality() != Locality.CONTAINER_LOCAL) {
memoryPerPartition += stream.getKey().getValue(PortContext.BUFFER_MEMORY_MB);
}
}
memoryPerPartition += pp.getValue(OperatorContext.MEMORY_MB);
}
int requiredMemoryMB = (mainPC.newPartitions.size() - mainPC.currentPartitions.size()) * memoryPerPartition;
if (requiredMemoryMB > availableMemoryMB) {
LOG.warn("Insufficient headroom for repartitioning: available {}m required {}m", availableMemoryMB, requiredMemoryMB);
return;
}
List<Partition<Operator>> addedPartitions = new ArrayList<>();
// determine modifications of partition set, identify affected operator instance(s)
for (Partition<Operator> newPartition : mainPC.newPartitions) {
PTOperator op = mainPC.currentPartitionMap.remove(newPartition);
if (op == null) {
addedPartitions.add(newPartition);
} else {
// check whether mapping was changed
for (DefaultPartition<Operator> pi : mainPC.currentPartitions) {
if (pi == newPartition && pi.isModified()) {
// existing partition changed (operator or partition keys)
// remove/add to update subscribers and state
mainPC.currentPartitionMap.put(newPartition, op);
addedPartitions.add(newPartition);
}
}
}
}
// remaining entries represent deprecated partitions
this.undeployOpers.addAll(mainPC.currentPartitionMap.values());
// downstream dependencies require redeploy, resolve prior to modifying plan
Set<PTOperator> deps = this.getDependents(mainPC.currentPartitionMap.values());
this.undeployOpers.addAll(deps);
// dependencies need redeploy, except operators excluded in remove
this.deployOpers.addAll(deps);
// process parallel partitions before removing operators from the plan
LinkedHashMap<PMapping, RepartitionContext> partitionContexts = Maps.newLinkedHashMap();
Stack<OperatorMeta> parallelPartitions = new Stack<>();
parallelPartitions.addAll(currentMapping.parallelPartitions);
pendingLoop: while (!parallelPartitions.isEmpty()) {
OperatorMeta ppMeta = parallelPartitions.pop();
for (StreamMeta s : ppMeta.getInputStreams().values()) {
if (currentMapping.parallelPartitions.contains(s.getSource().getOperatorMeta()) && parallelPartitions.contains(s.getSource().getOperatorMeta())) {
parallelPartitions.push(ppMeta);
parallelPartitions.remove(s.getSource().getOperatorMeta());
parallelPartitions.push(s.getSource().getOperatorMeta());
continue pendingLoop;
}
}
LOG.debug("Processing parallel partition {}", ppMeta);
PMapping ppm = this.logicalToPTOperator.get(ppMeta);
Partitioner<Operator> ppp = getPartitioner(ppm);
if (ppp == null) {
partitionContexts.put(ppm, null);
} else {
RepartitionContext pc = new RepartitionContext(ppp, ppm, mainPC.newPartitions.size());
if (pc.newPartitions == null) {
throw new IllegalStateException("Partitioner returns null for parallel partition " + ppm.logicalOperator);
}
partitionContexts.put(ppm, pc);
}
}
// plan updates start here, after all changes were identified
// remove obsolete operators first, any freed resources
// can subsequently be used for new/modified partitions
List<PTOperator> copyPartitions = Lists.newArrayList(currentMapping.partitions);
// remove deprecated partitions from plan
for (PTOperator p : mainPC.currentPartitionMap.values()) {
copyPartitions.remove(p);
removePartition(p, currentMapping);
mainPC.operatorIdToPartition.remove(p.getId());
}
currentMapping.partitions = copyPartitions;
// add new operators
for (Partition<Operator> newPartition : addedPartitions) {
PTOperator p = addPTOperator(currentMapping, newPartition, mainPC.minCheckpoint);
mainPC.operatorIdToPartition.put(p.getId(), newPartition);
}
// process parallel partition changes
for (Map.Entry<PMapping, RepartitionContext> e : partitionContexts.entrySet()) {
if (e.getValue() == null) {
// no partitioner, add required operators
for (int i = 0; i < addedPartitions.size(); i++) {
LOG.debug("Automatically adding to parallel partition {}", e.getKey());
// set activation windowId to confirm to upstream checkpoints
addPTOperator(e.getKey(), null, mainPC.minCheckpoint);
}
} else {
RepartitionContext pc = e.getValue();
// track previous parallel partition mapping
Map<Partition<Operator>, Partition<Operator>> prevMapping = Maps.newHashMap();
for (int i = 0; i < mainPC.currentPartitions.size(); i++) {
prevMapping.put(pc.currentPartitions.get(i), mainPC.currentPartitions.get(i));
}
// determine which new partitions match upstream, remaining to be treated as new operator
Map<Partition<Operator>, Partition<Operator>> newMapping = Maps.newHashMap();
Iterator<Partition<Operator>> itMain = mainPC.newPartitions.iterator();
Iterator<Partition<Operator>> itParallel = pc.newPartitions.iterator();
while (itMain.hasNext() && itParallel.hasNext()) {
newMapping.put(itParallel.next(), itMain.next());
}
for (Partition<Operator> newPartition : pc.newPartitions) {
PTOperator op = pc.currentPartitionMap.remove(newPartition);
if (op == null) {
pc.addedPartitions.add(newPartition);
} else if (prevMapping.get(newPartition) != newMapping.get(newPartition)) {
// upstream partitions don't match, remove/add to replace with new operator
pc.currentPartitionMap.put(newPartition, op);
pc.addedPartitions.add(newPartition);
} else {
// check whether mapping was changed - based on DefaultPartition implementation
for (DefaultPartition<Operator> pi : pc.currentPartitions) {
if (pi == newPartition && pi.isModified()) {
// existing partition changed (operator or partition keys)
// remove/add to update subscribers and state
mainPC.currentPartitionMap.put(newPartition, op);
pc.addedPartitions.add(newPartition);
}
}
}
}
if (!pc.currentPartitionMap.isEmpty()) {
// remove obsolete partitions
List<PTOperator> cowPartitions = Lists.newArrayList(e.getKey().partitions);
for (PTOperator p : pc.currentPartitionMap.values()) {
cowPartitions.remove(p);
removePartition(p, e.getKey());
pc.operatorIdToPartition.remove(p.getId());
}
e.getKey().partitions = cowPartitions;
}
// add new partitions
for (Partition<Operator> newPartition : pc.addedPartitions) {
PTOperator oper = addPTOperator(e.getKey(), newPartition, mainPC.minCheckpoint);
pc.operatorIdToPartition.put(oper.getId(), newPartition);
}
getPartitioner(e.getKey()).partitioned(pc.operatorIdToPartition);
}
}
updateStreamMappings(currentMapping);
for (PMapping pp : partitionContexts.keySet()) {
updateStreamMappings(pp);
}
deployChanges();
if (mainPC.currentPartitions.size() != mainPC.newPartitions.size()) {
StramEvent ev = new StramEvent.PartitionEvent(currentMapping.logicalOperator.getName(), mainPC.currentPartitions.size(), mainPC.newPartitions.size());
ev.setReason(note);
this.ctx.recordEventAsync(ev);
}
partitioner.partitioned(mainPC.operatorIdToPartition);
}
use of com.datatorrent.api.DefaultPartition in project apex-core by apache.
the class PhysicalPlan method initPartitioning.
private void initPartitioning(PMapping m, int partitionCnt) {
Operator operator = m.logicalOperator.getOperator();
Collection<Partition<Operator>> partitions;
@SuppressWarnings("unchecked") Partitioner<Operator> partitioner = m.logicalOperator.getAttributes().contains(OperatorContext.PARTITIONER) ? (Partitioner<Operator>) m.logicalOperator.getValue(OperatorContext.PARTITIONER) : operator instanceof Partitioner ? (Partitioner<Operator>) operator : null;
Collection<Partition<Operator>> collection = new ArrayList<>(1);
DefaultPartition<Operator> firstPartition = new DefaultPartition<>(operator);
collection.add(firstPartition);
if (partitioner != null) {
partitions = partitioner.definePartitions(collection, new PartitioningContextImpl(m, partitionCnt));
if (partitions == null || partitions.isEmpty()) {
throw new IllegalStateException("Partitioner returns null or empty.");
}
} else {
//Non zero in the case of parallel partitioning.
for (int partitionCounter = 0; partitionCounter < partitionCnt - 1; partitionCounter++) {
collection.add(firstPartition);
}
partitions = collection;
}
Collection<StatsListener> statsListeners = m.logicalOperator.getValue(OperatorContext.STATS_LISTENERS);
if (statsListeners != null && !statsListeners.isEmpty()) {
if (m.statsHandlers == null) {
m.statsHandlers = new ArrayList<>(statsListeners.size());
}
m.statsHandlers.addAll(statsListeners);
}
if (m.logicalOperator.getOperator() instanceof StatsListener) {
if (m.statsHandlers == null) {
m.statsHandlers = new ArrayList<>(1);
}
m.statsHandlers.add(new StatsListenerProxy(m.logicalOperator));
}
// create operator instance per partition
Map<Integer, Partition<Operator>> operatorIdToPartition = Maps.newHashMapWithExpectedSize(partitions.size());
for (Partition<Operator> partition : partitions) {
PTOperator p = addPTOperator(m, partition, null);
operatorIdToPartition.put(p.getId(), partition);
}
if (partitioner != null) {
partitioner.partitioned(operatorIdToPartition);
}
}
Aggregations