### Build libcuckoo with Examples and Tests Source: https://github.com/efficient/libcuckoo/blob/master/README.md Builds the libcuckoo library, including examples and tests, and installs it to a local directory. Assumes you are in the 'build' directory. ```bash $ cmake -DCMAKE_INSTALL_PREFIX=../install -DBUILD_EXAMPLES=1 -DBUILD_TESTS=1 .. $ make all $ make install ``` -------------------------------- ### Complete libcuckoo C API Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md A comprehensive example demonstrating the initialization, insertion, searching, locking, iteration, and cleanup of a cuckoo table using the C API. ```c #include #include #include #define CUCKOO_TABLE_NAME int_str #define CUCKOO_KEY_TYPE int #define CUCKOO_MAPPED_TYPE const char * #include int main() { // Create table int_str_table *table = int_str_table_init(100); if (!table) { perror("Failed to create table"); return 1; } // Insert some values const char *val1 = "hello"; const char *val2 = "world"; int_str_table_insert(table, &(int){1}, &val1); int_str_table_insert(table, &(int){2}, &val2); // Search const char *found; if (int_str_table_find(table, &(int){1}, &found)) { printf("Found: %s\n", found); } // Lock and iterate int_str_table_locked_table *lt = int_str_table_lock_table(table); if (!lt) { perror("Failed to lock table"); return 1; } int_str_table_const_iterator *it = int_str_table_locked_table_cbegin(lt); int_str_table_const_iterator *end = int_str_table_locked_table_cend(lt); while (!int_str_table_const_iterator_equal(it, end)) { int k = *int_str_table_const_iterator_key(it); const char *v = *int_str_table_const_iterator_mapped(it); printf("%d -> %s\n", k, v); int_str_table_const_iterator_increment(it); } int_str_table_const_iterator_free(it); int_str_table_const_iterator_free(end); int_str_table_locked_table_free(lt); // Cleanup int_str_table_free(table); return 0; } ``` -------------------------------- ### Install CMake on Ubuntu Source: https://github.com/efficient/libcuckoo/blob/master/README.md Installs CMake on Ubuntu systems using apt-get. ```bash $ sudo apt-get update && sudo apt-get install cmake ``` -------------------------------- ### Install libcuckoo Targets and Configuration Files Source: https://github.com/efficient/libcuckoo/blob/master/libcuckoo/CMakeLists.txt Installs the library targets, export set, and configuration files for package management. ```cmake install(TARGETS libcuckoo EXPORT libcuckoo-targets) install(EXPORT libcuckoo-targets NAMESPACE libcuckoo:: DESTINATION ${libcuckoo_pkgloc} FILE "libcuckoo-targets.cmake") install(FILES libcuckoo-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/libcuckoo-config-version.cmake DESTINATION ${libcuckoo_pkgloc}) ``` -------------------------------- ### Add Static Library and Link libcuckoo Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt This example shows how to create a static library and link it against libcuckoo. ```cmake add_library(int_str_table STATIC int_str_table.cc) target_link_libraries(int_str_table libcuckoo) ``` -------------------------------- ### Install libcuckoo Header Files Source: https://github.com/efficient/libcuckoo/blob/master/libcuckoo/CMakeLists.txt Installs the public header files for the libcuckoo library to the include directory. ```cmake install( FILES cuckoohash_config.hh cuckoohash_map.hh cuckoohash_util.hh bucket_container.hh DESTINATION ${CMAKE_INSTALL_PREFIX}/include/libcuckoo ) ``` -------------------------------- ### Add Another Executable and Link libcuckoo Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt Another example of adding an executable and linking it to libcuckoo. ```cmake add_executable(hellohash hellohash.cc) target_link_libraries(hellohash libcuckoo) ``` -------------------------------- ### CUCKOO_TABLE_NAME Macro Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Example of defining the CUCKOO_TABLE_NAME macro, which sets the table's name and the prefix for generated functions. ```c #define CUCKOO_TABLE_NAME int_str_table // Generates: int_str_table_init, int_str_table_insert, etc. ``` -------------------------------- ### Add C Executable with Multiple Library Links Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt This example shows how to add a C executable and link it against multiple libraries, including custom ones. ```cmake add_executable(c_hash c_hash.c) target_link_libraries(c_hash int_str_table blob_blob_table) ``` -------------------------------- ### Bucket Memory Layout Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Illustrates the memory organization within a single bucket, showing the storage for key-value pairs, partial keys, and occupancy flags. This layout is fixed per bucket based on SLOT_PER_BUCKET. ```text Bucket 0: ├─ values_[0] — aligned storage for pair ├─ values_[1] — aligned storage for pair ├─ values_[2] — aligned storage for pair ├─ values_[3] — aligned storage for pair ├─ partials_[0..3] — uint8_t partial keys └─ occupied_[0..3] — bool occupancy flags Bucket 1: ├─ values_[0..3] ├─ partials_[0..3] └─ occupied_[0..3] ... ``` -------------------------------- ### CUCKOO_KEY_TYPE Macro Examples Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Examples demonstrating the definition of the CUCKOO_KEY_TYPE macro, specifying the C type for keys in the hash table. The key type must be copyable and comparable. ```c #define CUCKOO_KEY_TYPE int #define CUCKOO_KEY_TYPE uint64_t #define CUCKOO_KEY_TYPE struct my_key #define CUCKOO_KEY_TYPE const char * ``` -------------------------------- ### CMake Integration for libcuckoo Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Demonstrates how to integrate libcuckoo into a CMake build system, including setting the installation prefix and linking the library to a target. ```cmake cmake -DCMAKE_INSTALL_PREFIX=../install .. make install ``` ```cmake find_package(libcuckoo REQUIRED) target_link_libraries(myapp libcuckoo) ``` -------------------------------- ### Usage Example for load_factor_too_low Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Demonstrates how to use a cuckoohash_map and catch the load_factor_too_low exception, which might occur with a poorly distributed hash function. ```cpp #include #include int main() { libcuckoo::cuckoohash_map table; // Set strict load factor threshold table.minimum_load_factor(0.01); try { // Insert many items with a bad hash function // If hash function distributes poorly, might hit this exception for (int i = 0; i < 1000000; ++i) { table.insert(i, "value"); } } catch (const libcuckoo::load_factor_too_low &e) { std::cerr << "Hash function issue detected!\n"; std::cerr << "Load factor: " << e.load_factor() << "\n"; std::cerr << "Minimum allowed: " << table.minimum_load_factor() << "\n"; // Investigate hash function quality } return 0; } ``` -------------------------------- ### Manage Minimum Load Factor at Runtime Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Demonstrates getting the current minimum load factor, setting it to a stricter or more permissive value, and catching the `load_factor_too_low` exception. ```cpp // Get current minimum load factor double mlf = table.minimum_load_factor(); // Returns 0.05 // Set stricter minimum to catch hash problems faster table.minimum_load_factor(0.01); // Make more permissive for specific workloads table.minimum_load_factor(0.1); // Catch and handle try { table.insert(key, value); } catch (const libcuckoo::load_factor_too_low &e) { std::cerr << "Hash function issue detected at load factor: " << e.load_factor() << std::endl; } ``` -------------------------------- ### Custom Equality Function Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/types.md Example of a case-insensitive string equality function. Must be callable with two arguments of type const Key& and return a value convertible to bool. ```cpp struct CaseInsensitiveEqual { bool operator()(const std::string &a, const std::string &b) const { if (a.length() != b.length()) return false; for (size_t i = 0; i < a.length(); ++i) { if (std::tolower(a[i]) != std::tolower(b[i])) return false; } return true; } }; ``` -------------------------------- ### Move Constructor Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Demonstrates transferring ownership of locks from one locked_table to another using the move constructor. The source locked_table becomes inactive after the move. ```cpp auto lt1 = table.lock_table(); auto lt2 = std::move(lt1); // lt1 is no longer active after move ``` -------------------------------- ### Example: Catching maximum_hashpower_exceeded during rehash Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Illustrates catching the maximum_hashpower_exceeded exception when attempting to rehash a table to a size that exceeds the configured limit. ```cpp try { table.rehash(25); } catch (const libcuckoo::maximum_hashpower_exceeded &e) { size_t attempted = e.hashpower(); std::cout << "Requested hashpower 2^" << attempted << " exceeds limit\n"; } ``` -------------------------------- ### Example Usage with Aligned Allocator Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/types.md Demonstrates how to use a custom aligned allocator with libcuckoo hash tables for potential performance improvements, especially in concurrent scenarios. Ensure your aligned allocator meets C++ Allocator requirements. ```cpp // Example with aligned allocator using aligned_allocator = ... // Your aligned allocator type libcuckoo::cuckoohash_map, std::equal_to, aligned_allocator> table; ``` -------------------------------- ### CUCKOO_MAPPED_TYPE Macro Examples Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Examples showing how to define the CUCKOO_MAPPED_TYPE macro, which specifies the C type for values stored in the hash table. The value type must be copyable. ```c #define CUCKOO_MAPPED_TYPE double #define CUCKOO_MAPPED_TYPE size_t #define CUCKOO_MAPPED_TYPE struct my_value #define CUCKOO_MAPPED_TYPE const char * ``` -------------------------------- ### Usage Example: Limiting Table Size Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Demonstrates how to set a maximum hash power for a cuckoohash_map and catch the maximum_hashpower_exceeded exception when the limit is reached during insertions. ```cpp #include #include int main() { libcuckoo::cuckoohash_map table; // Limit table to maximum 2^20 buckets (1 million buckets) table.maximum_hashpower(20); try { // Insert items until we hit the limit for (int i = 0; i < 10000000; ++i) { table.insert(i, "value"); if (table.hashpower() == 20) { std::cout << "Approaching size limit\n"; } } } catch (const libcuckoo::maximum_hashpower_exceeded &e) { std::cerr << "Table size limit reached!\n"; std::cerr << "Attempted hashpower: " << e.hashpower() << "\n"; std::cerr << "Maximum allowed: " << table.maximum_hashpower() << "\n"; } return 0; } ``` -------------------------------- ### C API Error Handling Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md In the C wrapper, exceptions are converted to `errno` values. This example shows how to check `errno` after a C API call to handle potential errors like memory allocation failure (`ENOMEM`). ```c errno = 0; int_str_table_insert(table, &key, &value); if (errno == ENOMEM) { // Memory allocation failed } ``` -------------------------------- ### Unlock Method Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Shows how to manually unlock the table using the unlock() method. This invalidates the locked_table object, and subsequent operations on it are undefined. The method is idempotent. ```cpp auto lt = table.lock_table(); // Use locked table... lt.unlock(); // lt is no longer active ``` -------------------------------- ### Get Hashpower Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Returns the hashpower of the bucket_container, which is the logarithm base 2 of the number of buckets. ```cpp size_type hashpower() const ``` -------------------------------- ### Get Table Size and Capacity Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Retrieves the current number of elements in the table, its total capacity, and the current load factor. ```cpp size_t sz = table.size(); size_t cap = table.capacity(); double lf = table.load_factor(); ``` -------------------------------- ### Custom Hash Function Implementation Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/types.md Provides an example of a custom hash function for use with libcuckoo hash tables. This function must be callable with a key, return a std::size_t, and satisfy hash function requirements for uniform distribution. ```cpp struct CustomHash { size_t operator()(const std::string &key) const { size_t h = 0; for (char c : key) { h = h * 31 + c; } return h; } }; libcuckoo::cuckoohash_map table; ``` -------------------------------- ### Get Key Equality Function Instance Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the key equality function object used by the map instance. This is used to compare keys for equality. ```cpp auto eq = table.key_eq(); ``` -------------------------------- ### Memory Efficiency Tuning: Smaller Size and Explicit Reserve Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Configures the hash map for memory efficiency by starting with a smaller initial size and fewer slots per bucket. It allows for explicit control over capacity using the reserve method. ```cpp // Smaller initial size, fewer slots libcuckoo::cuckoohash_map table(1000); table.reserve(needed_size); // Explicit control ``` -------------------------------- ### is_active() Method Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Demonstrates checking if a locked_table object is still actively holding locks using the is_active() method. This is useful for verifying the state after operations like unlock() or move construction. ```cpp auto lt = table.lock_table(); assert(lt.is_active()); lt.unlock(); assert(!lt.is_active()); ``` -------------------------------- ### init() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Constructs and initializes a new hash table with a specified initial capacity. It returns a pointer to the newly allocated table or NULL if memory allocation fails. ```APIDOC ### init() ```c CUCKOO_TABLE_NAME *CUCKOO(_init)(size_t n) ``` Constructs a new table allocated to store at least `n` elements. | Parameter | Type | Description | |-----------|------|-------------| | n | `size_t` | Initial capacity (number of elements to reserve) | **Returns:** `CUCKOO_TABLE_NAME*` — Pointer to newly allocated table, or NULL on memory error (sets errno to ENOMEM) **Example:** ```c int_str_table *table = int_str_table_init(1000); if (table == NULL) { perror("Failed to allocate table"); return 1; } ``` ``` -------------------------------- ### Manage Maximum Hashpower Limit Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Shows how to set the table to allow unlimited expansion, set an explicit limit (e.g., 2^24 buckets), and check if a limit is currently set. ```cpp // Allow unlimited expansion (default) table.maximum_hashpower(libcuckoo::NO_MAXIMUM_HASHPOWER); // Set explicit limit to 2^24 buckets table.maximum_hashpower(24); // Check if limit is set if (table.maximum_hashpower() == libcuckoo::NO_MAXIMUM_HASHPOWER) { std::cout << "Table can expand without limit\n"; } ``` -------------------------------- ### Getting Element Range with equal_range() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Use `equal_range()` to get iterators to the beginning and end of the range of elements matching a specific key. If the key is not found, the iterators will be equal. ```cpp auto lt = table.lock_table(); auto [begin_it, end_it] = lt.equal_range(42); for (auto it = begin_it; it != end_it; ++it) { std::cout << it->second << std::endl; } ``` -------------------------------- ### Cross-Platform Alignment: Default and Aligned Allocator Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Demonstrates default alignment for x86_64 and how to use a custom aligned allocator for specific architectures to optimize cache-line performance. ```cpp // Default: optimized for x86_64 libcuckoo::cuckoohash_map table; // Aligned allocator for specific architectures using AlignedAlloc = __gnu_parallel::aligned_allocator< std::pair, 64>; libcuckoo::cuckoohash_map table; ``` -------------------------------- ### Get Allocator Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Returns the allocator instance used by the bucket_container. ```cpp allocator_type get_allocator() const ``` -------------------------------- ### Basic C Usage of libcuckoo Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Illustrates the C API for libcuckoo, demonstrating table initialization, insertion, lookup, and freeing resources. Requires defining table name, key type, and mapped type. ```c #define CUCKOO_TABLE_NAME int_str #define CUCKOO_KEY_TYPE int #define CUCKOO_MAPPED_TYPE const char * #include #include int main() { int_str_table *table = int_str_table_init(100); int key = 42; const char *value = "hello"; int_str_table_insert(table, &key, &value); const char *found; if (int_str_table_find(table, &key, &found)) { printf("Found: %s\n", found); } int_str_table_free(table); return 0; } ``` -------------------------------- ### Get Map Size Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the number of key-value pairs currently stored in the hash map. ```cpp size_t num_elements = table.size(); ``` -------------------------------- ### Get Maximum Worker Threads Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the maximum number of extra worker threads supported by the CuckooHash map. ```cpp size_type max_num_worker_threads() const ``` -------------------------------- ### Get Allocator Instance Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the allocator object associated with the map instance. This object manages memory allocations for the map. ```cpp auto alloc = table.get_allocator(); ``` -------------------------------- ### Define Multiple Table Interfaces in One File Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Demonstrates how to define multiple table types within the same compilation unit by undefining the configuration macros before including the template for each new table. ```c #define CUCKOO_TABLE_NAME int_str_table #define CUCKOO_KEY_TYPE int #define CUCKOO_MAPPED_TYPE const char * #include // Now undefine for next table #undef CUCKOO_TABLE_NAME #undef CUCKOO_KEY_TYPE #undef CUCKOO_MAPPED_TYPE // Define new table #define CUCKOO_TABLE_NAME str_int_table #define CUCKOO_KEY_TYPE const char * #define CUCKOO_MAPPED_TYPE int #include ``` -------------------------------- ### Creating a Table Interface Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md To use the C API, you must create a header file that defines table-specific macros (CUCKOO_TABLE_NAME, CUCKOO_KEY_TYPE, CUCKOO_MAPPED_TYPE) and then include the template header. This process generates a set of functions prefixed with the defined table name. ```APIDOC ## Creating a Table Interface To use the C API, you must create a header file that defines three macros and includes the template: ```c #ifndef MY_TABLE_H #define MY_TABLE_H // Define table name #define CUCKOO_TABLE_NAME my_int_str_table // Define key type #define CUCKOO_KEY_TYPE int // Define mapped value type #define CUCKOO_MAPPED_TYPE const char * // Include the template to generate the interface #include #endif // MY_TABLE_H ``` **Effect:** This generates the following functions with `my_int_str_table_` prefix: - `my_int_str_table_init()` - `my_int_str_table_insert()` - `my_int_str_table_find()` - etc. ``` -------------------------------- ### Link Libraries for Universal Benchmark Source: https://github.com/efficient/libcuckoo/blob/master/tests/universal-benchmark/CMakeLists.txt Links the necessary libraries (test_util, libcuckoo, pcg) to the universal benchmark executable. ```cmake target_link_libraries(universal_benchmark PRIVATE test_util PRIVATE libcuckoo PRIVATE pcg ) ``` -------------------------------- ### Get Bucket Count Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the total number of buckets currently present in the hash table. This value is always a power of two. ```cpp size_t buckets = table.bucket_count(); ``` -------------------------------- ### Basic C++ Usage of cuckoohash_map Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Demonstrates basic insertion, lookup, and update operations on a cuckoohash_map. Shows how to use locked_table for exclusive access and iteration. ```cpp #include #include #include int main() { // Create a hash table mapping int to string libcuckoo::cuckoohash_map table; // Insert elements table.insert(1, "one"); table.insert(2, "two"); // Search std::string value; if (table.find(1, value)) { std::cout << "Found: " << value << std::endl; } // Update table.update(1, "ONE"); // Concurrent access from multiple threads is safe // Lock-free operations for reads // For exclusive access, use locked_table { auto lt = table.lock_table(); for (const auto &kv : lt) { std::cout << kv.first << " -> " << kv.second << std::endl; } } return 0; } ``` -------------------------------- ### Handle Insertion Exceptions Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Demonstrates how to catch specific exceptions during table insertion, such as low load factor, maximum hashpower exceeded, or memory allocation failures. ```cpp try { table.insert(key, value); } catch (const libcuckoo::load_factor_too_low &e) { std::cerr << "Hash function issue at LF=" << e.load_factor() << "\n"; } catch (const libcuckoo::maximum_hashpower_exceeded &e) { std::cerr << "Table size limit reached\n"; } catch (const std::bad_alloc &) { std::cerr << "Out of memory\n"; } ``` -------------------------------- ### Generate Package Version File Source: https://github.com/efficient/libcuckoo/blob/master/libcuckoo/CMakeLists.txt Uses CMake's helper function to create a version file for package configuration, specifying compatibility. ```cmake write_basic_package_version_file( "libcuckoo-config-version.cmake" VERSION ${libcuckoo_VERSION} COMPATIBILITY AnyNewerVersion) ``` -------------------------------- ### Get Hash Function Instance Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the hash function object used by the map instance. This can be used to compute hash values for keys. ```cpp auto h = table.hash_function(); size_t hash_val = h(42); ``` -------------------------------- ### Get Slots Per Bucket Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the number of slots allocated within each hash bucket. This is a static method and does not require an instance of the map. ```cpp size_t slots = libcuckoo::cuckoohash_map::slot_per_bucket(); ``` -------------------------------- ### begin() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Returns an iterator pointing to the first element in the locked table. If the table is empty, it returns an iterator equivalent to `end()`. ```APIDOC ## begin() ### Description Returns an iterator to the beginning of the table. ### Returns - `iterator` or `const_iterator` — Iterator to first element, or end if empty ### Example ```cpp auto lt = table.lock_table(); for (auto it = lt.begin(); it != lt.end(); ++it) { std::cout << it->first << " -> " << it->second << std::endl; } ``` ``` -------------------------------- ### Get Size of Cuckoo Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Returns the current number of elements stored within the Cuckoo hash table. This reflects the active data count. ```c size_t CUCKOO(_size)(const CUCKOO_TABLE_NAME *tbl) ``` -------------------------------- ### Bucket Container Size and Capacity Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Provides methods to retrieve the number of buckets in the container. For bucket_container, size() and capacity() are equivalent. ```cpp // size() — Returns number of buckets // capacity() — Equivalent to size() for bucket_container ``` -------------------------------- ### Bucket Container Constructor Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Constructs a bucket_container with a specified hashpower and allocator. The hashpower determines the initial number of buckets (2^hp). ```cpp bucket_container(size_type hp, const allocator_type &allocator) ``` -------------------------------- ### Handling Expansion Failures During Insertion Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Implement a `try_insert` function to gracefully handle potential exceptions during insertion. This function catches `load_factor_too_low`, `maximum_hashpower_exceeded`, and `std::bad_alloc`, returning false if insertion fails. ```cpp bool try_insert(const Key &k, const Value &v) { try { table.insert(k, v); return true; } catch (const libcuckoo::load_factor_too_low &) { // Log issue with hash function log_warning("Hash function distribution issue"); return false; } catch (const libcuckoo::maximum_hashpower_exceeded &) { // Table at size limit log_info("Table at maximum configured size"); return false; } catch (const std::bad_alloc &) { // Memory exhausted log_error("Memory allocation failed"); return false; } } ``` -------------------------------- ### Define C Table Interface with Macros Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Create a C header file to define table-specific macros (name, key type, value type) and include the template header to generate the C API for a specific table. ```c #ifndef MY_TABLE_H #define MY_TABLE_H // Define table name #define CUCKOO_TABLE_NAME my_int_str_table // Define key type #define CUCKOO_KEY_TYPE int // Define mapped value type #define CUCKOO_MAPPED_TYPE const char * // Include the template to generate the interface #include #endif // MY_TABLE_H ``` -------------------------------- ### Get Bucket Count of Cuckoo Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Returns the total number of buckets in the Cuckoo hash table. This indicates the table's primary storage capacity. ```c size_t CUCKOO(_bucket_count)(const CUCKOO_TABLE_NAME *tbl) ``` -------------------------------- ### Get Minimum Load Factor Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the currently set minimum load factor for the hash map. This value influences when automatic table expansions are triggered. ```cpp double mlf = table.minimum_load_factor(); ``` -------------------------------- ### Define Universal Benchmark Executable Source: https://github.com/efficient/libcuckoo/blob/master/tests/universal-benchmark/CMakeLists.txt Defines the main executable for the universal benchmark, linking it to the source file 'universal_benchmark.cc'. ```cmake add_executable(universal_benchmark universal_benchmark.cc) ``` -------------------------------- ### Destructor Example Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Illustrates how the locked_table's destructor automatically releases all acquired locks when the object goes out of scope. This ensures locks are freed even if exceptions occur. ```cpp { auto lt = table.lock_table(); // Use locked table } // Destructor called, locks released ``` -------------------------------- ### Bounded Size Tuning: Limit Buckets and Early Problem Detection Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Limits the maximum number of buckets to control the table's size and sets a stricter minimum load factor to detect potential issues earlier. ```cpp table.maximum_hashpower(16); // Limit to 2^16 buckets table.minimum_load_factor(0.2); // Detect problems early ``` -------------------------------- ### Get Hashpower of Cuckoo Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Retrieves the hashpower, which is the base-2 logarithm of the bucket count, for a given Cuckoo table. This is useful for understanding the table's internal structure. ```c size_t CUCKOO(_hashpower)(const CUCKOO_TABLE_NAME *tbl) ``` ```c size_t hp = int_str_table_hashpower(table); printf("Hashpower: %zu\n", hp); ``` -------------------------------- ### Add Executable for Unit Tests Source: https://github.com/efficient/libcuckoo/blob/master/tests/unit-tests/CMakeLists.txt Configures the 'unit_tests' executable, listing all source files and headers required for the tests. ```cmake add_executable(unit_tests test_bucket_container.cc test_c_interface.cc test_constructor.cc test_hash_properties.cc test_heterogeneous_compare.cc test_iterator.cc test_locked_table.cc test_maximum_hashpower.cc test_minimum_load_factor.cc test_noncopyable_types.cc test_resize.cc test_user_exceptions.cc acutest.h test_runner.cc unit_test_util.cc unit_test_util.hh ) ``` -------------------------------- ### Get Load Factor Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Calculates and returns the current load factor of the hash map, which is the ratio of the number of elements to the total capacity. The value ranges from 0.0 to 1.0. ```cpp double lf = table.load_factor(); std::cout << "Load factor: " << lf << std::endl; ``` -------------------------------- ### Get Load Factor of Cuckoo Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Computes and returns the load factor of the Cuckoo hash table, which is the ratio of the number of elements to the total capacity. This metric indicates how full the table is. ```c double CUCKOO(_load_factor)(const CUCKOO_TABLE_NAME *tbl) ``` -------------------------------- ### Get Maximum Hashpower Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the current maximum hashpower setting for the table. This value defines the upper bound on the table's size in terms of powers of two for its bucket count. ```cpp size_t mhp = table.maximum_hashpower(); ``` -------------------------------- ### Add Static Library Source: https://github.com/efficient/libcuckoo/blob/master/tests/unit-tests/CMakeLists.txt Defines the 'int_int_table' as a static library and links it against the 'libcuckoo' library. ```cmake add_library(int_int_table STATIC int_int_table.cc) target_link_libraries(int_int_table libcuckoo) ``` -------------------------------- ### Using Explicit Sizing to Avoid Expansion Exceptions Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Explicitly reserve space in the hash table using `reserve()` to minimize the likelihood of exceptions during insertions. If `maximum_hashpower_exceeded` is caught, you can adjust the maximum hash power and retry reservation. ```cpp // Avoid automatic expansion exceptions try { table.reserve(expected_element_count); } catch (const libcuckoo::maximum_hashpower_exceeded &e) { // Handle gracefully or adjust maximum table.maximum_hashpower(e.hashpower() + 1); table.reserve(expected_element_count); } // Now insertions are less likely to need expansion for (const auto &item : items) { table.insert(item.first, item.second); } ``` -------------------------------- ### Get Map Capacity Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Retrieves the total capacity of the hash map, calculated as the product of bucket count and slots per bucket. This represents the maximum number of elements the map can hold before resizing. ```cpp size_t cap = table.capacity(); ``` -------------------------------- ### Initialize Cuckoo Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Initializes a new Cuckoo hash table with a specified capacity. Returns a pointer to the table or NULL if memory allocation fails. ```c int_str_table *table = int_str_table_init(1000); if (table == NULL) { perror("Failed to allocate table"); return 1; } ``` -------------------------------- ### Handling std::bad_alloc during Table Creation Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Demonstrates catching std::bad_alloc when a cuckoohash_map is constructed with a size that exceeds available memory. ```cpp try { libcuckoo::cuckoohash_map table(1000000000); } catch (const std::bad_alloc &e) { std::cerr << "Allocation failed: " << e.what() << "\n"; } ``` -------------------------------- ### Get Capacity of Cuckoo Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Calculates and returns the total capacity of the Cuckoo hash table, defined as the product of buckets and slots per bucket. This represents the maximum number of elements it can hold without resizing. ```c size_t CUCKOO(_capacity)(const CUCKOO_TABLE_NAME *tbl) ``` -------------------------------- ### Declare Cuckoo Hash Map with Default and Custom Sizes Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Shows default construction, explicit size reservation, and creation of a very small table. ```cpp // Default construction: reserves space for ~262,144 elements libcuckoo::cuckoohash_map table; // Explicit size: override default libcuckoo::cuckoohash_map table(500000); // Reserve 500k+ elements // Minimum size: can still be much smaller libcuckoo::cuckoohash_map table(100); // Very small table ``` -------------------------------- ### load_factor_too_low Constructor and Methods Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Details the constructor and member functions (what, load_factor) of the load_factor_too_low exception class. ```cpp load_factor_too_low(const double lf) noexcept ``` ```cpp virtual const char *what() const noexcept override ``` ```cpp double load_factor() const noexcept ``` ```cpp try { table.insert(key, value); } catch (const libcuckoo::load_factor_too_low &e) { double lf = e.load_factor(); std::cout << "Triggered at load factor: " << lf << std::endl; } ``` -------------------------------- ### Reserving Space with reserve() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Use `reserve()` to ensure the table has enough capacity for a specified number of elements. This can help avoid reallocations during subsequent insertions. It may throw `maximum_hashpower_exceeded`. ```cpp auto lt = table.lock_table(); lt.reserve(100000); ``` -------------------------------- ### Hash Table Construction with Initial Capacity Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Create a cuckoohash_map and specify an initial capacity to reserve space for a given number of elements. ```cpp // With initial capacity libcuckoo::cuckoohash_map table(1000000); ``` -------------------------------- ### Set C Standard for Target Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt This snippet demonstrates how to set the C standard version for a specific target. ```cmake set_property(TARGET c_hash PROPERTY C_STANDARD 99) ``` -------------------------------- ### Recovering from Maximum Hashpower Exceeded Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/errors.md Shows three strategies for handling the maximum_hashpower_exceeded exception: increasing the limit, removing the limit, or failing gracefully. ```cpp try { table.insert(key, value); } catch (const libcuckoo::maximum_hashpower_exceeded &e) { // Option 1: Increase the limit (if possible) table.maximum_hashpower(e.hashpower() + 1); table.insert(key, value); // Retry // Option 2: Remove the limit table.maximum_hashpower(libcuckoo::NO_MAXIMUM_HASHPOWER); table.insert(key, value); // Retry // Option 3: Fail gracefully std::cerr << "Cannot expand beyond configured limit\n"; return false; } ``` -------------------------------- ### Add Executable for Frequency Counting Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt This snippet demonstrates adding an executable for frequency counting and linking it with libcuckoo. ```cmake add_executable(count_freq count_freq.cc) target_link_libraries(count_freq libcuckoo) ``` -------------------------------- ### Set Include Directories for libcuckoo Source: https://github.com/efficient/libcuckoo/blob/master/libcuckoo/CMakeLists.txt Configures the include directories for the libcuckoo library, specifying build-time and install-time paths. ```cmake target_include_directories(libcuckoo INTERFACE $ $) ``` -------------------------------- ### Register libcuckoo GDB Printers Source: https://github.com/efficient/libcuckoo/blob/master/libcuckoo-gdb-printers/README.md Add this Python code to your ~/.gdbinit file to enable pretty-printing for libcuckoo hash maps in GDB. Ensure the path to the printers directory is correct. ```python import sys sys.path.insert(0, '/path/to/libcuckoo/libcuckoo-gdb-printers') from libcuckoo.printers import register_libcuckoo_printers register_libcuckoo_printers (None) ``` -------------------------------- ### Set Compile Options for Universal Benchmark Source: https://github.com/efficient/libcuckoo/blob/master/tests/universal-benchmark/CMakeLists.txt Sets compile-time options for the universal benchmark, including key, value, and table types. Conditionally adds tracking allocator option. ```cmake target_compile_options(universal_benchmark PRIVATE -DKEY=${UNIVERSAL_KEY} PRIVATE -DVALUE=${UNIVERSAL_VALUE} PRIVATE -D${UNIVERSAL_TABLE} ) if(UNIVERSAL_TRACKING_ALLOCATOR) target_compile_options(universal_benchmark PRIVATE -DTRACKING_ALLOCATOR) endif() ``` -------------------------------- ### read() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Reads a serialized hash table from a given file pointer and constructs a new table. This operation is only supported if the key and value types are Plain Old Data (POD). ```APIDOC ### read() ```c CUCKOO_TABLE_NAME *CUCKOO(_read)(FILE *fp) ``` Reads a serialized table from a file and constructs a new table. Only works if key and value types are POD (Plain Old Data). | Parameter | Type | Description | |-----------|------|-------------| | fp | `FILE*` | File pointer opened in binary read mode | **Returns:** `CUCKOO_TABLE_NAME*` — New table, or NULL on error **Example:** ```c FILE *fp = fopen("table.bin", "rb"); if (!fp) { perror("Cannot open file"); return 1; } int_str_table *table = int_str_table_read(fp); fclose(fp); ``` ``` -------------------------------- ### Declare Cuckoo Hash Map with Custom Slots Per Bucket Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Demonstrates declaring a cuckoohash_map with default, 8, and 2 slots per bucket using template parameters. ```cpp // Default: 4 slots per bucket libcuckoo::cuckoohash_map table; // Custom: 8 slots per bucket libcuckoo::cuckoohash_map, std::equal_to, std::allocator>, 8> table_8slot; // Custom: 2 slots per bucket libcuckoo::cuckoohash_map, std::equal_to, std::allocator>, 2> table_2slot; ``` -------------------------------- ### load_factor_too_low Exception Class Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/types.md Thrown when automatic expansion is triggered but the load factor is below the minimum threshold. Indicates potential issues with hash function distribution or adversarial workloads. ```cpp class load_factor_too_low : public std::exception ``` ```cpp load_factor_too_low(const double lf) noexcept ``` ```cpp virtual const char *what() const noexcept override ``` ```cpp double load_factor() const noexcept ``` ```cpp table.minimum_load_factor(0.1); try { // Operations that trigger expansion... table.insert(key, value); } catch (const libcuckoo::load_factor_too_low &e) { std::cerr << "Load factor too low: " << e.load_factor() << std::endl; std::cerr << "Possible bad hash function or adversarial input\n"; } ``` -------------------------------- ### insert() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Inserts a new key-value pair into the hash table. If the key already exists, the insertion fails. ```APIDOC ## insert() ### Description Inserts the key-value pair into the table. ### Method Signature ```cpp template bool insert(K &&key, Args &&...val) ``` ### Parameters #### Path Parameters - **key** (K&&): Key to insert - **val** (Args&&...): Constructor arguments for value ### Returns - **bool**: true if a new key was inserted, false if key already existed ### Example ```cpp if (table.insert(42, "hello")) { std::cout << "Inserted\n"; } else { std::cout << "Key already existed\n"; } ``` ``` -------------------------------- ### Bucket Container Copy Constructor Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Creates a copy of an existing bucket_container, optionally specifying an allocator for the new container. ```cpp bucket_container(const bucket_container &bc) bucket_container(const bucket_container &bc, const allocator_type &a) ``` -------------------------------- ### Construct Cuckoo Hash Map with Initializer List Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Constructs a cuckoohash_map using an initializer list for initial key-value pairs. Optional parameters allow specifying initial size, hash function, key equality function, and allocator. ```cpp libcuckoo::cuckoohash_map table = {{1, "a"}, {2, "b"}}; ``` -------------------------------- ### Add Executable and Link libcuckoo Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt This snippet shows how to add an executable target and link it against the libcuckoo library. ```cmake add_executable(nested_table nested_table.cc) target_link_libraries(nested_table libcuckoo) ``` -------------------------------- ### Basic Insertion Operation Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Performs a standard insertion of a key-value pair into the hash table. Returns true if insertion was successful, false otherwise. ```cpp bool inserted = table.insert(key, value); ``` -------------------------------- ### Define Test Utility Library Source: https://github.com/efficient/libcuckoo/blob/master/tests/CMakeLists.txt Defines an INTERFACE library for test utilities and specifies include directories for build and binary targets. ```cmake add_library(test_util INTERFACE) target_include_directories(test_util INTERFACE $ $ ) ``` -------------------------------- ### Range-based for loop on Locked Table Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/locked_table.md Shows how to use range-based for loops for iterating over a locked table. This provides a more concise syntax for accessing key-value pairs. ```cpp auto lt = table.lock_table(); for (const auto &kv : lt) { std::cout << kv.first << " -> " << kv.second << std::endl; } ``` -------------------------------- ### Compile with C++11 Support Source: https://github.com/efficient/libcuckoo/blob/master/README.md Enables C++11 features for compilers like g++ and clang++. For clang++, it also specifies the libc++ standard library. ```bash g++: -std=c++11 clang++: -std=c++11 -stdlib=libc++ ``` -------------------------------- ### Default Hash Table Construction Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Construct a cuckoohash_map with default settings for hash function, equality comparison, and allocator. ```cpp libcuckoo::cuckoohash_map table; ``` -------------------------------- ### Throughput Tuning: Larger Table and Slots Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Optimizes for high throughput by initializing the table with a larger capacity and using more slots per bucket. It also increases the number of worker threads for parallel resizing. ```cpp // Larger table initially, more slots per bucket libcuckoo::cuckoohash_map table(1000000); table.minimum_load_factor(0.1); // More permissive table.max_num_worker_threads(4); // Parallel resizing ``` -------------------------------- ### Checking for Memory Allocation Failures Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Illustrates how to check the `errno` variable after memory allocation functions to detect and handle `ENOMEM` errors. ```c errno = 0; int_str_table *table = int_str_table_init(1000000000); if (table == NULL && errno == ENOMEM) { perror("Allocation failed"); } ``` -------------------------------- ### Add Blob Blob Table Library Source: https://github.com/efficient/libcuckoo/blob/master/examples/CMakeLists.txt This snippet illustrates adding a static library for blob-to-blob table functionality and linking it with libcuckoo. ```cmake add_library(blob_blob_table STATIC blob_blob_table.cc) target_link_libraries(blob_blob_table libcuckoo) ``` -------------------------------- ### Include Header-Only Library Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Shows the required include statement for using the libcuckoo header-only library in a C++ project. ```cpp #include ``` -------------------------------- ### swap() Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Exchanges the contents of this cuckoo hash map with another one. ```APIDOC ## swap() ### Description Exchanges the contents of the map with those of another map. ### Method Signature ```cpp void swap(cuckoohash_map &other) noexcept ``` ### Example ```cpp table1.swap(table2); std::swap(table1, table2); // Also supported via std::swap ``` ``` -------------------------------- ### Custom Allocator for Bucket Storage Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/bucket_container.md Demonstrates how to provide a custom allocator, AlignedAllocator, to libcuckoo's cuckoohash_map for specialized memory management of bucket storage. This allows for control over allocation and deallocation strategies. ```cpp // Custom allocator for aligned allocation struct AlignedAllocator { void *allocate(size_t n); void deallocate(void *p, size_t n); // ... other allocator methods ... }; libcuckoo::cuckoohash_map table; ``` -------------------------------- ### Exception Safety and Error Handling Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/c-api.md Details on how the C API handles memory failures and other exceptions, including setting `errno` and recommended practices for checking errors. ```APIDOC ## Exception Safety ### Memory Failures All functions that allocate memory (e.g., `init`, `lock_table`, `insert`, `upsert`, `rehash`, `reserve`, `locked_table::insert`, `locked_table::rehash`, `locked_table::reserve`) set `errno` to `ENOMEM` on allocation failure and return `NULL` or `false`. ### Other Failures Exceptions like `load_factor_too_low` and `maximum_hashpower_exceeded` set `errno` to `EINVAL`. ### Check errno ```c errno = 0; int_str_table *table = int_str_table_init(1000000000); if (table == NULL && errno == ENOMEM) { perror("Allocation failed"); } ``` ``` -------------------------------- ### Find Element and Copy Value Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/api-reference/cuckoohash_map.md Searches for a key and copies its associated value into a provided reference. Returns true if found, false otherwise. Use when you need to retrieve a value and handle the not-found case explicitly. ```cpp template bool find(const K &key, mapped_type &val) const ``` ```cpp std::string value; if (table.find(42, value)) { std::cout << "Found: " << value << std::endl; } ``` -------------------------------- ### Hash Table Construction with Custom Hash and Equality Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/configuration.md Instantiate a cuckoohash_map using custom hash and equality function objects for key comparison. ```cpp struct MyHash { size_t operator()(int k) const { return k * 2654435761U; } }; struct MyEqual { bool operator()(int a, int b) const { return a == b; } }; libcuckoo::cuckoohash_map table; ``` -------------------------------- ### Set PCG Include Directories Source: https://github.com/efficient/libcuckoo/blob/master/tests/pcg/CMakeLists.txt Configures the include directories for the PCG library, relative to the source directory. ```cmake target_include_directories(pcg INTERFACE $ ) ``` -------------------------------- ### Recommended Clang Compiler Flags Source: https://github.com/efficient/libcuckoo/blob/master/_autodocs/README.md Provides recommended compiler flags for Clang when building a C++ program with libcuckoo, including C++ standard, standard library, optimization level, and threading support. ```bash clang++ -std=c++11 -stdlib=libc++ -O3 -pthread myprogram.cpp ```