//===-- Resizable Monotonic HashTable ---------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H #define LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H #include "include/llvm-libc-types/ENTRY.h" #include "src/__support/CPP/bit.h" // bit_ceil #include "src/__support/CPP/new.h" #include "src/__support/HashTable/bitmask.h" #include "src/__support/hash.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" #include "src/__support/memory_size.h" #include "src/string/memset.h" #include "src/string/strcmp.h" #include "src/string/strlen.h" #include <stddef.h> #include <stdint.h> namespace LIBC_NAMESPACE_DECL { namespace internal { LIBC_INLINE uint8_t secondary_hash(uint64_t hash) { … } // Probe sequence based on triangular numbers, which is guaranteed (since our // table size is a power of two) to visit every group of elements exactly once. // // A triangular probe has us jump by 1 more group every time. So first we // jump by 1 group (meaning we just continue our linear scan), then 2 groups // (skipping over 1 group), then 3 groups (skipping over 2 groups), and so on. // // If we set sizeof(Group) to be one unit: // T[k] = sum {1 + 2 + ... + k} = k * (k + 1) / 2 // It is provable that T[k] mod 2^m generates a permutation of // 0, 1, 2, 3, ..., 2^m - 2, 2^m - 1 // Detailed proof is available at: // https://fgiesen.wordpress.com/2015/02/22/triangular-numbers-mod-2n/ struct ProbeSequence { … }; // The number of entries is at least group width: we do not // need to do the fixup when we set the control bytes. // The number of entries is at least 8: we don't have to worry // about special sizes when check the fullness of the table. LIBC_INLINE size_t capacity_to_entries(size_t cap) { … } // The heap memory layout for N buckets HashTable is as follows: // // ======================= // | N * Entry | // ======================= <- align boundary // | Header | // ======================= <- align boundary (for fast resize) // | (N + 1) * Byte | // ======================= // // The trailing group part is to make sure we can always load // a whole group of control bytes. struct HashTable { … }; } // namespace internal } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC___SUPPORT_HASHTABLE_TABLE_H