1 | //===-- Implementation of hsearch -------------------------------*- C++ -*-===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "src/search/hsearch.h" |
10 | #include "src/__support/HashTable/randomness.h" |
11 | #include "src/__support/HashTable/table.h" |
12 | #include "src/errno/libc_errno.h" |
13 | #include "src/search/hsearch/global.h" |
14 | |
15 | namespace LIBC_NAMESPACE { |
16 | LLVM_LIBC_FUNCTION(ENTRY *, hsearch, (ENTRY item, ACTION action)) { |
17 | ENTRY *result; |
18 | if (internal::global_hash_table == nullptr) { |
19 | // If global_hash_table is null, we create a new hash table with a minimal |
20 | // capacity. Such hashtable will be expanded as needed. |
21 | uint64_t randomness = internal::randomness::next_random_seed(); |
22 | internal::global_hash_table = internal::HashTable::allocate(capacity: 0, randomness); |
23 | } |
24 | |
25 | // In rare cases, the global hashtable may still fail to allocate. We treat it |
26 | // as ESRCH or ENOMEM depending on the action. |
27 | switch (action) { |
28 | case FIND: |
29 | result = internal::global_hash_table |
30 | ? internal::global_hash_table->find(key: item.key) |
31 | : nullptr; |
32 | if (result == nullptr) { |
33 | libc_errno = ESRCH; |
34 | } |
35 | break; |
36 | case ENTER: |
37 | result = |
38 | internal::global_hash_table |
39 | ? internal::HashTable::insert(table&: internal::global_hash_table, item) |
40 | : nullptr; |
41 | if (result == nullptr) { |
42 | libc_errno = ENOMEM; |
43 | } |
44 | break; |
45 | } |
46 | return result; |
47 | } |
48 | |
49 | } // namespace LIBC_NAMESPACE |
50 |