xref: /aosp_15_r20/external/llvm-libc/test/src/search/hsearch_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for hsearch ---------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/bit.h" // bit_ceil
10*71db0c75SAndroid Build Coastguard Worker #include "src/__support/HashTable/table.h"
11*71db0c75SAndroid Build Coastguard Worker #include "src/search/hcreate.h"
12*71db0c75SAndroid Build Coastguard Worker #include "src/search/hcreate_r.h"
13*71db0c75SAndroid Build Coastguard Worker #include "src/search/hdestroy.h"
14*71db0c75SAndroid Build Coastguard Worker #include "src/search/hdestroy_r.h"
15*71db0c75SAndroid Build Coastguard Worker #include "src/search/hsearch.h"
16*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/ErrnoSetterMatcher.h"
17*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
18*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHsearchTest,CreateTooLarge)19*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHsearchTest, CreateTooLarge) {
20*71db0c75SAndroid Build Coastguard Worker   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
21*71db0c75SAndroid Build Coastguard Worker   struct hsearch_data hdata;
22*71db0c75SAndroid Build Coastguard Worker   ASSERT_THAT(LIBC_NAMESPACE::hcreate(-1), Fails(ENOMEM, 0));
23*71db0c75SAndroid Build Coastguard Worker   ASSERT_THAT(LIBC_NAMESPACE::hcreate_r(-1, &hdata), Fails(ENOMEM, 0));
24*71db0c75SAndroid Build Coastguard Worker }
25*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHSearchTest,CreateInvalid)26*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHSearchTest, CreateInvalid) {
27*71db0c75SAndroid Build Coastguard Worker   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
28*71db0c75SAndroid Build Coastguard Worker   ASSERT_THAT(LIBC_NAMESPACE::hcreate_r(16, nullptr), Fails(EINVAL, 0));
29*71db0c75SAndroid Build Coastguard Worker }
30*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHSearchTest,CreateValid)31*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHSearchTest, CreateValid) {
32*71db0c75SAndroid Build Coastguard Worker   struct hsearch_data hdata;
33*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(LIBC_NAMESPACE::hcreate_r(1, &hdata), 0);
34*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::hdestroy_r(&hdata);
35*71db0c75SAndroid Build Coastguard Worker 
36*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(LIBC_NAMESPACE::hcreate(1), 0);
37*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::hdestroy();
38*71db0c75SAndroid Build Coastguard Worker }
39*71db0c75SAndroid Build Coastguard Worker 
40*71db0c75SAndroid Build Coastguard Worker char search_data[] = "1234567890abcdefghijklmnopqrstuvwxyz"
41*71db0c75SAndroid Build Coastguard Worker                      "1234567890abcdefghijklmnopqrstuvwxyz"
42*71db0c75SAndroid Build Coastguard Worker                      "1234567890abcdefghijklmnopqrstuvwxyz"
43*71db0c75SAndroid Build Coastguard Worker                      "1234567890abcdefghijklmnopqrstuvwxyz"
44*71db0c75SAndroid Build Coastguard Worker                      "1234567890abcdefghijklmnopqrstuvwxyz";
45*71db0c75SAndroid Build Coastguard Worker char search_data2[] =
46*71db0c75SAndroid Build Coastguard Worker     "@@@@@@@@@@@@@@!!!!!!!!!!!!!!!!!###########$$$$$$$$$$^^^^^^&&&&&&&&";
47*71db0c75SAndroid Build Coastguard Worker 
48*71db0c75SAndroid Build Coastguard Worker constexpr size_t GROUP_SIZE = sizeof(LIBC_NAMESPACE::internal::Group);
49*71db0c75SAndroid Build Coastguard Worker constexpr size_t CAP =
50*71db0c75SAndroid Build Coastguard Worker     LIBC_NAMESPACE::cpp::bit_ceil((GROUP_SIZE + 1) * 8 / 7) / 8 * 7;
51*71db0c75SAndroid Build Coastguard Worker static_assert(CAP < sizeof(search_data), "CAP too large");
52*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHSearchTest,GrowFromZero)53*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHSearchTest, GrowFromZero) {
54*71db0c75SAndroid Build Coastguard Worker   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
55*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(LIBC_NAMESPACE::hcreate(0), 0);
56*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < sizeof(search_data) - 1; ++i) {
57*71db0c75SAndroid Build Coastguard Worker     ENTRY *inserted = LIBC_NAMESPACE::hsearch(
58*71db0c75SAndroid Build Coastguard Worker         {&search_data[i], reinterpret_cast<void *>(i)}, ENTER);
59*71db0c75SAndroid Build Coastguard Worker     ASSERT_NE(inserted, static_cast<ENTRY *>(nullptr));
60*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(inserted->key, &search_data[i]);
61*71db0c75SAndroid Build Coastguard Worker   }
62*71db0c75SAndroid Build Coastguard Worker   for (size_t i = sizeof(search_data) - 1; i != 0; --i) {
63*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(
64*71db0c75SAndroid Build Coastguard Worker         LIBC_NAMESPACE::hsearch({&search_data[i - 1], nullptr}, FIND)->data,
65*71db0c75SAndroid Build Coastguard Worker         reinterpret_cast<void *>(i - 1));
66*71db0c75SAndroid Build Coastguard Worker   }
67*71db0c75SAndroid Build Coastguard Worker 
68*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::hdestroy();
69*71db0c75SAndroid Build Coastguard Worker }
70*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHSearchTest,NotFound)71*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHSearchTest, NotFound) {
72*71db0c75SAndroid Build Coastguard Worker   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
73*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(LIBC_NAMESPACE::hcreate(GROUP_SIZE + 1), 0);
74*71db0c75SAndroid Build Coastguard Worker   ASSERT_THAT(static_cast<void *>(
75*71db0c75SAndroid Build Coastguard Worker                   LIBC_NAMESPACE::hsearch({search_data2, nullptr}, FIND)),
76*71db0c75SAndroid Build Coastguard Worker               Fails(ESRCH, static_cast<void *>(nullptr)));
77*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CAP; ++i) {
78*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::hsearch({&search_data[i], nullptr}, ENTER)->key,
79*71db0c75SAndroid Build Coastguard Worker               &search_data[i]);
80*71db0c75SAndroid Build Coastguard Worker   }
81*71db0c75SAndroid Build Coastguard Worker   ASSERT_THAT(static_cast<void *>(
82*71db0c75SAndroid Build Coastguard Worker                   LIBC_NAMESPACE::hsearch({search_data2, nullptr}, FIND)),
83*71db0c75SAndroid Build Coastguard Worker               Fails(ESRCH, static_cast<void *>(nullptr)));
84*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::hdestroy();
85*71db0c75SAndroid Build Coastguard Worker }
86*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHSearchTest,Found)87*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHSearchTest, Found) {
88*71db0c75SAndroid Build Coastguard Worker   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
89*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(LIBC_NAMESPACE::hcreate(GROUP_SIZE + 1), 0);
90*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CAP; ++i) {
91*71db0c75SAndroid Build Coastguard Worker     ENTRY *inserted = LIBC_NAMESPACE::hsearch(
92*71db0c75SAndroid Build Coastguard Worker         {&search_data[i], reinterpret_cast<void *>(i)}, ENTER);
93*71db0c75SAndroid Build Coastguard Worker     ASSERT_NE(inserted, static_cast<ENTRY *>(nullptr));
94*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(inserted->key, &search_data[i]);
95*71db0c75SAndroid Build Coastguard Worker   }
96*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CAP; ++i) {
97*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::hsearch({&search_data[i], nullptr}, FIND)->data,
98*71db0c75SAndroid Build Coastguard Worker               reinterpret_cast<void *>(i));
99*71db0c75SAndroid Build Coastguard Worker   }
100*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::hdestroy();
101*71db0c75SAndroid Build Coastguard Worker }
102*71db0c75SAndroid Build Coastguard Worker 
TEST(LlvmLibcHSearchTest,OnlyInsertWhenNotFound)103*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcHSearchTest, OnlyInsertWhenNotFound) {
104*71db0c75SAndroid Build Coastguard Worker   using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
105*71db0c75SAndroid Build Coastguard Worker   ASSERT_GT(LIBC_NAMESPACE::hcreate(GROUP_SIZE + 1), 0);
106*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CAP / 7 * 5; ++i) {
107*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::hsearch(
108*71db0c75SAndroid Build Coastguard Worker                   {&search_data[i], reinterpret_cast<void *>(i)}, ENTER)
109*71db0c75SAndroid Build Coastguard Worker                   ->key,
110*71db0c75SAndroid Build Coastguard Worker               &search_data[i]);
111*71db0c75SAndroid Build Coastguard Worker   }
112*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CAP; ++i) {
113*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::hsearch(
114*71db0c75SAndroid Build Coastguard Worker                   {&search_data[i], reinterpret_cast<void *>(1000 + i)}, ENTER)
115*71db0c75SAndroid Build Coastguard Worker                   ->key,
116*71db0c75SAndroid Build Coastguard Worker               &search_data[i]);
117*71db0c75SAndroid Build Coastguard Worker   }
118*71db0c75SAndroid Build Coastguard Worker   for (size_t i = 0; i < CAP / 7 * 5; ++i) {
119*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::hsearch({&search_data[i], nullptr}, FIND)->data,
120*71db0c75SAndroid Build Coastguard Worker               reinterpret_cast<void *>(i));
121*71db0c75SAndroid Build Coastguard Worker   }
122*71db0c75SAndroid Build Coastguard Worker   for (size_t i = CAP / 7 * 5; i < CAP; ++i) {
123*71db0c75SAndroid Build Coastguard Worker     ASSERT_EQ(LIBC_NAMESPACE::hsearch({&search_data[i], nullptr}, FIND)->data,
124*71db0c75SAndroid Build Coastguard Worker               reinterpret_cast<void *>(1000 + i));
125*71db0c75SAndroid Build Coastguard Worker   }
126*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::hdestroy();
127*71db0c75SAndroid Build Coastguard Worker }
128