@@ -34,7 +34,10 @@ class arraymap_
3434
3535using link3 = linkage<3 >;
3636struct 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.
4043constexpr 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
5154BOOST_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
222356class record_excess
223357{
0 commit comments