Skip to content

Commit b09ddc7

Browse files
committed
[Wasm] Adapt OpenAddressingHashTable::rehash() to not reallocating and copying out-of-place values.
1 parent d886ce1 commit b09ddc7

File tree

2 files changed

+39
-35
lines changed

2 files changed

+39
-35
lines changed

src/backend/WasmAlgo.cpp

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,11 +1545,24 @@ HashTable::entry_t OpenAddressingHashTable<IsGlobal, ValueInPlace>::emplace(std:
15451545
update_high_watermark();
15461546
};
15471547

1548-
return emplace_without_rehashing(std::move(key));
1548+
auto slot = emplace_without_rehashing(std::move(key));
1549+
1550+
if constexpr (ValueInPlace) {
1551+
/*----- Return entry handle containing all values. -----*/
1552+
return value_entry(slot);
1553+
} else {
1554+
/*----- Allocate memory for out-of-place values and set pointer to it. -----*/
1555+
Ptr<void> ptr =
1556+
Module::Allocator().allocate(layout_.values_size_in_bytes_, layout_.values_max_alignment_in_bytes_);
1557+
*(slot + layout_.ptr_offset_in_bytes_).template to<uint32_t*>() = ptr.clone().to<uint32_t>();
1558+
1559+
/*----- Return entry handle containing all values. -----*/
1560+
return value_entry(ptr);
1561+
}
15491562
}
15501563

15511564
template<bool IsGlobal, bool ValueInPlace>
1552-
HashTable::entry_t OpenAddressingHashTable<IsGlobal, ValueInPlace>::emplace_without_rehashing(std::vector<SQL_t> key)
1565+
Ptr<void> OpenAddressingHashTable<IsGlobal, ValueInPlace>::emplace_without_rehashing(std::vector<SQL_t> key)
15531566
{
15541567
M_insist(bool(num_entries_), "must call `setup()` before");
15551568
M_insist(bool(high_watermark_absolute_), "must call `setup()` before");
@@ -1600,25 +1613,7 @@ HashTable::entry_t OpenAddressingHashTable<IsGlobal, ValueInPlace>::emplace_with
16001613
/*----- Insert key. -----*/
16011614
insert_key(slot, std::move(key)); // move key at last use
16021615

1603-
if constexpr (ValueInPlace) {
1604-
/*----- Return entry handle containing all values. -----*/
1605-
return value_entry(slot);
1606-
} else {
1607-
/*----- Allocate memory for out-of-place values and set pointer to it. -----*/
1608-
Ptr<void> ptr =
1609-
Module::Allocator().allocate(layout_.values_size_in_bytes_, layout_.values_max_alignment_in_bytes_);
1610-
*(slot + layout_.ptr_offset_in_bytes_).template to<uint32_t*>() = ptr.clone().to<uint32_t>();
1611-
1612-
if (pred) {
1613-
/*----- Store address and size of dummy predication entry to free them later. -----*/
1614-
var_t<Ptr<void>> ptr_; // create global variable iff `IsGlobal` to be able to access it later for deallocation
1615-
ptr_ = ptr.clone();
1616-
dummy_allocations_.emplace_back(ptr_, layout_.values_size_in_bytes_);
1617-
}
1618-
1619-
/*----- Return entry handle containing all values. -----*/
1620-
return value_entry(ptr);
1621-
}
1616+
return slot;
16221617
}
16231618

16241619
template<bool IsGlobal, bool ValueInPlace>
@@ -2173,18 +2168,27 @@ void OpenAddressingHashTable<IsGlobal, ValueInPlace>::rehash()
21732168
}
21742169

21752170
/*----- Insert key into new hash table. No rehashing needed since the new hash table is large enough. */
2176-
auto e_new = emplace_without_rehashing(std::move(key));
2177-
2178-
/*----- Insert values from old entry into new one. -----*/
2179-
for (auto v : value_indices_) {
2180-
auto id = schema_.get()[v].id;
2181-
std::visit(overloaded {
2182-
[&]<sql_type T>(reference_t<T> &&r) -> void { r = e_old.template extract<T>(id); },
2183-
[](std::monostate) -> void { M_unreachable("invalid reference"); },
2184-
}, e_new.extract(id));
2171+
auto slot = emplace_without_rehashing(std::move(key));
2172+
2173+
if constexpr (ValueInPlace) {
2174+
/*----- Get entry handle containing all values of new entry. -----*/
2175+
auto e_new = value_entry(slot);
2176+
2177+
/*----- Insert values from old entry into new one. -----*/
2178+
for (auto v : value_indices_) {
2179+
auto id = schema_.get()[v].id;
2180+
std::visit(overloaded {
2181+
[&]<sql_type T>(reference_t<T> &&r) -> void { r = e_old.template extract<T>(id); },
2182+
[](std::monostate) -> void { M_unreachable("invalid reference"); },
2183+
}, e_new.extract(id));
2184+
}
2185+
M_insist(e_old.empty());
2186+
M_insist(e_new.empty());
2187+
} else {
2188+
/*----- Set pointer to out-of-place values of new entry to the one of old entry. -----*/
2189+
*(slot + layout_.ptr_offset_in_bytes_).template to<uint32_t*>() =
2190+
*(it + layout_.ptr_offset_in_bytes_).template to<uint32_t*>();
21852191
}
2186-
M_insist(e_old.empty());
2187-
M_insist(e_new.empty());
21882192
};
21892193

21902194
/*----- Advance to next entry in old hash table. -----*/

src/backend/WasmAlgo.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -927,10 +927,10 @@ struct OpenAddressingHashTable : OpenAddressingHashTableBase
927927

928928
private:
929929
/** Inserts an entry into the hash table with key \p key regardless whether it already exists, i.e. duplicates
930-
* are allowed. Returns a handle to the newly inserted entry which may be used to write the values for this
931-
* entry. No rehashing of the hash table must be performed, i.e. the hash table must have at least
930+
* are allowed. Returns a pointer to the newly inserted slot without allocating any space for possible
931+
* out-of-place values. No rehashing of the hash table must be performed, i.e. the hash table must have at least
932932
* one free entry slot. */
933-
entry_t emplace_without_rehashing(std::vector<SQL_t> key);
933+
Ptr<void> emplace_without_rehashing(std::vector<SQL_t> key);
934934

935935
/** Compares the key of the slot at address \p slot with \p key and returns `true` iff they are equal. */
936936
Bool equal_key(Ptr<void> slot, std::vector<SQL_t> key) const;

0 commit comments

Comments
 (0)