Skip to content

Commit 0814df9

Browse files
committed
Add slab arraymap tests.
1 parent 56f7fb3 commit 0814df9

1 file changed

Lines changed: 136 additions & 2 deletions

File tree

test/primitives/arraymap.cpp

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ class arraymap_
3434

3535
using link3 = linkage<3>;
3636
struct record4 { static constexpr size_t size = 4; };
37-
using record_table = arraymap<link3, record4::size>;
37+
using record_table = arraymap_<link3, record4::size>;
38+
39+
struct slab0 { static constexpr size_t size = max_size_t; };
40+
using slab_table = arraymap_<link3, slab0::size>;
3841

3942
// Bucket count is one less than link count, due to header.size field.
4043
constexpr auto initial_buckets = 18;
@@ -45,7 +48,7 @@ static_assert(initial_links == 19u);
4548
////std::cout << head_store.buffer() << std::endl << std::endl;
4649
////std::cout << body_store.buffer() << std::endl << std::endl;
4750

48-
// record hashmap
51+
// record arraymap_
4952
// ----------------------------------------------------------------------------
5053

5154
BOOST_AUTO_TEST_CASE(arraymap__record_construct__empty__expected)
@@ -67,6 +70,58 @@ BOOST_AUTO_TEST_CASE(arraymap__record_construct__non_empty__expected)
6770
BOOST_REQUIRE_EQUAL(body_store.buffer().size(), body_size);
6871
BOOST_REQUIRE(!instance.get_fault());
6972
}
73+
// slab arraymap_
74+
// ----------------------------------------------------------------------------
75+
76+
BOOST_AUTO_TEST_CASE(arraymap___slab_construct__empty__expected)
77+
{
78+
test::chunk_storage head_store{};
79+
test::chunk_storage body_store{};
80+
const slab_table instance{ head_store, body_store, initial_buckets };
81+
BOOST_REQUIRE(body_store.buffer().empty());
82+
BOOST_REQUIRE(!instance.get_fault());
83+
}
84+
85+
BOOST_AUTO_TEST_CASE(arraymap___slab_construct__non_empty__expected_enabled)
86+
{
87+
constexpr auto body_size = 12345u;
88+
test::chunk_storage head_store{};
89+
test::chunk_storage body_store{};
90+
body_store.buffer().resize(body_size);
91+
const slab_table instance{ head_store, body_store, initial_buckets };
92+
BOOST_REQUIRE_EQUAL(body_store.buffer().size(), body_size);
93+
BOOST_REQUIRE(instance.enabled());
94+
BOOST_REQUIRE(!instance.get_fault());
95+
}
96+
97+
BOOST_AUTO_TEST_CASE(arraymap___enabled__non_empty_slab_zero_buckets__false)
98+
{
99+
constexpr auto body_size = 12345u;
100+
test::chunk_storage head_store{};
101+
test::chunk_storage body_store{};
102+
body_store.buffer().resize(body_size);
103+
const slab_table instance{ head_store, body_store, 0 };
104+
BOOST_REQUIRE(!instance.enabled());
105+
BOOST_REQUIRE(!instance.get_fault());
106+
}
107+
108+
BOOST_AUTO_TEST_CASE(arraymap___enabled__empty_slab_one_bucket__false)
109+
{
110+
test::chunk_storage head_store{};
111+
test::chunk_storage body_store{};
112+
slab_table instance{ head_store, body_store, 1 };
113+
BOOST_REQUIRE(!instance.enabled());
114+
BOOST_REQUIRE(!instance.get_fault());
115+
}
116+
117+
BOOST_AUTO_TEST_CASE(arraymap___enabled__empty_slab_nonzero_buckets__true)
118+
{
119+
test::chunk_storage head_store{};
120+
test::chunk_storage body_store{};
121+
slab_table instance{ head_store, body_store, initial_buckets };
122+
BOOST_REQUIRE(instance.enabled());
123+
BOOST_REQUIRE(!instance.get_fault());
124+
}
70125

71126
// get/put
72127
// ----------------------------------------------------------------------------
@@ -218,6 +273,85 @@ BOOST_AUTO_TEST_CASE(arraymap__record_get__big_end_populated__expected)
218273
BOOST_REQUIRE(!instance.get_fault());
219274
}
220275

276+
class little_slab
277+
{
278+
public:
279+
static constexpr size_t size = max_size_t;
280+
static constexpr link3 count() NOEXCEPT
281+
{
282+
return sizeof(uint32_t);
283+
}
284+
285+
bool from_data(database::reader& source) NOEXCEPT
286+
{
287+
value = source.read_little_endian<uint32_t>();
288+
return source;
289+
}
290+
291+
bool to_data(database::finalizer& sink) const NOEXCEPT
292+
{
293+
sink.write_little_endian(value);
294+
return sink;
295+
}
296+
297+
uint32_t value{ 0 };
298+
};
299+
300+
class big_slab
301+
{
302+
public:
303+
static constexpr size_t size = max_size_t;
304+
static constexpr link3 count() NOEXCEPT
305+
{
306+
return sizeof(uint32_t);
307+
}
308+
309+
bool from_data(database::reader& source) NOEXCEPT
310+
{
311+
value = source.read_big_endian<uint32_t>();
312+
return source;
313+
}
314+
315+
bool to_data(database::finalizer& sink) const NOEXCEPT
316+
{
317+
sink.write_big_endian(value);
318+
return sink;
319+
}
320+
321+
uint32_t value{ 0 };
322+
};
323+
324+
BOOST_AUTO_TEST_CASE(hashmap__slab_put__multiple__expected)
325+
{
326+
test::chunk_storage head_store{};
327+
test::chunk_storage body_store{};
328+
329+
arraymap<link3, big_slab::size> instance{ head_store, body_store, initial_buckets };
330+
BOOST_REQUIRE(instance.create());
331+
332+
constexpr link3::integer key_big{ 0 };
333+
constexpr link3::integer key_little{ 1 };
334+
BOOST_REQUIRE(instance.put(key_big, big_slab{ 0xa1b2c3d4_u32 }));
335+
BOOST_REQUIRE(instance.put(key_little, little_slab{ 0xa1b2c3d4_u32 }));
336+
337+
big_slab slab1{};
338+
BOOST_REQUIRE(instance.get(0, slab1));
339+
BOOST_REQUIRE_EQUAL(slab1.value, 0xa1b2c3d4_u32);
340+
341+
little_slab slab2{};
342+
BOOST_REQUIRE(instance.get(big_slab::count(), slab2));
343+
BOOST_REQUIRE_EQUAL(slab2.value, 0xa1b2c3d4_u32);
344+
345+
// This expectation relies on the fact of no hash table conflict between 0x41 and 0x42.
346+
const data_chunk expected_file
347+
{
348+
0xa1, 0xb2, 0xc3, 0xd4,
349+
0xd4, 0xc3, 0xb2, 0xa1
350+
};
351+
BOOST_REQUIRE_EQUAL(body_store.buffer(), expected_file);
352+
BOOST_REQUIRE(!instance.get_fault());
353+
}
354+
221355
// advertises 32 but reads/writes 64
222356
class record_excess
223357
{

0 commit comments

Comments
 (0)