xref: /llvm-project/libc/test/src/__support/blockstore_test.cpp (revision bc4c3bf1b75fec183e2616d6688aa155d6aada74)
1f00567ecSGuillaume Chatelet //===-- Unittests for BlockStore ------------------------------------------===//
2f00567ecSGuillaume Chatelet //
3f00567ecSGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f00567ecSGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information.
5f00567ecSGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f00567ecSGuillaume Chatelet //
7f00567ecSGuillaume Chatelet //===----------------------------------------------------------------------===//
8f00567ecSGuillaume Chatelet 
9f00567ecSGuillaume Chatelet #include "src/__support/blockstore.h"
10af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h"
11f00567ecSGuillaume Chatelet 
12f00567ecSGuillaume Chatelet struct Element {
13f00567ecSGuillaume Chatelet   int a;
14f00567ecSGuillaume Chatelet   long b;
15f00567ecSGuillaume Chatelet   unsigned c;
16f00567ecSGuillaume Chatelet };
17f00567ecSGuillaume Chatelet 
18b6bc9d72SGuillaume Chatelet class LlvmLibcBlockStoreTest : public LIBC_NAMESPACE::testing::Test {
19f00567ecSGuillaume Chatelet public:
20f00567ecSGuillaume Chatelet   template <size_t BLOCK_SIZE, size_t ELEMENT_COUNT, bool REVERSE>
21f00567ecSGuillaume Chatelet   void populate_and_iterate() {
226503eff6SNick Desaulniers     LIBC_NAMESPACE::BlockStore<Element, BLOCK_SIZE, REVERSE> block_store;
23f00567ecSGuillaume Chatelet     for (int i = 0; i < int(ELEMENT_COUNT); ++i)
24eb9cc253SSiva Chandra Reddy       ASSERT_TRUE(block_store.push_back({i, 2 * i, 3 * unsigned(i)}));
25f00567ecSGuillaume Chatelet     auto end = block_store.end();
26f00567ecSGuillaume Chatelet     int i = 0;
27f00567ecSGuillaume Chatelet     for (auto iter = block_store.begin(); iter != end; ++iter, ++i) {
28f00567ecSGuillaume Chatelet       Element &e = *iter;
29f00567ecSGuillaume Chatelet       if (REVERSE) {
30f00567ecSGuillaume Chatelet         int j = ELEMENT_COUNT - 1 - i;
31f00567ecSGuillaume Chatelet         ASSERT_EQ(e.a, j);
32f00567ecSGuillaume Chatelet         ASSERT_EQ(e.b, long(j * 2));
33f00567ecSGuillaume Chatelet         ASSERT_EQ(e.c, unsigned(j * 3));
34f00567ecSGuillaume Chatelet       } else {
35f00567ecSGuillaume Chatelet         ASSERT_EQ(e.a, i);
36f00567ecSGuillaume Chatelet         ASSERT_EQ(e.b, long(i * 2));
37f00567ecSGuillaume Chatelet         ASSERT_EQ(e.c, unsigned(i * 3));
38f00567ecSGuillaume Chatelet       }
39f00567ecSGuillaume Chatelet     }
40f00567ecSGuillaume Chatelet     ASSERT_EQ(i, int(ELEMENT_COUNT));
416503eff6SNick Desaulniers     LIBC_NAMESPACE::BlockStore<Element, BLOCK_SIZE, REVERSE>::destroy(
42f00567ecSGuillaume Chatelet         &block_store);
43f00567ecSGuillaume Chatelet   }
44f00567ecSGuillaume Chatelet 
45f00567ecSGuillaume Chatelet   template <bool REVERSE> void back_test() {
466503eff6SNick Desaulniers     using LIBC_NAMESPACE::BlockStore;
47f00567ecSGuillaume Chatelet     BlockStore<int, 4, REVERSE> block_store;
48f00567ecSGuillaume Chatelet     for (int i = 0; i < 20; i++)
49eb9cc253SSiva Chandra Reddy       ASSERT_TRUE(block_store.push_back(i));
50f00567ecSGuillaume Chatelet     for (int i = 19; i >= 0; i--, block_store.pop_back())
51f00567ecSGuillaume Chatelet       ASSERT_EQ(block_store.back(), i);
52f00567ecSGuillaume Chatelet     block_store.destroy(&block_store);
53f00567ecSGuillaume Chatelet   }
54f00567ecSGuillaume Chatelet 
55f00567ecSGuillaume Chatelet   template <bool REVERSE> void empty_test() {
566503eff6SNick Desaulniers     using LIBC_NAMESPACE::BlockStore;
57f00567ecSGuillaume Chatelet     BlockStore<int, 2, REVERSE> block_store;
58f00567ecSGuillaume Chatelet 
59f00567ecSGuillaume Chatelet     ASSERT_TRUE(block_store.empty());
60eb9cc253SSiva Chandra Reddy     ASSERT_TRUE(block_store.push_back(1));
61eb9cc253SSiva Chandra Reddy     for (int i = 0; i < 10; i++) {
62f00567ecSGuillaume Chatelet       ASSERT_FALSE(block_store.empty());
63eb9cc253SSiva Chandra Reddy       ASSERT_TRUE(block_store.push_back(1));
64eb9cc253SSiva Chandra Reddy     }
65f00567ecSGuillaume Chatelet     block_store.destroy(&block_store);
66f00567ecSGuillaume Chatelet   }
67eb272568SMichael Jones 
68eb272568SMichael Jones   template <bool REVERSE> void erase_test() {
69eb272568SMichael Jones     using LIBC_NAMESPACE::BlockStore;
70eb272568SMichael Jones     BlockStore<int, 2, REVERSE> block_store;
71eb272568SMichael Jones     int i;
72eb272568SMichael Jones 
73eb272568SMichael Jones     constexpr int ARR_SIZE = 6;
74eb272568SMichael Jones 
75eb272568SMichael Jones     ASSERT_TRUE(block_store.empty());
76eb272568SMichael Jones     for (int i = 0; i < ARR_SIZE; i++) {
77eb272568SMichael Jones       ASSERT_TRUE(block_store.push_back(i + 1));
78eb272568SMichael Jones     }
79eb272568SMichael Jones 
80eb272568SMichael Jones     // block_store state should be {1,2,3,4,5,6}
81eb272568SMichael Jones 
82eb272568SMichael Jones     block_store.erase(block_store.begin());
83eb272568SMichael Jones 
84eb272568SMichael Jones     // FORWARD: block_store state should be {2,3,4,5,6}
85eb272568SMichael Jones     // REVERSE: block_store state should be {1,2,3,4,5}
86eb272568SMichael Jones 
87eb272568SMichael Jones     auto iter = block_store.begin();
88eb272568SMichael Jones     for (i = 0; iter != block_store.end(); ++i, ++iter) {
89eb272568SMichael Jones       if (!REVERSE) {
90eb272568SMichael Jones         ASSERT_EQ(*iter, i + 2);
91eb272568SMichael Jones       } else {
92eb272568SMichael Jones         ASSERT_EQ(*iter, (ARR_SIZE - 1) - i);
93eb272568SMichael Jones       }
94eb272568SMichael Jones     }
95eb272568SMichael Jones 
96eb272568SMichael Jones     // Assert that there were the correct number of elements
97eb272568SMichael Jones     ASSERT_EQ(i, ARR_SIZE - 1);
98eb272568SMichael Jones 
99eb272568SMichael Jones     block_store.erase(block_store.end());
100eb272568SMichael Jones 
101eb272568SMichael Jones     // BOTH: block_store state should be {2,3,4,5}
102eb272568SMichael Jones 
103eb272568SMichael Jones     iter = block_store.begin();
104eb272568SMichael Jones     for (i = 0; iter != block_store.end(); ++i, ++iter) {
105eb272568SMichael Jones       if (!REVERSE) {
106eb272568SMichael Jones         ASSERT_EQ(*iter, i + 2);
107eb272568SMichael Jones       } else {
108eb272568SMichael Jones         ASSERT_EQ(*iter, (ARR_SIZE - 1) - i);
109eb272568SMichael Jones       }
110eb272568SMichael Jones     }
111eb272568SMichael Jones 
112eb272568SMichael Jones     ASSERT_EQ(i, ARR_SIZE - 2);
113eb272568SMichael Jones 
114eb272568SMichael Jones     block_store.erase(block_store.begin() + 1);
115eb272568SMichael Jones 
116eb272568SMichael Jones     // FORWARD: block_store state should be {2,4,5}
117eb272568SMichael Jones     // REVERSE: block_store state should be {2,3,5}
118eb272568SMichael Jones 
119eb272568SMichael Jones     const int FORWARD_RESULTS[] = {2, 4, 5};
120eb272568SMichael Jones     const int REVERSE_RESULTS[] = {2, 3, 5};
121eb272568SMichael Jones 
122eb272568SMichael Jones     iter = block_store.begin();
123eb272568SMichael Jones     for (i = 0; iter != block_store.end(); ++i, ++iter) {
124eb272568SMichael Jones       if (!REVERSE) {
125eb272568SMichael Jones         ASSERT_EQ(*iter, FORWARD_RESULTS[i]);
126eb272568SMichael Jones       } else {
127eb272568SMichael Jones         ASSERT_EQ(*iter, REVERSE_RESULTS[ARR_SIZE - 4 - i]); // reversed
128eb272568SMichael Jones       }
129eb272568SMichael Jones     }
130eb272568SMichael Jones 
131eb272568SMichael Jones     ASSERT_EQ(i, ARR_SIZE - 3);
132eb272568SMichael Jones 
133eb272568SMichael Jones     block_store.erase(block_store.begin() + 1);
134eb272568SMichael Jones     // BOTH: block_store state should be {2,5}
135eb272568SMichael Jones 
136eb272568SMichael Jones     iter = block_store.begin();
137eb272568SMichael Jones     if (!REVERSE) {
138eb272568SMichael Jones       ASSERT_EQ(*iter, 2);
139eb272568SMichael Jones       ASSERT_EQ(*(iter + 1), 5);
140eb272568SMichael Jones     } else {
141eb272568SMichael Jones       ASSERT_EQ(*iter, 5);
142eb272568SMichael Jones       ASSERT_EQ(*(iter + 1), 2);
143eb272568SMichael Jones     }
144eb272568SMichael Jones 
145eb272568SMichael Jones     block_store.erase(block_store.begin());
146eb272568SMichael Jones     // FORWARD: block_store state should be {5}
147eb272568SMichael Jones     // REVERSE: block_store state should be {2}
148eb272568SMichael Jones     iter = block_store.begin();
149eb272568SMichael Jones     if (!REVERSE) {
150eb272568SMichael Jones       ASSERT_EQ(*iter, 5);
151eb272568SMichael Jones     } else {
152eb272568SMichael Jones       ASSERT_EQ(*iter, 2);
153eb272568SMichael Jones     }
154eb272568SMichael Jones 
155eb272568SMichael Jones     block_store.erase(block_store.begin());
156eb272568SMichael Jones     // BOTH: block_store state should be {}
157eb272568SMichael Jones 
158eb272568SMichael Jones     block_store.destroy(&block_store);
159eb272568SMichael Jones   }
160f00567ecSGuillaume Chatelet };
161f00567ecSGuillaume Chatelet 
162f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate4) {
163f00567ecSGuillaume Chatelet   populate_and_iterate<4, 4, false>();
164f00567ecSGuillaume Chatelet }
165f00567ecSGuillaume Chatelet 
166f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate8) {
167f00567ecSGuillaume Chatelet   populate_and_iterate<4, 8, false>();
168f00567ecSGuillaume Chatelet }
169f00567ecSGuillaume Chatelet 
170f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterate10) {
171f00567ecSGuillaume Chatelet   populate_and_iterate<4, 10, false>();
172f00567ecSGuillaume Chatelet }
173f00567ecSGuillaume Chatelet 
174f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse4) {
175f00567ecSGuillaume Chatelet   populate_and_iterate<4, 4, true>();
176f00567ecSGuillaume Chatelet }
177f00567ecSGuillaume Chatelet 
178f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse8) {
179f00567ecSGuillaume Chatelet   populate_and_iterate<4, 8, true>();
180f00567ecSGuillaume Chatelet }
181f00567ecSGuillaume Chatelet 
182f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, PopulateAndIterateReverse10) {
183f00567ecSGuillaume Chatelet   populate_and_iterate<4, 10, true>();
184f00567ecSGuillaume Chatelet }
185f00567ecSGuillaume Chatelet 
186*bc4c3bf1SJoseph Huber TEST_F(LlvmLibcBlockStoreTest, Back) {
187*bc4c3bf1SJoseph Huber   back_test<false>();
188*bc4c3bf1SJoseph Huber   back_test<true>();
189*bc4c3bf1SJoseph Huber }
190f00567ecSGuillaume Chatelet 
191f00567ecSGuillaume Chatelet TEST_F(LlvmLibcBlockStoreTest, Empty) {
192f00567ecSGuillaume Chatelet   empty_test<false>();
193f00567ecSGuillaume Chatelet   empty_test<true>();
194f00567ecSGuillaume Chatelet }
195eb272568SMichael Jones 
196eb272568SMichael Jones TEST_F(LlvmLibcBlockStoreTest, Erase) {
197eb272568SMichael Jones   erase_test<false>();
198eb272568SMichael Jones   erase_test<true>();
199eb272568SMichael Jones }
200