10BC0 cheapify IN lookups on unsorted arrays (#11342) · arangodb/arangodb@549295d · GitHub
[go: up one dir, main page]

Skip to content

Commit 549295d

Browse files
authored
cheapify IN lookups on unsorted arrays (#11342)
1 parent a80f336 commit 549295d

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

arangod/Aql/Expression.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "Basics/StringBuffer.h"
4444
#include "Basics/VPackStringBufferAdapter.h"
4545
#include "Basics/VelocyPackHelper.h"
46+
#include "Transaction/Context.h"
4647
#include "Transaction/Helpers.h"
4748
#include "Transaction/Methods.h"
4849
#include "V8/v8-globals.h"
@@ -261,18 +262,40 @@ bool Expression::findInArray(AqlValue const& left, AqlValue const& right,
261262
}
262263
// fall-through to linear search
263264
}
264-
265+
265266
// use linear search
266-
for (size_t i = 0; i < n; ++i) {
267-
bool mustDestroy;
268-
AqlValue a = right.at(i, mustDestroy, false);
269-
AqlValueGuard guard(a, mustDestroy);
270267

271-
int compareResult = AqlValue::Compare(trx, left, a, false);
268+
if (!right.isDocvec() && !right.isRange() &&
269+
!left.isDocvec() && !left.isRange()) {
270+
// optimization for the case in which rhs is a Velocypack array, and we
271+
// can simply use a VelocyPack iterator to walk through it. this will
272+
// be a lot more efficient than using right.at(i) in case the array is
273+
// of type Compact (without any index tables)
274+
VPackSlice const lhs(left.slice());
275+
276+
VPackOptions const* options = trx->transactionContextPtr()->getVPackOptions();
277+
VPackArrayIterator it(right.slice());
278+
while (it.valid()) {
279+
int compareResult = arangodb::basics::VelocyPackHelper::compare(lhs, it.value(), false, options);
280+
281+
if (compareResult == 0) {
282+
// item found in the list
283+
return true;
284+
}
285+
it.next();
286+
}
287+
} else {
288+
for (size_t i = 0; i < n; ++i) {
289+
bool mustDestroy;
290+
AqlValue a = right.at(i, mustDestroy, false);
291+
AqlValueGuard guard(a, mustDestroy);
292+
293+
int compareResult = AqlValue::Compare(trx, left, a, false);
272294

273-
if (compareResult == 0) {
274-
// item found in the list
275-
return true;
295+
if (compareResult == 0) {
296+
// item found in the list
297+
return true;
298+
}
276299
}
277300
}
278301

0 commit comments

Comments
 (0)
0