diff --git a/src/main/java/net/spy/memcached/internal/result/SMGetResult.java b/src/main/java/net/spy/memcached/internal/result/SMGetResult.java index 6689ee297..262ae1f20 100644 --- a/src/main/java/net/spy/memcached/internal/result/SMGetResult.java +++ b/src/main/java/net/spy/memcached/internal/result/SMGetResult.java @@ -16,9 +16,9 @@ public abstract class SMGetResult { protected final List missedKeyList; protected final Map missedKeyMap; - protected final List mergedTrimmedKeys; + protected volatile List mergedTrimmedKeys; - protected final List> mergedResult; + protected volatile List> mergedResult; protected volatile CollectionOperationStatus resultOperationStatus = null; protected volatile CollectionOperationStatus failedOperationStatus = null; diff --git a/src/main/java/net/spy/memcached/internal/result/SMGetResultImpl.java b/src/main/java/net/spy/memcached/internal/result/SMGetResultImpl.java index be73096ac..b3724f375 100644 --- a/src/main/java/net/spy/memcached/internal/result/SMGetResultImpl.java +++ b/src/main/java/net/spy/memcached/internal/result/SMGetResultImpl.java @@ -1,5 +1,6 @@ package net.spy.memcached.internal.result; +import java.util.ArrayList; import java.util.List; import net.spy.memcached.collection.SMGetElement; @@ -98,6 +99,68 @@ private void mergeSMGetElements(final List> eachResult) { } } + private void mergeSMGetElements2(final List> eachResult) { + if (mergedResult.isEmpty()) { + // merged result is empty, add all. + mergedResult.addAll(eachResult); + + while (mergedResult.size() > count) { + mergedResult.remove(count); + } + return; + } + + final int eachSize = eachResult.size(); + final int mergedSize = mergedResult.size(); + final List> newMergedResult = new ArrayList>(count); + + int eachPos = 0, mergedPos = 0; + int comp, keyComp; + + while (eachPos < eachSize && mergedPos < mergedSize && newMergedResult.size() < count) { + final SMGetElement each = eachResult.get(eachPos); + final SMGetElement merged = mergedResult.get(mergedPos); + + comp = each.compareBkeyTo(merged); + if ((reverse) ? (comp > 0) : (comp < 0)) { + newMergedResult.add(each); + eachPos++; + } else if ((reverse) ? (comp < 0) : (comp > 0)) { + newMergedResult.add(merged); + mergedPos++; + } else { + // Duplicated bkey. Compare the "cache key". + keyComp = each.compareKeyTo(merged); + if ((reverse) ? (keyComp > 0) : (keyComp < 0)) { + newMergedResult.add(each); + eachPos++; + + if (unique) { + // NOT the first cache key with the same bkey. do NOT insert. + mergedPos++; + } + } else { + newMergedResult.add(merged); + mergedPos++; + + if (unique) { + // NOT the first cache key with the same bkey. do NOT insert. + eachPos++; + } + } + } + } + + while (eachPos < eachSize && newMergedResult.size() < count) { + newMergedResult.add(eachResult.get(eachPos++)); + } + while (mergedPos < mergedSize && newMergedResult.size() < count) { + newMergedResult.add(mergedResult.get(mergedPos++)); + } + + mergedResult = newMergedResult; + } + private void mergeTrimmedKeys(final List eachTrimmedResult) { if (mergedTrimmedKeys.isEmpty()) { mergedTrimmedKeys.addAll(eachTrimmedResult); @@ -118,6 +181,47 @@ private void mergeTrimmedKeys(final List eachTrimmedResult) { } } + private void mergeTrimmedKeys2(final List eachTrimmedResult) { + if (mergedTrimmedKeys.isEmpty()) { + mergedTrimmedKeys.addAll(eachTrimmedResult); + return; + } + + final int eachSize = eachTrimmedResult.size(); + final int mergedSize = mergedTrimmedKeys.size(); + final List newMergedTrimmedKeys + = new ArrayList(eachSize + mergedSize); + + int eachPos = 0, mergedPos = 0; + int comp; + + while (eachPos < eachSize && mergedPos < mergedSize) { + final SMGetTrimKey each = eachTrimmedResult.get(eachPos); + final SMGetTrimKey merged = mergedTrimmedKeys.get(mergedPos); + + comp = each.compareTo(merged); + if ((reverse) ? (comp > 0) : (comp < 0)) { + newMergedTrimmedKeys.add(each); + eachPos++; + } else if ((reverse) ? (comp < 0) : (comp > 0)) { + newMergedTrimmedKeys.add(merged); + mergedPos++; + } else { + // comp == 0; + mergedPos++; + } + } + + while (eachPos < eachSize) { + newMergedTrimmedKeys.add(eachTrimmedResult.get(eachPos++)); + } + while (mergedPos < mergedSize) { + newMergedTrimmedKeys.add(mergedTrimmedKeys.get(mergedPos++)); + } + + mergedTrimmedKeys = newMergedTrimmedKeys; + } + @Override public void makeResultOperationStatus() { if (!mergedTrimmedKeys.isEmpty() && count <= mergedResult.size()) {