public void execute(Pipeline pipeline) {
Map<ByteArray, List<Versioned<byte[]>>> result = pipelineData.getResult();
for(ByteArray key: keys) {
boolean zoneRequirement = false;
MutableInt successCount = pipelineData.getSuccessCount(key);
if(logger.isDebugEnabled())
logger.debug("GETALL for key " + ByteUtils.toHexString(key.get()) + " (keyRef: "
+ System.identityHashCode(key) + ") successes: "
+ successCount.intValue() + " preferred: " + preferred + " required: "
+ required);
if(successCount.intValue() >= preferred) {
if(pipelineData.getZonesRequired() != null && pipelineData.getZonesRequired() > 0) {
if(pipelineData.getKeyToZoneResponse().containsKey(key)) {
int zonesSatisfied = pipelineData.getKeyToZoneResponse().get(key).size();
if(zonesSatisfied >= (pipelineData.getZonesRequired() + 1)) {
continue;
} else {
zoneRequirement = true;
}
} else {
zoneRequirement = true;
}
} else {
continue;
}
}
List<Node> extraNodes = pipelineData.getKeyToExtraNodesMap().get(key);
Map<ByteArray, byte[]> transforms = pipelineData.getTransforms();
if(extraNodes == null)
continue;
for(Node node: extraNodes) {
long start = System.nanoTime();
try {
Store<ByteArray, byte[], byte[]> store = stores.get(node.getId());
List<Versioned<byte[]>> values;
if(transforms == null)
values = store.get(key, null);
else
values = store.get(key, transforms.get(key));
if(values.size() != 0) {
if(result.get(key) == null)
result.put(key, Lists.newArrayList(values));
else
result.get(key).addAll(values);
}
Map<ByteArray, List<Versioned<byte[]>>> map = new HashMap<ByteArray, List<Versioned<byte[]>>>();
map.put(key, values);
Response<Iterable<ByteArray>, Map<ByteArray, List<Versioned<byte[]>>>> response = new Response<Iterable<ByteArray>, Map<ByteArray, List<Versioned<byte[]>>>>(node,
Arrays.asList(key),
map,
((System.nanoTime() - start) / Time.NS_PER_MS));
successCount.increment();
pipelineData.getResponses().add(response);
failureDetector.recordSuccess(response.getNode(), response.getRequestTime());
if(logger.isDebugEnabled())
logger.debug("GET for key " + ByteUtils.toHexString(key.get())
+ " (keyRef: " + System.identityHashCode(key)
+ ") successes: " + successCount.intValue() + " preferred: "
+ preferred + " required: " + required
+ " new GET success on node " + node.getId());
HashSet<Integer> zoneResponses = null;
if(pipelineData.getKeyToZoneResponse().containsKey(key)) {
zoneResponses = pipelineData.getKeyToZoneResponse().get(key);
} else {
zoneResponses = new HashSet<Integer>();
pipelineData.getKeyToZoneResponse().put(key, zoneResponses);
}
zoneResponses.add(response.getNode().getZoneId());
if(zoneRequirement) {
if(zoneResponses.size() >= pipelineData.getZonesRequired())
break;
} else {
if(successCount.intValue() >= preferred)
break;
}
} catch(Exception e) {
long requestTime = (System.nanoTime() - start) / Time.NS_PER_MS;
if(handleResponseError(e, node, requestTime, pipeline, failureDetector))
return;
}
}
}
for(ByteArray key: keys) {
MutableInt successCount = pipelineData.getSuccessCount(key);
if(successCount.intValue() < required) {
// if we allow partial results, then just remove keys that did
// not meet 'required' guarantee; else raise error
if(allowPartial) {
if(logger.isDebugEnabled()) {
logger.debug("Excluding Key " + ByteUtils.toHexString(key.get())
+ " from partial get_all result");
}
result.remove(key);
} else {
pipelineData.setFatalError(new InsufficientOperationalNodesException(required
+ " "
+ pipeline.getOperation()
.getSimpleName()
+ "s required, but "
+ successCount.intValue()
+ " succeeded. Failing nodes : "
+ pipelineData.getFailedNodes(),
pipelineData.getFailures()));
pipeline.addEvent(Event.ERROR);
return;