Skip to content
Open
Changes from 3 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
446b3bb
Make hash by the value allocated, not by pointer
cpjulia Nov 25, 2025
1977cd9
Removed duplicate
cpjulia Nov 25, 2025
e0dafb5
Fix hash function
cpjulia Nov 25, 2025
4572970
Removed special treatment for SLICE_POINTER in hash
cpjulia Nov 25, 2025
b8ef3df
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Nov 25, 2025
28eafae
Added missing brace
cpjulia Nov 25, 2025
ad56c03
Added comparison for different types
cpjulia Nov 25, 2025
f3aa424
Change comparison to use normalized equal instead of binaryEquals for…
cpjulia Nov 26, 2025
0eb6df5
Remove unused variable
cpjulia Nov 26, 2025
9c201b3
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Nov 26, 2025
6f766d1
Fix hash comparison
cpjulia Nov 26, 2025
36eccf0
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Nov 26, 2025
12f1c17
Fix comment
cpjulia Nov 26, 2025
b44b774
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Nov 27, 2025
fb50172
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Nov 28, 2025
2650bd8
Simplified AqlValue equal_to, added new tests
cpjulia Nov 28, 2025
4bce568
Added test to check if the new implementation makes more sense in the…
cpjulia Nov 28, 2025
66e216b
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Nov 28, 2025
8a33cdd
Fixed usage of velocypack helper in AqlValue equal_to and added tests
cpjulia Nov 28, 2025
8d4f533
Added new tests
cpjulia Nov 28, 2025
20708d0
Pass seed to avoid collisions and fix tests
cpjulia Nov 30, 2025
3892a23
Added nullptr check to hash
cpjulia Dec 1, 2025
d2165d1
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 1, 2025
e6e3225
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 1, 2025
d631a69
Attempt to fix circle ci errors
cpjulia Dec 2, 2025
d4d92e3
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 2, 2025
9dcf5f1
Simplified logic in cloneDataAndMoveShadow
cpjulia Dec 2, 2025
2e7a7ba
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 2, 2025
4c83b53
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 3, 2025
2f72dcc
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 3, 2025
51699d9
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 4, 2025
2455622
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 4, 2025
122e129
Simplified hash ccode, removed verbose comments
cpjulia Dec 4, 2025
2f5a6ba
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 5, 2025
d2def76
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 5, 2025
0fd411a
Merge branch 'devel' of github.com:arangodb/arangodb into bug-fix/aql…
cpjulia Dec 8, 2025
df15fb6
Added normalization of -0.0 to +0.0 as in an AqlValue constructor and…
cpjulia Dec 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 46 additions & 45 deletions arangod/Aql/AqlValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1371,59 +1371,60 @@ namespace std {
using arangodb::aql::AqlValue;

size_t hash<AqlValue>::operator()(AqlValue const& x) const noexcept {
auto t = x.type();
switch (t) {
case AqlValue::VPACK_INLINE:
return static_cast<size_t>(
VPackSlice(x._data.inlineSliceMeta.slice).volatileHash());
case AqlValue::VPACK_INLINE_INT64:
case AqlValue::VPACK_INLINE_UINT64:
case AqlValue::VPACK_INLINE_DOUBLE:
return static_cast<size_t>(
VPackSlice(x._data.longNumberMeta.data.slice.slice).volatileHash());
// TODO(MBkkt) these hashes have bad distribution
case AqlValue::VPACK_SLICE_POINTER:
return std::hash<void const*>()(x._data.slicePointerMeta.pointer);
case AqlValue::VPACK_MANAGED_SLICE:
return std::hash<void const*>()(x._data.managedSliceMeta.pointer);
case AqlValue::VPACK_MANAGED_STRING:
return std::hash<void const*>()(x._data.managedStringMeta.pointer);
case AqlValue::RANGE:
return std::hash<void const*>()(x._data.rangeMeta.range);
using T = AqlValue::AqlValueType;
auto aqlValueType = x.type();
// as this is non owning, we hash by the pointer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the owning make for a difference?

Hashing is a quick look of the content is equal.
In my opinion it should not take into account if the value is owned or not.

if (aqlValueType == T::VPACK_SLICE_POINTER) {
return std::hash<void const*>()(x._data.slicePointerMeta.pointer);
}
return 0;
auto hash64 = x.hash(0); // make a normalized hash, for the semantics of the
// value regardless of the storae stype
size_t h = static_cast<size_t>(hash64);
if (h == 0) { // fallback to avoid collision with the marker that uses h ==
// 0, very unlikely to happen
h = 1;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hö what is this?

return h;
}

bool equal_to<AqlValue>::operator()(AqlValue const& a,
AqlValue const& b) const noexcept {
// TODO(MBkkt) can be just compare two uint64_t?
auto t = a.type();
if (t != b.type()) {
using T = AqlValue::AqlValueType;
auto ta = a.type();
auto tb = b.type();

if (ta == tb) {
switch (ta) {
case T::VPACK_INLINE:
return VPackSlice(a._data.inlineSliceMeta.slice)
.binaryEquals(VPackSlice(b._data.inlineSliceMeta.slice));
case T::VPACK_INLINE_INT64:
case T::VPACK_INLINE_UINT64:
case T::VPACK_INLINE_DOUBLE:
return a._data.longNumberMeta.data.intLittleEndian.val ==
b._data.longNumberMeta.data.intLittleEndian.val;
case T::VPACK_SLICE_POINTER:
return a._data.slicePointerMeta.pointer ==
b._data.slicePointerMeta.pointer;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pointer comparison?
And not real equality comparison like the default case?

case T::RANGE: {
auto const* ra = a._data.rangeMeta.range;
auto const* rb = b._data.rangeMeta.range;
return ra->_low == rb->_low && ra->_high == rb->_high;
}
default:
return a.slice(ta).binaryEquals(b.slice(tb));
}
}

if (ta == T::RANGE || tb == T::RANGE) {
return false;
}
switch (t) {
case AqlValue::VPACK_INLINE:
return VPackSlice(a._data.inlineSliceMeta.slice)
.binaryEquals(VPackSlice(b._data.inlineSliceMeta.slice));
case AqlValue::VPACK_INLINE_INT64:
case AqlValue::VPACK_INLINE_UINT64:
case AqlValue::VPACK_INLINE_DOUBLE:
// equal is equal. sign/endianess does not matter
return a._data.longNumberMeta.data.intLittleEndian.val ==
b._data.longNumberMeta.data.intLittleEndian.val;
case AqlValue::VPACK_SLICE_POINTER:
return a._data.slicePointerMeta.pointer ==
b._data.slicePointerMeta.pointer;
case AqlValue::VPACK_MANAGED_SLICE:
return a._data.managedSliceMeta.pointer ==
b._data.managedSliceMeta.pointer;
case AqlValue::VPACK_MANAGED_STRING:
return a._data.managedStringMeta.pointer ==
b._data.managedStringMeta.pointer;
case AqlValue::RANGE:
return a._data.rangeMeta.range == b._data.rangeMeta.range;

if (ta == T::VPACK_SLICE_POINTER || tb == T::VPACK_SLICE_POINTER) {
return false;
}
return false;

return a.slice(ta).binaryEquals(b.slice(tb));
}

} // namespace std