private <KIn, VIn, KOut, VOut> Map<KOut, List<VOut>> combineForLocalReduction( MapCombineCommand<KIn, VIn, KOut, VOut> mcc, CollectableCollector<KOut, VOut> collector) { String taskId = mcc.getTaskId(); Reducer<KOut, VOut> combiner = mcc.getCombiner(); Map<KOut, List<VOut>> result = null; if (combiner != null) { result = new HashMap<KOut, List<VOut>>(); log.tracef("For m/r task %s invoking combiner %s at %s", taskId, mcc, cdl.getAddress()); MapReduceTaskLifecycleService taskLifecycleService = MapReduceTaskLifecycleService.getInstance(); long start = log.isTraceEnabled() ? timeService.time() : 0; try { Cache<?, ?> cache = cacheManager.getCache(mcc.getCacheName()); taskLifecycleService.onPreExecute(combiner, cache); Map<KOut, List<VOut>> collectedValues = collector.collectedValues(); for (Entry<KOut, List<VOut>> e : collectedValues.entrySet()) { VOut combined; List<VOut> list = e.getValue(); List<VOut> l = new LinkedList<VOut>(); if (list.size() > 1) { combined = combiner.reduce(e.getKey(), list.iterator()); } else { combined = list.get(0); } l.add(combined); result.put(e.getKey(), l); log.tracef( "For m/r task %s combined %s to %s at %s", taskId, e.getKey(), combined, cdl.getAddress()); } } finally { if (log.isTraceEnabled()) { log.tracef( "Combine for task %s took %s milliseconds", mcc.getTaskId(), timeService.timeDuration(start, TimeUnit.MILLISECONDS)); } taskLifecycleService.onPostExecute(combiner); } } else { // Combiner not specified result = collector.collectedValues(); } return result; }
/** @param isRemote true if the command is deserialized and is executed remote. */ @Override public void initializeReplicableCommand(ReplicableCommand c, boolean isRemote) { if (c == null) return; switch (c.getCommandId()) { case PutKeyValueCommand.COMMAND_ID: ((PutKeyValueCommand) c).init(notifier, configuration); break; case ReplaceCommand.COMMAND_ID: ((ReplaceCommand) c).init(notifier, configuration); break; case PutMapCommand.COMMAND_ID: ((PutMapCommand) c).init(notifier); break; case RemoveCommand.COMMAND_ID: ((RemoveCommand) c).init(notifier, configuration); break; case MultipleRpcCommand.COMMAND_ID: MultipleRpcCommand rc = (MultipleRpcCommand) c; rc.init(interceptorChain, icf); if (rc.getCommands() != null) for (ReplicableCommand nested : rc.getCommands()) { initializeReplicableCommand(nested, false); } break; case SingleRpcCommand.COMMAND_ID: SingleRpcCommand src = (SingleRpcCommand) c; src.init(interceptorChain, icf); if (src.getCommand() != null) initializeReplicableCommand(src.getCommand(), false); break; case InvalidateCommand.COMMAND_ID: InvalidateCommand ic = (InvalidateCommand) c; ic.init(notifier, configuration); break; case InvalidateL1Command.COMMAND_ID: InvalidateL1Command ilc = (InvalidateL1Command) c; ilc.init(configuration, distributionManager, notifier, dataContainer); break; case PrepareCommand.COMMAND_ID: case VersionedPrepareCommand.COMMAND_ID: case TotalOrderNonVersionedPrepareCommand.COMMAND_ID: case TotalOrderVersionedPrepareCommand.COMMAND_ID: PrepareCommand pc = (PrepareCommand) c; pc.init(interceptorChain, icf, txTable); pc.initialize(notifier, recoveryManager); if (pc.getModifications() != null) for (ReplicableCommand nested : pc.getModifications()) { initializeReplicableCommand(nested, false); } pc.markTransactionAsRemote(isRemote); if (configuration.deadlockDetection().enabled() && isRemote) { DldGlobalTransaction transaction = (DldGlobalTransaction) pc.getGlobalTransaction(); transaction.setLocksHeldAtOrigin(pc.getAffectedKeys()); } break; case CommitCommand.COMMAND_ID: case VersionedCommitCommand.COMMAND_ID: case TotalOrderCommitCommand.COMMAND_ID: case TotalOrderVersionedCommitCommand.COMMAND_ID: CommitCommand commitCommand = (CommitCommand) c; commitCommand.init(interceptorChain, icf, txTable); commitCommand.markTransactionAsRemote(isRemote); break; case RollbackCommand.COMMAND_ID: case TotalOrderRollbackCommand.COMMAND_ID: RollbackCommand rollbackCommand = (RollbackCommand) c; rollbackCommand.init(interceptorChain, icf, txTable); rollbackCommand.markTransactionAsRemote(isRemote); break; case ClearCommand.COMMAND_ID: ClearCommand cc = (ClearCommand) c; cc.init(notifier, dataContainer); break; case ClusteredGetCommand.COMMAND_ID: ClusteredGetCommand clusteredGetCommand = (ClusteredGetCommand) c; clusteredGetCommand.initialize( icf, this, entryFactory, interceptorChain, distributionManager, txTable, configuration.dataContainer().keyEquivalence()); break; case LockControlCommand.COMMAND_ID: LockControlCommand lcc = (LockControlCommand) c; lcc.init(interceptorChain, icf, txTable); lcc.markTransactionAsRemote(isRemote); if (configuration.deadlockDetection().enabled() && isRemote) { DldGlobalTransaction gtx = (DldGlobalTransaction) lcc.getGlobalTransaction(); RemoteTransaction transaction = txTable.getRemoteTransaction(gtx); if (transaction != null) { if (!configuration.clustering().cacheMode().isDistributed()) { Set<Object> keys = txTable.getLockedKeysForRemoteTransaction(gtx); GlobalTransaction gtx2 = transaction.getGlobalTransaction(); ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(keys); gtx.setLocksHeldAtOrigin(keys); } else { GlobalTransaction gtx2 = transaction.getGlobalTransaction(); ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(gtx.getLocksHeldAtOrigin()); } } } break; case StateRequestCommand.COMMAND_ID: ((StateRequestCommand) c).init(stateProvider); break; case StateResponseCommand.COMMAND_ID: ((StateResponseCommand) c).init(stateConsumer); break; case GetInDoubtTransactionsCommand.COMMAND_ID: GetInDoubtTransactionsCommand gptx = (GetInDoubtTransactionsCommand) c; gptx.init(recoveryManager); break; case TxCompletionNotificationCommand.COMMAND_ID: TxCompletionNotificationCommand ftx = (TxCompletionNotificationCommand) c; ftx.init(txTable, lockManager, recoveryManager, stateTransferManager); break; case MapCombineCommand.COMMAND_ID: MapCombineCommand mrc = (MapCombineCommand) c; mrc.init(mapReduceManager); break; case ReduceCommand.COMMAND_ID: ReduceCommand reduceCommand = (ReduceCommand) c; reduceCommand.init(mapReduceManager); break; case DistributedExecuteCommand.COMMAND_ID: DistributedExecuteCommand dec = (DistributedExecuteCommand) c; dec.init(cache); break; case GetInDoubtTxInfoCommand.COMMAND_ID: GetInDoubtTxInfoCommand gidTxInfoCommand = (GetInDoubtTxInfoCommand) c; gidTxInfoCommand.init(recoveryManager); break; case CompleteTransactionCommand.COMMAND_ID: CompleteTransactionCommand ccc = (CompleteTransactionCommand) c; ccc.init(recoveryManager); break; case ApplyDeltaCommand.COMMAND_ID: break; case CreateCacheCommand.COMMAND_ID: CreateCacheCommand createCacheCommand = (CreateCacheCommand) c; createCacheCommand.init(cache.getCacheManager()); break; case XSiteAdminCommand.COMMAND_ID: XSiteAdminCommand xSiteAdminCommand = (XSiteAdminCommand) c; xSiteAdminCommand.init(backupSender); break; case CancelCommand.COMMAND_ID: CancelCommand cancelCommand = (CancelCommand) c; cancelCommand.init(cancellationService); break; case XSiteStateTransferControlCommand.COMMAND_ID: XSiteStateTransferControlCommand xSiteStateTransferControlCommand = (XSiteStateTransferControlCommand) c; xSiteStateTransferControlCommand.initialize( xSiteStateProvider, xSiteStateConsumer, xSiteStateTransferManager); break; case XSiteStatePushCommand.COMMAND_ID: XSiteStatePushCommand xSiteStatePushCommand = (XSiteStatePushCommand) c; xSiteStatePushCommand.initialize(xSiteStateConsumer); break; case EntryRequestCommand.COMMAND_ID: EntryRequestCommand entryRequestCommand = (EntryRequestCommand) c; entryRequestCommand.init(entryRetriever); break; case EntryResponseCommand.COMMAND_ID: EntryResponseCommand entryResponseCommand = (EntryResponseCommand) c; entryResponseCommand.init(entryRetriever); break; case GetKeysInGroupCommand.COMMAND_ID: GetKeysInGroupCommand getKeysInGroupCommand = (GetKeysInGroupCommand) c; getKeysInGroupCommand.setGroupManager(groupManager); break; case ClusteredGetAllCommand.COMMAND_ID: ClusteredGetAllCommand clusteredGetAllCommand = (ClusteredGetAllCommand) c; clusteredGetAllCommand.init( icf, this, entryFactory, interceptorChain, txTable, configuration.dataContainer().keyEquivalence()); break; case StreamRequestCommand.COMMAND_ID: StreamRequestCommand streamRequestCommand = (StreamRequestCommand) c; streamRequestCommand.inject(localStreamManager); break; case StreamResponseCommand.COMMAND_ID: StreamResponseCommand streamResponseCommand = (StreamResponseCommand) c; streamResponseCommand.inject(clusterStreamManager); break; case StreamSegmentResponseCommand.COMMAND_ID: StreamSegmentResponseCommand streamSegmentResponseCommand = (StreamSegmentResponseCommand) c; streamSegmentResponseCommand.inject(clusterStreamManager); break; case RemoveExpiredCommand.COMMAND_ID: RemoveExpiredCommand removeExpiredCommand = (RemoveExpiredCommand) c; removeExpiredCommand.init(notifier, configuration); break; default: ModuleCommandInitializer mci = moduleCommandInitializers.get(c.getCommandId()); if (mci != null) { mci.initializeReplicableCommand(c, isRemote); } else { if (trace) log.tracef("Nothing to initialize for command: %s", c); } } }
protected <KIn, VIn, KOut, VOut> Set<KOut> combine( MapCombineCommand<KIn, VIn, KOut, VOut> mcc, CollectableCollector<KOut, VOut> collector) throws Exception { String taskId = mcc.getTaskId(); boolean emitCompositeIntermediateKeys = mcc.isEmitCompositeIntermediateKeys(); Reducer<KOut, VOut> combiner = mcc.getCombiner(); Set<KOut> mapPhaseKeys = new HashSet<KOut>(); Cache<Object, DeltaAwareList<VOut>> tmpCache = null; if (emitCompositeIntermediateKeys) { tmpCache = cacheManager.getCache(DEFAULT_TMP_CACHE_CONFIGURATION_NAME); } else { tmpCache = cacheManager.getCache(taskId); } if (tmpCache == null) { throw new IllegalStateException( "Temporary cache for MapReduceTask " + taskId + " not found on " + cdl.getAddress()); } DistributionManager dm = tmpCache.getAdvancedCache().getDistributionManager(); if (combiner != null) { Cache<?, ?> cache = cacheManager.getCache(mcc.getCacheName()); log.tracef("For m/r task %s invoking combiner %s at %s", taskId, mcc, cdl.getAddress()); MapReduceTaskLifecycleService taskLifecycleService = MapReduceTaskLifecycleService.getInstance(); Map<KOut, VOut> combinedMap = new ConcurrentHashMap<KOut, VOut>(); long start = log.isTraceEnabled() ? timeService.time() : 0; try { taskLifecycleService.onPreExecute(combiner, cache); Map<KOut, List<VOut>> collectedValues = collector.collectedValues(); for (Entry<KOut, List<VOut>> e : collectedValues.entrySet()) { List<VOut> list = e.getValue(); VOut combined; if (list.size() > 1) { combined = combiner.reduce(e.getKey(), list.iterator()); combinedMap.put(e.getKey(), combined); } else { combined = list.get(0); combinedMap.put(e.getKey(), combined); } log.tracef( "For m/r task %s combined %s to %s at %s", taskId, e.getKey(), combined, cdl.getAddress()); } } finally { if (log.isTraceEnabled()) { log.tracef( "Combine for task %s took %s milliseconds", mcc.getTaskId(), timeService.timeDuration(start, TimeUnit.MILLISECONDS)); } taskLifecycleService.onPostExecute(combiner); } Map<Address, List<KOut>> keysToNodes = mapKeysToNodes(dm, taskId, combinedMap.keySet(), emitCompositeIntermediateKeys); start = log.isTraceEnabled() ? timeService.time() : 0; try { for (Entry<Address, List<KOut>> entry : keysToNodes.entrySet()) { List<KOut> keysHashedToAddress = entry.getValue(); try { log.tracef( "For m/r task %s migrating intermediate keys %s to %s", taskId, keysHashedToAddress, entry.getKey()); for (KOut key : keysHashedToAddress) { VOut value = combinedMap.get(key); DeltaAwareList<VOut> delta = new DeltaAwareList<VOut>(value); if (emitCompositeIntermediateKeys) { tmpCache.put(new IntermediateCompositeKey<KOut>(taskId, key), delta); } else { tmpCache.put(key, delta); } mapPhaseKeys.add(key); } } catch (Exception e) { throw new CacheException( "Could not move intermediate keys/values for M/R task " + taskId, e); } } } finally { if (log.isTraceEnabled()) { log.tracef( "Migrating keys for task %s took %s milliseconds (Migrated %s keys)", mcc.getTaskId(), timeService.timeDuration(start, TimeUnit.MILLISECONDS), mapPhaseKeys.size()); } } } else { // Combiner not specified so lets insert each key/uncombined-List pair into tmp cache Map<KOut, List<VOut>> collectedValues = collector.collectedValues(); Map<Address, List<KOut>> keysToNodes = mapKeysToNodes(dm, taskId, collectedValues.keySet(), emitCompositeIntermediateKeys); long start = log.isTraceEnabled() ? timeService.time() : 0; try { for (Entry<Address, List<KOut>> entry : keysToNodes.entrySet()) { List<KOut> keysHashedToAddress = entry.getValue(); try { log.tracef( "For m/r task %s migrating intermediate keys %s to %s", taskId, keysHashedToAddress, entry.getKey()); for (KOut key : keysHashedToAddress) { List<VOut> value = collectedValues.get(key); DeltaAwareList<VOut> delta = new DeltaAwareList<VOut>(value); if (emitCompositeIntermediateKeys) { tmpCache.put(new IntermediateCompositeKey<KOut>(taskId, key), delta); } else { tmpCache.put(key, delta); } mapPhaseKeys.add(key); } } catch (Exception e) { throw new CacheException( "Could not move intermediate keys/values for M/R task " + taskId, e); } } } finally { if (log.isTraceEnabled()) { log.tracef( "Migrating keys for task %s took %s milliseconds (Migrated %s keys)", mcc.getTaskId(), timeService.timeDuration(start, TimeUnit.MILLISECONDS), mapPhaseKeys.size()); } } } return mapPhaseKeys; }
protected <KIn, VIn, KOut, VOut> CollectableCollector<KOut, VOut> map( MapCombineCommand<KIn, VIn, KOut, VOut> mcc) throws InterruptedException { Cache<KIn, VIn> cache = cacheManager.getCache(mcc.getCacheName()); Set<KIn> keys = mcc.getKeys(); Set<KIn> inputKeysCopy = null; Mapper<KIn, VIn, KOut, VOut> mapper = mcc.getMapper(); DistributionManager dm = cache.getAdvancedCache().getDistributionManager(); boolean inputKeysSpecified = keys != null && !keys.isEmpty(); Set<KIn> inputKeys = keys; if (!inputKeysSpecified) { inputKeys = filterLocalPrimaryOwner(cache.keySet(), dm); } else { inputKeysCopy = new HashSet<KIn>(keys); } // hook map function into lifecycle and execute it MapReduceTaskLifecycleService taskLifecycleService = MapReduceTaskLifecycleService.getInstance(); DefaultCollector<KOut, VOut> collector = new DefaultCollector<KOut, VOut>(); log.tracef("For m/r task %s invoking %s with input keys %s", mcc.getTaskId(), mcc, inputKeys); int interruptCount = 0; long start = log.isTraceEnabled() ? timeService.time() : 0; try { taskLifecycleService.onPreExecute(mapper, cache); for (KIn key : inputKeys) { if (checkInterrupt(interruptCount++) && Thread.currentThread().isInterrupted()) throw new InterruptedException(); VIn value = cache.get(key); mapper.map(key, value, collector); if (inputKeysSpecified) { inputKeysCopy.remove(key); } } Set<KIn> keysFromCacheLoader = null; if (inputKeysSpecified) { // load only specified remaining input keys - iff in CL and pinned to this primary owner keysFromCacheLoader = filterLocalPrimaryOwner(inputKeysCopy, dm); } else { // load everything from CL pinned to this primary owner keysFromCacheLoader = filterLocalPrimaryOwner(loadAllKeysFromCacheLoaderUsingFilter(inputKeys), dm); } log.tracef( "For m/r task %s cache loader input keys %s", mcc.getTaskId(), keysFromCacheLoader); interruptCount = 0; for (KIn key : keysFromCacheLoader) { if (checkInterrupt(interruptCount++) && Thread.currentThread().isInterrupted()) throw new InterruptedException(); VIn value = loadValueFromCacheLoader(key); if (value != null) { mapper.map(key, value, collector); } } } finally { if (log.isTraceEnabled()) { log.tracef( "Map phase for task %s took %s milliseconds", mcc.getTaskId(), timeService.timeDuration(start, TimeUnit.MILLISECONDS)); } taskLifecycleService.onPostExecute(mapper); } return collector; }