Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/tests/DenseHash.test.cpp
2723 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#include "Luau/DenseHash.h"
3
4
#include "doctest.h"
5
6
/** So... why are we picking a very specific number to fill the DenseHash(Map|Set)?
7
*
8
* That's because that's the count that happens to trigger a specific bug.
9
*
10
* DHT determines if it is full by checking whether the count is greater than or equal to 75% of
11
* its capacity. Once this condition triggers, it rehashes everything by doubling its buffer.
12
*
13
* If DHT gets rehashed, the iterator gets invalidated, but it's very important that we support
14
* the use case of overwriting/merging DHTs while iterating.
15
*/
16
17
TEST_SUITE_BEGIN("DenseHashTests");
18
19
TEST_CASE("overwriting_an_existing_field_when_full_shouldnt_rehash")
20
{
21
// See the note at the top on why these numbers were chosen.
22
23
Luau::DenseHashMap<int, int> m{-1};
24
for (int i = 0; i < 12; ++i)
25
m[i] = i;
26
27
REQUIRE(m.size() == 12);
28
29
for (auto [k, a] : m)
30
m[k] = a + 1;
31
32
for (size_t i = 0; i < m.size(); ++i)
33
{
34
int* a = m.find(int(i));
35
REQUIRE(a);
36
CHECK(i + 1 == *a);
37
}
38
}
39
40
TEST_CASE("merging_another_map_and_resolve_conflicts_that_also_just_so_happens_to_rehash_while_iterating")
41
{
42
// See the note at the top on why these numbers were chosen.
43
44
Luau::DenseHashMap<int, int> m1{-1};
45
for (int i = 0; i < 12; ++i)
46
m1[i] = i;
47
48
Luau::DenseHashMap<int, int> m2{-1};
49
for (int i = 8; i < 24; ++i)
50
m2[i] = i;
51
52
REQUIRE(m1.size() == 12);
53
REQUIRE(m2.size() == 16);
54
55
for (auto [k, a] : m1)
56
{
57
if (int* b = m2.find(k))
58
m1[k] = a + *b;
59
}
60
61
for (auto [k, a] : m2)
62
{
63
if (!m1.find(k))
64
m1[k] = a;
65
}
66
67
REQUIRE(m1.size() == 24);
68
for (size_t i = 0; i < m1.size(); ++i)
69
{
70
int* a = m1.find(int(i));
71
REQUIRE(a);
72
if (i < 8 || i >= 12)
73
CHECK(i == *a);
74
else
75
CHECK(i + i == *a);
76
}
77
}
78
79
TEST_SUITE_END();
80
81