Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndex.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndex.java (date 1412352606000)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedIndex.java (revision )
@@ -124,25 +124,29 @@
* the default direction for sorting the index
*/
OrderDirection DEFAULT_DIRECTION = OrderDirection.ASC;
-
+
+
/**
- * defines the default distribution of items across the skip list. It's with a factor of 10%
+ * Defines the distribution of items across the skip list. With a factor of 25%
* having therefore
- *
+ *
*
* - lane 0:
- 100.0% (the base linked list)
- * - lane 1:
- 10.0%
- * - lane 2:
- 1.0%
- * - lane 3:
- 0.1%
+ * - lane 1:
- 25.0%
+ * - lane 2:
- 6.25%
+ * - lane 3:
- 1.56%
+ * - ------
*
*/
double DEFAULT_PROBABILITY = 0.1;
+ double PROBABILITY = Double.valueOf(
+ System.getProperty("oak.ordered.skip.prob", String.valueOf(DEFAULT_PROBABILITY)).trim());
-
+
/**
- * the number of lanes used in the SkipList
+ * the number of lanes used in the SkipList. The default is 32
*/
- int LANES = 4;
+ int LANES = Integer.getInteger("oak.ordered.skip.lanes", 32);
-
+
/**
* Convenience Predicate that will force the implementor to expose what we're searching for
*
Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java (date 1412352606000)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/OrderedContentMirrorStoreStrategy.java (revision )
@@ -23,6 +23,7 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
@@ -33,6 +34,7 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import com.google.common.collect.ImmutableList;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.property.OrderedIndex;
@@ -51,7 +53,6 @@
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -73,7 +74,7 @@
/**
* convenience property for initialising an empty multi-value :next
*/
- public static final Iterable EMPTY_NEXT = ImmutableList.of("", "", "", "");
+ public static final Iterable EMPTY_NEXT = ImmutableList.of("");
/**
* convenience property that represent an empty :next as array
@@ -117,10 +118,10 @@
private static void printWalkedLanes(final String msg, final String[] walked) {
String m = (msg == null) ? "" : msg;
if (walked == null) {
- LOG.debug(m + " walked: null");
+ LOG.trace(m + " walked: null");
} else {
for (int i = 0; i < walked.length; i++) {
- LOG.debug("{}walked[{}]: {}", new Object[] { m, i, walked[i] });
+ LOG.trace("{}walked[{}]: {}", new Object[] {m, i, walked[i]});
}
}
}
@@ -144,8 +145,8 @@
// we use the seek for seeking the right spot. The walkedLanes will have all our
// predecessors
String entry = seek(index, condition, walked);
- if (LOG.isDebugEnabled()) {
- LOG.debug("fetchKeyNode() - entry: {} ", entry);
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("fetchKeyNode() - entry: {} ", entry);
printWalkedLanes("fetchKeyNode() - ", walked);
}
@@ -162,10 +163,12 @@
LOG.debug("fetchKeyNode() - extracted lane: {}", lane);
String next;
NodeBuilder predecessor;
+ List vals;
for (int l = lane; l >= 0; l--) {
+ vals = Lists.newArrayList();
// let's update the predecessors starting from the coin-flip lane
predecessor = index.getChildNode(walked[l]);
- next = getPropertyNext(predecessor, l);
+ next = getPropertyNext(predecessor, vals, l);
setPropertyNext(predecessor, key, l);
setPropertyNext(node, next, l);
if (LOG.isDebugEnabled()) {
@@ -834,7 +837,9 @@
int lane;
boolean stillLaning;
- String nextkey;
+ String nextkey;
+ NodeBuilder currentKeyNode = index.getChildNode(currentKey);
+ List vals = Lists.newArrayList();
if ((direction.isAscending() && condition instanceof PredicateLessThan)
|| (direction.isDescending() && condition instanceof PredicateGreaterThan)) {
@@ -846,7 +851,7 @@
lane = 0;
do {
stillLaning = lane < OrderedIndex.LANES;
- nextkey = getPropertyNext(index.getChildNode(currentKey), lane);
+ nextkey = getPropertyNext(currentKeyNode, vals, lane);
if ((Strings.isNullOrEmpty(nextkey) || !walkingPredicate.apply(nextkey)) && lane < OrderedIndex.LANES) {
// if we're currently pointing to NIL or the next element does not fit the search
// but we still have lanes left
@@ -856,6 +861,10 @@
found = nextkey;
} else {
currentKey = nextkey;
+ vals = Lists.newArrayList();
+ if (!Strings.isNullOrEmpty(currentKey)) {
+ currentKeyNode = index.getChildNode(currentKey);
+ }
if (keepWalked && !Strings.isNullOrEmpty(currentKey)) {
walkedLanes[lane] = currentKey;
}
@@ -869,7 +878,7 @@
do {
stillLaning = lane > 0;
- nextkey = getPropertyNext(index.getChildNode(currentKey), lane);
+ nextkey = getPropertyNext(currentKeyNode, vals, lane);
if ((Strings.isNullOrEmpty(nextkey) || !walkingPredicate.apply(nextkey)) && lane > 0) {
// if we're currently pointing to NIL or the next element does not fit the search
// but we still have lanes left, let's lower the lane;
@@ -879,6 +888,10 @@
found = nextkey;
} else {
currentKey = nextkey;
+ vals = Lists.newArrayList();
+ if (!Strings.isNullOrEmpty(currentKey)) {
+ currentKeyNode = index.getChildNode(currentKey);
+ }
if (keepWalked && !Strings.isNullOrEmpty(currentKey)) {
for (int l = lane; l >= 0; l--) {
walkedLanes[l] = currentKey;
@@ -1071,12 +1084,7 @@
*/
static void setPropertyNext(@Nonnull final NodeBuilder node, final String... next) {
if (node != null && next != null) {
- String n1 = (next.length > 0) ? next[0] : "";
- String n2 = (next.length > 1) ? next[1] : "";
- String n3 = (next.length > 2) ? next[2] : "";
- String n4 = (next.length > 3) ? next[3] : "";
-
- node.setProperty(NEXT, ImmutableList.of(n1, n2, n3, n4), Type.STRINGS);
+ node.setProperty(NEXT, Arrays.asList(next), Type.STRINGS);
}
}
@@ -1096,12 +1104,12 @@
String[] values;
if (next.isArray()) {
values = Iterables.toArray(next.getValue(Type.STRINGS), String.class);
- if (values.length < OrderedIndex.LANES) {
+ if (values.length < lane + 1) {
// it could be we increased the number of lanes and running on some existing
// content
LOG.debug("topping-up the number of lanes.");
List vv = Lists.newArrayList(values);
- for (int i = vv.size(); i <= OrderedIndex.LANES; i++) {
+ for (int i = vv.size(); i <= lane; i++) {
vv.add("");
}
values = vv.toArray(new String[vv.size()]);
@@ -1159,6 +1167,38 @@
}
/**
+ * short-cut for using NodeBuilder. See {@code getNext(NodeState)}
+ */
+ String getPropertyNext(@Nonnull final NodeBuilder node, List vals, final int lane) {
+ checkNotNull(node);
+
+ String next = "";
+
+ if (vals.isEmpty()) {
+ PropertyState ps = node.getProperty(NEXT);
+ if (ps != null) {
+ if (ps.isArray()) {
+ Iterable values = ps.getValue(Type.STRINGS);
+ Iterables.addAll(vals, values);
+ if (vals.size() > lane) {
+ next = vals.get(Math.min(vals.size() - 1, lane));
+ }
+ } else {
+ next = ps.getValue(Type.STRING);
+ if (next != null) {
+ vals.set(0, next);
+ }
+ }
+ }
+ } else {
+ if (vals.size() > lane) {
+ next = vals.get(Math.min(vals.size() - 1, lane));
+ }
+ }
+ return next;
+ }
+
+ /**
* retrieve the lane to be updated based on probabilistic approach.
*
* Having 4 lanes if we have the 3 to be updated it means we'll have to update lanes
@@ -1168,7 +1208,7 @@
*
* It uses {@code getLane(Random)} by passing a {@code new Random(System.currentTimeMillis())}
*
- * @see OrderedIndex.DEFAULT_PROBABILITY
+ * @see OrderedIndex.PROBABILITY
*
* @return the lane to start updating from.
*/
@@ -1186,10 +1226,10 @@
final int maxLanes = OrderedIndex.LANES - 1;
int lane = 0;
- while (rnd.nextDouble() < OrderedIndex.DEFAULT_PROBABILITY && lane < maxLanes) {
+ while (rnd.nextDouble() < OrderedIndex.PROBABILITY && lane < maxLanes) {
lane++;
}
return lane;
}
-}
\ No newline at end of file
+}