mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +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 ]
|
* 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 ]
|
* 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));
|
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));
|
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