mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
HashTable fix bug during resize with nonstandard grower
This commit is contained in:
parent
4f919261bd
commit
e3003add57
@ -539,7 +539,8 @@ protected:
|
||||
* after transferring all the elements from the old halves you need to [ o x ]
|
||||
* process tail from the collision resolution chain immediately after it [ o x ]
|
||||
*/
|
||||
for (; !buf[i].isZero(*this); ++i)
|
||||
size_t new_size = grower.bufSize();
|
||||
for (; i < new_size && !buf[i].isZero(*this); ++i)
|
||||
{
|
||||
size_t updated_place_value = reinsert(buf[i], buf[i].getHash(*this));
|
||||
|
||||
|
@ -317,3 +317,51 @@ TEST(HashTable, SerializationDeserialization)
|
||||
ASSERT_EQ(convertToSet(cont), convertToSet(deserialized));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct IdentityHash
|
||||
{
|
||||
size_t operator()(T x) const { return x; }
|
||||
};
|
||||
|
||||
struct OneElementResizeGrower
|
||||
{
|
||||
/// If collision resolution chains are contiguous, we can implement erase operation by moving the elements.
|
||||
static constexpr auto performs_linear_probing_with_single_step = true;
|
||||
|
||||
static constexpr size_t initial_count = 1;
|
||||
|
||||
size_t bufSize() const { return buf_size; }
|
||||
|
||||
size_t place(size_t x) const { return x % buf_size; }
|
||||
|
||||
size_t next(size_t pos) const { return (pos + 1) % buf_size; }
|
||||
|
||||
bool overflow(size_t elems) const { return elems >= buf_size; }
|
||||
|
||||
void increaseSize() { ++buf_size; }
|
||||
|
||||
void set(size_t) { }
|
||||
|
||||
void setBufSize(size_t buf_size_) { buf_size = buf_size_; }
|
||||
|
||||
size_t buf_size = initial_count;
|
||||
};
|
||||
|
||||
TEST(HashTable, Resize)
|
||||
{
|
||||
{
|
||||
/// Test edge case if after resize all cells are resized in end of buf and will take half of
|
||||
/// hash table place.
|
||||
using HashSet = HashSet<int, IdentityHash<int>, OneElementResizeGrower>;
|
||||
HashSet cont;
|
||||
|
||||
cont.insert(3);
|
||||
cont.insert(1);
|
||||
|
||||
std::set<int> expected = {1, 3};
|
||||
std::set<int> actual = convertToSet(cont);
|
||||
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user