Skip to content

Commit c63b138

Browse files
committed
even faster
1 parent 584a3d1 commit c63b138

4 files changed

Lines changed: 95 additions & 10 deletions

File tree

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbCachedFrontier.java

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,52 @@ long countAt(int index) {
4747
}
4848

4949
int seek(long target) {
50-
int index = Arrays.binarySearch(values, target);
51-
return index >= 0 ? index : -index - 1;
50+
return lowerBound(values, target, -1);
51+
}
52+
53+
int seek(long target, int hintIndex) {
54+
return lowerBound(values, target, hintIndex);
5255
}
5356

5457
long countFor(long value) {
58+
int index = lowerBound(values, value, -1);
59+
if (index >= values.length || values[index] != value) {
60+
return 0L;
61+
}
5562
if (counts == null) {
56-
int index = Arrays.binarySearch(values, value);
57-
return index >= 0 ? 1L : 0L;
63+
return 1L;
64+
}
65+
return counts[index];
66+
}
67+
68+
static int lowerBound(long[] values, long target, int hintIndex) {
69+
if (hintIndex < 0 || hintIndex >= values.length) {
70+
int index = Arrays.binarySearch(values, target);
71+
return index >= 0 ? index : -index - 1;
5872
}
5973

60-
int index = Arrays.binarySearch(values, value);
61-
return index >= 0 ? counts[index] : 0L;
74+
long hintValue = values[hintIndex];
75+
if (hintValue == target) {
76+
return hintIndex;
77+
}
78+
79+
if (hintValue < target) {
80+
int nextIndex = hintIndex + 1;
81+
if (nextIndex >= values.length) {
82+
return values.length;
83+
}
84+
if (values[nextIndex] >= target) {
85+
return nextIndex;
86+
}
87+
int index = Arrays.binarySearch(values, nextIndex + 1, values.length, target);
88+
return index >= 0 ? index : -index - 1;
89+
}
90+
91+
int previousIndex = hintIndex - 1;
92+
if (previousIndex >= 0 && values[previousIndex] < target) {
93+
return hintIndex;
94+
}
95+
int index = Arrays.binarySearch(values, 0, hintIndex, target);
96+
return index >= 0 ? index : -index - 1;
6297
}
6398
}

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbCachedTrieCursor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public boolean seek(long target) {
4848
}
4949

5050
Frame frame = currentFrame();
51-
int position = frame.frontier.seek(target);
51+
int position = frame.frontier.seek(target, frame.position);
5252
if (position >= frame.frontier.size()) {
5353
frame.position = -1;
5454
return false;

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/LmdbLftjFullCodegenCompiler.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,11 @@ private void appendRelationFrontierMethods(StringBuilder source, int patternOrdi
635635
source.append(" return seekSlot").append(suffix).append("(0L);\n");
636636
source.append(" }\n\n");
637637
source.append(" private boolean seekSlot").append(suffix).append("(long target) {\n");
638+
source.append(" long[] previousFrontierValues")
639+
.append(suffix)
640+
.append(" = frontierValues")
641+
.append(suffix)
642+
.append(";\n");
638643
if (component == patternShape.derivedSourceComponent()) {
639644
source.append(" frontierValues")
640645
.append(suffix)
@@ -653,7 +658,15 @@ private void appendRelationFrontierMethods(StringBuilder source, int patternOrdi
653658
.append(suffix)
654659
.append(" = seekFrontier(frontierValues")
655660
.append(suffix)
656-
.append(", target);\n");
661+
.append(", target, frontierAvailable")
662+
.append(suffix)
663+
.append(" && frontierValues")
664+
.append(suffix)
665+
.append(" == previousFrontierValues")
666+
.append(suffix)
667+
.append(" ? frontierIndex")
668+
.append(suffix)
669+
.append(" : -1);\n");
657670
source.append(" if (frontierIndex")
658671
.append(suffix)
659672
.append(" >= frontierValues")
@@ -1163,8 +1176,32 @@ private void appendCloseCursorResources(StringBuilder source, int patternOrdinal
11631176
private void appendHelpers(StringBuilder source) {
11641177
source.append(" private static final long[] EMPTY_FRONTIER_VALUES = new long[0];\n\n");
11651178
if (relationGroups.length > 0) {
1166-
source.append(" private static int seekFrontier(long[] values, long target) {\n");
1167-
source.append(" int index = java.util.Arrays.binarySearch(values, target);\n");
1179+
source.append(" private static int seekFrontier(long[] values, long target, int hintIndex) {\n");
1180+
source.append(" if (hintIndex < 0 || hintIndex >= values.length) {\n");
1181+
source.append(" int index = java.util.Arrays.binarySearch(values, target);\n");
1182+
source.append(" return index >= 0 ? index : -index - 1;\n");
1183+
source.append(" }\n");
1184+
source.append(" long hintValue = values[hintIndex];\n");
1185+
source.append(" if (hintValue == target) {\n");
1186+
source.append(" return hintIndex;\n");
1187+
source.append(" }\n");
1188+
source.append(" if (hintValue < target) {\n");
1189+
source.append(" int nextIndex = hintIndex + 1;\n");
1190+
source.append(" if (nextIndex >= values.length) {\n");
1191+
source.append(" return values.length;\n");
1192+
source.append(" }\n");
1193+
source.append(" if (values[nextIndex] >= target) {\n");
1194+
source.append(" return nextIndex;\n");
1195+
source.append(" }\n");
1196+
source.append(
1197+
" int index = java.util.Arrays.binarySearch(values, nextIndex + 1, values.length, target);\n");
1198+
source.append(" return index >= 0 ? index : -index - 1;\n");
1199+
source.append(" }\n");
1200+
source.append(" int previousIndex = hintIndex - 1;\n");
1201+
source.append(" if (previousIndex >= 0 && values[previousIndex] < target) {\n");
1202+
source.append(" return hintIndex;\n");
1203+
source.append(" }\n");
1204+
source.append(" int index = java.util.Arrays.binarySearch(values, 0, hintIndex, target);\n");
11681205
source.append(" return index >= 0 ? index : -index - 1;\n");
11691206
source.append(" }\n\n");
11701207
source.append(" private static int mixFrontierCacheKey(long value) {\n");

core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/FoafCliqueQueryBenchmarkResults.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,16 @@ FoafCliqueQueryBenchmark.cycle5ValuesDistinctMailboxOrdered executor_codegen
103103
FoafCliqueQueryBenchmark.cycle5ValuesDistinctMailboxOrdered full_codegen 30 8 3 5000 15000 12345 avgt 5 455.503 ± 20.033 ms/op
104104
FoafCliqueQueryBenchmark.cycle5ValuesDistinctMailboxOrdered disabled 30 8 3 5000 15000 12345 avgt 5 2165.313 ± 74.562 ms/op
105105
```
106+
107+
```
108+
Benchmark (benchmarkMode) (cliquePercentage) (maxCliqueSize) (minCliqueSize) (peopleCount) (randomKnowsEdges) (seed) Mode Cnt Score Error Units
109+
FoafCliqueQueryBenchmark.cycle3 full_codegen 30 8 3 5000 15000 12345 avgt 5 12.145 ± 0.697 ms/op
110+
FoafCliqueQueryBenchmark.cycle3CountCityInterest full_codegen 30 8 3 5000 15000 12345 avgt 5 36.130 ± 2.730 ms/op
111+
FoafCliqueQueryBenchmark.cycle3DistinctCityOrdered full_codegen 30 8 3 5000 15000 12345 avgt 5 90.575 ± 8.376 ms/op
112+
FoafCliqueQueryBenchmark.cycle3GroupedInterest full_codegen 30 8 3 5000 15000 12345 avgt 5 33.409 ± 2.409 ms/op
113+
FoafCliqueQueryBenchmark.cycle4 full_codegen 30 8 3 5000 15000 12345 avgt 5 54.210 ± 3.619 ms/op
114+
FoafCliqueQueryBenchmark.cycle4ValuesFilteredOrdered full_codegen 30 8 3 5000 15000 12345 avgt 5 145.352 ± 11.220 ms/op
115+
FoafCliqueQueryBenchmark.cycle5 full_codegen 30 8 3 5000 15000 12345 avgt 5 255.649 ± 11.363 ms/op
116+
FoafCliqueQueryBenchmark.cycle5ValuesCountMailboxHomepage full_codegen 30 8 3 5000 15000 12345 avgt 5 1088.888 ± 24.557 ms/op
117+
FoafCliqueQueryBenchmark.cycle5ValuesDistinctMailboxOrdered full_codegen 30 8 3 5000 15000 12345 avgt 5 437.191 ± 53.469 ms/op
118+
```

0 commit comments

Comments
 (0)