
com.hazelcast.mapreduce.impl.task.MapCombineTask Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.mapreduce.impl.task;
import com.hazelcast.mapreduce.KeyValueSource;
import com.hazelcast.mapreduce.LifecycleMapper;
import com.hazelcast.mapreduce.Mapper;
import com.hazelcast.mapreduce.PartitionIdAware;
import com.hazelcast.mapreduce.impl.MapReduceService;
import com.hazelcast.mapreduce.impl.MapReduceUtil;
import com.hazelcast.mapreduce.impl.notification.IntermediateChunkNotification;
import com.hazelcast.mapreduce.impl.notification.LastChunkNotification;
import com.hazelcast.mapreduce.impl.operation.KeysAssignmentOperation;
import com.hazelcast.mapreduce.impl.operation.KeysAssignmentResult;
import com.hazelcast.mapreduce.impl.operation.PostPonePartitionProcessing;
import com.hazelcast.mapreduce.impl.operation.RequestMemberIdAssignment;
import com.hazelcast.mapreduce.impl.operation.RequestPartitionMapping;
import com.hazelcast.mapreduce.impl.operation.RequestPartitionProcessed;
import com.hazelcast.mapreduce.impl.operation.RequestPartitionReducing;
import com.hazelcast.mapreduce.impl.operation.RequestPartitionResult;
import com.hazelcast.nio.Address;
import com.hazelcast.partition.InternalPartitionService;
import com.hazelcast.spi.NodeEngine;
import com.hazelcast.util.ExceptionUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.hazelcast.mapreduce.JobPartitionState.State.REDUCING;
import static com.hazelcast.mapreduce.impl.MapReduceUtil.notifyRemoteException;
import static com.hazelcast.mapreduce.impl.operation.RequestPartitionResult.ResultState.CHECK_STATE_FAILED;
import static com.hazelcast.mapreduce.impl.operation.RequestPartitionResult.ResultState.NO_MORE_PARTITIONS;
import static com.hazelcast.mapreduce.impl.operation.RequestPartitionResult.ResultState.NO_SUPERVISOR;
import static com.hazelcast.mapreduce.impl.operation.RequestPartitionResult.ResultState.SUCCESSFUL;
/**
* This class acutally executed the mapping-combine phase. It is responsible for opening / closing
* the {@link com.hazelcast.mapreduce.KeyValueSource} implementation and possible configuring the
* partitionId to operate on.
*
* @param type of the input key
* @param type of the input value
* @param type of the emitted key
* @param type of the emitted value
* @param type of the intermediate chunk (retrieved from combiners)
*/
public class MapCombineTask {
private final AtomicBoolean cancelled = new AtomicBoolean();
private final Mapper mapper;
private final MappingPhase mappingPhase;
private final KeyValueSource keyValueSource;
private final MapReduceService mapReduceService;
private final InternalPartitionService partitionService;
private final JobSupervisor supervisor;
private final NodeEngine nodeEngine;
private final String name;
private final String jobId;
private final int chunkSize;
public MapCombineTask(JobTaskConfiguration configuration, JobSupervisor supervisor,
MappingPhase mappingPhase) {
this.mappingPhase = mappingPhase;
this.supervisor = supervisor;
this.mapper = configuration.getMapper();
this.name = configuration.getName();
this.jobId = configuration.getJobId();
this.chunkSize = configuration.getChunkSize();
this.nodeEngine = configuration.getNodeEngine();
this.partitionService = nodeEngine.getPartitionService();
this.mapReduceService = supervisor.getMapReduceService();
this.keyValueSource = configuration.getKeyValueSource();
}
public String getName() {
return name;
}
public String getJobId() {
return jobId;
}
public int getChunkSize() {
return chunkSize;
}
public void cancel() {
cancelled.set(true);
mappingPhase.cancel();
}
public void process() {
ExecutorService es = mapReduceService.getExecutorService(name);
if (keyValueSource instanceof PartitionIdAware) {
es.submit(new PartitionBasedProcessor());
} else {
es.submit(new NonPartitionBasedProcessor());
}
}
public final void processMapping(int partitionId, DefaultContext context,
KeyValueSource keyValueSource, boolean partitionProcessor)
throws Exception {
context.setPartitionId(partitionId);
if (mapper instanceof LifecycleMapper) {
((LifecycleMapper) mapper).initialize(context);
}
int keyPreSelectorId = partitionProcessor ? partitionId : -1;
if (mappingPhase.processingPartitionNecessary(keyPreSelectorId, partitionService)) {
mappingPhase.executeMappingPhase(keyValueSource, mapper, context);
}
if (mapper instanceof LifecycleMapper) {
((LifecycleMapper) mapper).finalized(context);
}
}
void onEmit(DefaultContext context, int partitionId) {
// If we have a reducer let's test for chunk size otherwise
// we need to collect all values locally and wait for final request
if (supervisor.getConfiguration().getReducerFactory() != null) {
if (context.getCollected() == chunkSize) {
Map chunkMap = context.requestChunk();
// Wrap into IntermediateChunkNotification object
Map> mapping = mapResultToMember(supervisor, chunkMap);
// Register remote addresses and partitionId for receiving reducer events
supervisor.registerReducerEventInterests(partitionId, mapping.keySet());
for (Map.Entry> entry : mapping.entrySet()) {
mapReduceService.sendNotification(entry.getKey(),
new IntermediateChunkNotification(entry.getKey(), name, jobId, entry.getValue(), partitionId));
}
}
}
}
public static Map> mapResultToMember(JobSupervisor supervisor, Map result) {
Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy