Skip to content

Commit 7bf7a3a

Browse files
committed
working on new ID based join iterator
1 parent cd96e9b commit 7bf7a3a

File tree

8 files changed

+1578
-257
lines changed

8 files changed

+1578
-257
lines changed

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

Lines changed: 104 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class LmdbRecordIterator implements RecordIterator {
5757

5858
private boolean matchValues;
5959
private GroupMatcher groupMatcher;
60+
private GroupMatcher matcherForEvaluation;
6061

6162
/**
6263
* True when late-bound variables exist beyond the contiguous prefix of the chosen index order, requiring
@@ -131,7 +132,7 @@ void initialize(TripleIndex index, KeyBuilder keyBuilder, boolean rangeSearch, l
131132
long context, boolean explicit, Txn txnRef, long[] quadReuse, ByteBuffer minKeyBufParam,
132133
ByteBuffer maxKeyBufParam) throws IOException {
133134
if (initialized && !closed) {
134-
throw new IllegalStateException("Cannot initialize LMDB record iterator while it is open");
135+
// prepareForReuse();
135136
}
136137
initializeInternal(index, keyBuilder, rangeSearch, subj, pred, obj, context, explicit, txnRef, quadReuse,
137138
minKeyBufParam, maxKeyBufParam);
@@ -141,12 +142,27 @@ void initialize(TripleIndex index, KeyBuilder keyBuilder, boolean rangeSearch, l
141142
private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolean rangeSearch, long subj,
142143
long pred, long obj, long context, boolean explicit, Txn txnRef, long[] quadReuse,
143144
ByteBuffer minKeyBufParam, ByteBuffer maxKeyBufParam) throws IOException {
145+
146+
// if (!initialized) {
147+
// System.out.println();
148+
// } else {
149+
// System.out.println();
150+
// }
151+
144152
this.index = index;
153+
long prevSubj = this.subj;
154+
long prevPred = this.pred;
155+
long prevObj = this.obj;
156+
long prevContext = this.context;
157+
145158
this.subj = subj;
146159
this.pred = pred;
147160
this.obj = obj;
148161
this.context = context;
149162

163+
boolean prevExternalMinKeyBuf = this.externalMinKeyBuf;
164+
boolean prevExternalMaxKeyBuf = this.externalMaxKeyBuf;
165+
150166
if (quadReuse != null && quadReuse.length >= 4) {
151167
this.quad = quadReuse;
152168
} else if (this.quad == null || this.quad.length < 4) {
@@ -166,20 +182,36 @@ private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolea
166182

167183
if (rangeSearch) {
168184
this.externalMinKeyBuf = minKeyBufParam != null;
169-
this.minKeyBuf = externalMinKeyBuf ? minKeyBufParam : pool.getKeyBuffer();
185+
if (externalMinKeyBuf) {
186+
this.minKeyBuf = minKeyBufParam;
187+
} else {
188+
if (this.minKeyBuf == null || prevExternalMinKeyBuf) {
189+
this.minKeyBuf = pool.getKeyBuffer();
190+
} else {
191+
this.minKeyBuf.clear();
192+
}
193+
}
170194
minKeyBuf.clear();
171195
if (keyBuilder != null) {
172196
keyBuilder.writeMin(minKeyBuf);
173197
} else {
174-
index.getMinKey(minKeyBuf, subj, pred, obj, context);
198+
index.getMinKey(minKeyBuf, subj, pred, obj, context, prevSubj, prevPred, prevObj, prevContext);
175199
}
176200
minKeyBuf.flip();
177201

178202
if (this.maxKey == null) {
179203
this.maxKey = pool.getVal();
180204
}
181205
this.externalMaxKeyBuf = maxKeyBufParam != null;
182-
this.maxKeyBuf = externalMaxKeyBuf ? maxKeyBufParam : pool.getKeyBuffer();
206+
if (externalMaxKeyBuf) {
207+
this.maxKeyBuf = maxKeyBufParam;
208+
} else {
209+
if (this.maxKeyBuf == null || prevExternalMaxKeyBuf) {
210+
this.maxKeyBuf = pool.getKeyBuffer();
211+
} else {
212+
this.maxKeyBuf.clear();
213+
}
214+
}
183215
maxKeyBuf.clear();
184216
if (keyBuilder != null) {
185217
keyBuilder.writeMax(maxKeyBuf);
@@ -193,24 +225,38 @@ private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolea
193225
pool.free(maxKey);
194226
this.maxKey = null;
195227
}
196-
if (this.maxKeyBuf != null && !externalMaxKeyBuf) {
228+
if (this.maxKeyBuf != null && !prevExternalMaxKeyBuf) {
197229
pool.free(maxKeyBuf);
230+
this.maxKeyBuf = null;
198231
}
199232
this.externalMaxKeyBuf = maxKeyBufParam != null;
200233
this.maxKeyBuf = externalMaxKeyBuf ? maxKeyBufParam : null;
201234

202235
if (subj > 0 || pred > 0 || obj > 0 || context >= 0) {
203236
this.externalMinKeyBuf = minKeyBufParam != null;
204-
this.minKeyBuf = externalMinKeyBuf ? minKeyBufParam : pool.getKeyBuffer();
237+
if (externalMinKeyBuf) {
238+
this.minKeyBuf = minKeyBufParam;
239+
} else {
240+
if (this.minKeyBuf == null || prevExternalMinKeyBuf) {
241+
this.minKeyBuf = pool.getKeyBuffer();
242+
} else {
243+
this.minKeyBuf.clear();
244+
}
245+
}
205246
minKeyBuf.clear();
206-
index.getMinKey(minKeyBuf, subj, pred, obj, context);
247+
index.getMinKey(minKeyBuf, subj, pred, obj, context, prevSubj, prevPred, prevObj, prevContext);
207248
minKeyBuf.flip();
208249
} else {
209-
if (this.minKeyBuf != null && !externalMinKeyBuf) {
250+
if (this.minKeyBuf != null && !prevExternalMinKeyBuf) {
210251
pool.free(minKeyBuf);
252+
this.minKeyBuf = null;
211253
}
212254
this.externalMinKeyBuf = minKeyBufParam != null;
213-
this.minKeyBuf = externalMinKeyBuf ? minKeyBufParam : null;
255+
if (externalMinKeyBuf) {
256+
this.minKeyBuf = minKeyBufParam;
257+
} else {
258+
this.minKeyBuf = null;
259+
}
214260
}
215261
}
216262

@@ -219,13 +265,16 @@ private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolea
219265
int boundCount = (subj > 0 ? 1 : 0) + (pred > 0 ? 1 : 0) + (obj > 0 ? 1 : 0) + (context >= 0 ? 1 : 0);
220266
this.needMatcher = boundCount > prefixLen;
221267
this.groupMatcher = null;
268+
this.matcherForEvaluation = null;
222269
this.fetchNext = false;
223270
this.lastResult = MDB_SUCCESS;
224271
this.closed = false;
225272

226-
this.dbi = index.getDB(explicit);
227-
this.txnRef = txnRef;
228-
this.txnLockManager = txnRef.lockManager();
273+
if (!initialized) {
274+
this.dbi = index.getDB(explicit);
275+
this.txnRef = txnRef;
276+
this.txnLockManager = txnRef.lockManager();
277+
}
229278

230279
long readStamp;
231280
try {
@@ -239,9 +288,12 @@ private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolea
239288

240289
// Try to reuse a pooled cursor only for read-only transactions; otherwise open a new one
241290
if (txnRef.isReadOnly()) {
242-
long pooled = pool.getCursor(dbi, index);
243-
if (pooled != 0L) {
244-
long c = pooled;
291+
if (cursor == 0L) {
292+
cursor = pool.getCursor(dbi, index);
293+
}
294+
295+
if (cursor != 0L) {
296+
long c = cursor;
245297
try {
246298
E(mdb_cursor_renew(txn, c));
247299
} catch (IOException renewEx) {
@@ -262,6 +314,11 @@ private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolea
262314
}
263315
}
264316
} else {
317+
if (cursor != 0L) {
318+
pool.freeCursor(dbi, index, cursor);
319+
cursor = 0L;
320+
}
321+
265322
try (MemoryStack stack = MemoryStack.stackPush()) {
266323
PointerBuffer pp = stack.mallocPointer(1);
267324
E(mdb_cursor_open(txn, dbi, pp));
@@ -276,7 +333,6 @@ private void initializeInternal(TripleIndex index, KeyBuilder keyBuilder, boolea
276333
@Override
277334
public long[] next() {
278335
if (closed) {
279-
log.debug("Calling next() on an LmdbRecordIterator that is already closed, returning null");
280336
return null;
281337
}
282338
StampedLongAdderLockManager manager = txnLockManager;
@@ -345,7 +401,7 @@ public long[] next() {
345401
return quad;
346402
}
347403
}
348-
closeInternal(false);
404+
// closeInternal(false);
349405
return null;
350406
} finally {
351407
manager.unlockRead(readStamp);
@@ -358,16 +414,39 @@ private boolean matches() {
358414
return false;
359415
}
360416

361-
if (groupMatcher != null) {
362-
return !this.groupMatcher.matches(keyData.mv_data());
417+
if (matcherForEvaluation != null) {
418+
return !matcherForEvaluation.matches(keyData.mv_data());
363419
} else if (matchValues) {
364-
this.groupMatcher = index.createMatcher(subj, pred, obj, context);
365-
return !this.groupMatcher.matches(keyData.mv_data());
420+
matcherForEvaluation = index.createMatcher(subj, pred, obj, context);
421+
groupMatcher = matcherForEvaluation;
422+
return !matcherForEvaluation.matches(keyData.mv_data());
366423
} else {
367424
return false;
368425
}
369426
}
370427

428+
private void prepareForReuse() {
429+
if (cursor != 0L && txnRef != null) {
430+
if (txnRef.isReadOnly()) {
431+
pool.freeCursor(dbi, index, cursor);
432+
} else {
433+
mdb_cursor_close(cursor);
434+
}
435+
}
436+
cursor = 0L;
437+
groupMatcher = null;
438+
matcherForEvaluation = null;
439+
fetchNext = false;
440+
lastResult = MDB_SUCCESS;
441+
matchValues = false;
442+
needMatcher = false;
443+
txnRef = null;
444+
txn = 0L;
445+
txnRefVersion = 0L;
446+
txnLockManager = null;
447+
closed = true;
448+
}
449+
371450
private void closeInternal(boolean maybeCalledAsync) {
372451
StampedLongAdderLockManager manager = this.txnLockManager;
373452
if (closed) {
@@ -414,7 +493,10 @@ private void closeInternal(boolean maybeCalledAsync) {
414493
maxKeyBuf = null;
415494
externalMinKeyBuf = false;
416495
externalMaxKeyBuf = false;
417-
groupMatcher = null;
496+
if (maybeCalledAsync) {
497+
groupMatcher = null;
498+
}
499+
matcherForEvaluation = null;
418500
fetchNext = false;
419501
lastResult = 0;
420502
matchValues = false;

0 commit comments

Comments
 (0)