Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable length key support and major template refactoring to support key as a template parameter #661

Closed

Conversation

thompsonbry
Copy link

@thompsonbry thompsonbry commented Jan 27, 2025

See #600
See #634
See #613
See #610

Note: test_art_span.cpp is disabled. This has the tests for variable length keys. It will remain disabled until we merge and then branch again. Right now the focus is to get the key template refactor back to mainline.

@coderabbitai pause
@coderabbitai resolve
@coderabbitai ignore

Summary by CodeRabbit

Release Notes

  • New Features

    • Added template support for database keys, enabling more flexible key handling
    • Introduced key encoding and decoding utilities for various integer types
    • Enhanced support for variable-length keys in Adaptive Radix Tree (ART) implementation
  • Performance Improvements

    • Optimized key comparison and handling across database operations
    • Improved memory management for key buffers
  • Bug Fixes

    • Resolved potential issues with key type conversions
    • Enhanced type safety in database operations
  • Testing

    • Added comprehensive test suite for key encoding, decoding, and ART operations
    • Expanded test coverage for different database implementations
  • Refactoring

    • Migrated from custom key type to standard std::uint64_t
    • Updated namespace and template structures
    • Improved code organization and type handling
  • Documentation

    • Updated copyright notices
    • Added clarifying comments in code

Copy link

coderabbitai bot commented Jan 27, 2025

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Walkthrough

This pull request introduces a comprehensive refactoring of the UnoDB library, focusing on enhancing type flexibility and standardizing key handling across the codebase. The primary change is the introduction of template-based key handling, moving from a fixed unodb::key type to a more generic approach using std::uint64_t and key_view. This modification affects multiple components, including database classes, iterators, benchmarks, and test suites, ensuring consistent key type management throughout the project.

Changes

File Change Summary
.gitignore Added entries for cf_off.sh, cf_on.sh, compile1.sh, and /docs/ directory
CMakeLists.txt Removed -Wmissing-declarations warning flag
art.cpp, art.hpp, art_common.hpp, etc. Extensive template modifications for key handling, introducing Key template parameter across multiple classes
Benchmark files Updated benchmark templates to use new database types with std::uint64_t keys
Test files Introduced new test suites for key encoding, decoding, and span operations

Sequence Diagram

sequenceDiagram
    participant DB as Database<Key>
    participant Encoder as Key Encoder
    participant Decoder as Key Decoder

    DB->>Encoder: Encode key
    Encoder-->>DB: Encoded binary key
    DB->>Decoder: Decode key
    Decoder-->>DB: Original key
Loading

Possibly related PRs

Poem

🐰 Hopping through code with glee,
Keys now dance more freely!
Templates bloom like spring's delight,
Uint64 takes its coding flight!
Adaptive radix, now more bright! 🌱

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 38

🔭 Outside diff range comments (3)
art.cpp (1)

Line range hint 34-53: Well-structured debug routine with potential clarity improvements

This templated debug method provides good insights into the iterator's internal state by copying the stack before printing. Since this is analytics/diagnostics code, its performance impact is minimal and mostly acceptable. Consider:

  1. Refactor for clarity: This function has a long loop and multiple output statements. Extracting small helper functions (e.g., a function to print stack entries) could improve readability.
  2. Consider concurrency states: If the underlying data structure can be mutated by other threads, double-check that copying the stack is sufficient to keep the debug output consistent.
benchmark/micro_benchmark_key_prefix.cpp (1)

Line range hint 170-174: Consider adding range-based validation for keys.

The insert_keys function could benefit from input validation to ensure keys are within expected ranges.

 void insert_keys(Db &test_db, const std::vector<std::uint64_t> &keys) {
+  for (const auto k : keys) {
+    if (k > std::numeric_limits<std::uint64_t>::max()) {
+      throw std::out_of_range("Key value exceeds maximum allowed value");
+    }
     unodb::benchmark::insert_key(test_db, k,
                                 unodb::value_view{unodb::benchmark::value100});
   }
 }
test/test_art_iter.cpp (1)

Line range hint 539-683: Consider using test fixtures for common tree structures.

While the tests are comprehensive, consider:

  1. Creating fixtures for common tree structures to reduce setup code duplication
  2. Using constants for test values instead of magic numbers
  3. Moving debug output to a test utility
+ class ThreeLeavesTreeFixture : public ::testing::Test {
+ protected:
+   static constexpr std::uint64_t k0 = 0xaa10;
+   static constexpr std::uint64_t k1 = 0xaa20;
+   static constexpr std::uint64_t k2 = 0xaa30;
+   
+   void SetUp() override {
+     verifier.insert(k0, unodb::test::test_values[0]);
+     verifier.insert(k1, unodb::test::test_values[1]);
+     verifier.insert(k2, unodb::test::test_values[2]);
+   }
+   
+   unodb::test::tree_verifier<TypeParam> verifier;
+ };
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 680ff72 and 7968d48.

📒 Files selected for processing (40)
  • .gitignore (1 hunks)
  • CMakeLists.txt (3 hunks)
  • art.cpp (2 hunks)
  • art.hpp (19 hunks)
  • art_common.cpp (2 hunks)
  • art_common.hpp (1 hunks)
  • art_internal.cpp (2 hunks)
  • art_internal.hpp (3 hunks)
  • art_internal_impl.hpp (45 hunks)
  • benchmark/micro_benchmark.cpp (13 hunks)
  • benchmark/micro_benchmark_concurrency.hpp (6 hunks)
  • benchmark/micro_benchmark_key_prefix.cpp (8 hunks)
  • benchmark/micro_benchmark_mutex.cpp (2 hunks)
  • benchmark/micro_benchmark_n16.cpp (2 hunks)
  • benchmark/micro_benchmark_n256.cpp (2 hunks)
  • benchmark/micro_benchmark_n4.cpp (5 hunks)
  • benchmark/micro_benchmark_n48.cpp (2 hunks)
  • benchmark/micro_benchmark_node_utils.hpp (18 hunks)
  • benchmark/micro_benchmark_olc.cpp (2 hunks)
  • benchmark/micro_benchmark_utils.cpp (2 hunks)
  • benchmark/micro_benchmark_utils.hpp (7 hunks)
  • examples/example_art.cpp (3 hunks)
  • examples/example_art_stats.cpp (1 hunks)
  • examples/example_olc_art.cpp (1 hunks)
  • mutex_art.cpp (1 hunks)
  • mutex_art.hpp (8 hunks)
  • olc_art.cpp (2 hunks)
  • olc_art.hpp (20 hunks)
  • portability_builtins.hpp (1 hunks)
  • test/CMakeLists.txt (3 hunks)
  • test/db_test_utils.cpp (2 hunks)
  • test/db_test_utils.hpp (12 hunks)
  • test/test_art.cpp (1 hunks)
  • test/test_art_concurrency.cpp (8 hunks)
  • test/test_art_iter.cpp (21 hunks)
  • test/test_art_key.cpp (1 hunks)
  • test/test_art_oom.cpp (4 hunks)
  • test/test_art_scan.cpp (37 hunks)
  • test/test_art_span.cpp (1 hunks)
  • test/test_key_encode_decode.cpp (1 hunks)
🧰 Additional context used
🪛 GitHub Check: CodeFactor
mutex_art.cpp

[notice] 1-1: mutex_art.cpp#L1
mutex_art.cpp should include its header file mutex_art.HPP. (build/include)

test/db_test_utils.cpp

[notice] 1-1: test/db_test_utils.cpp#L1
test/db_test_utils.cpp should include its header file test/db_test_utils.hpp. (build/include)

test/db_test_utils.hpp

[notice] 501-501: test/db_test_utils.hpp#L501
Should have a space between // and comment. (whitespace/comments)


[notice] 494-494: test/db_test_utils.hpp#L494
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 505-505: test/db_test_utils.hpp#L505
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)

art_internal.hpp

[notice] 229-229: art_internal.hpp#L229
Missing space after ,. (whitespace/comma)


[notice] 252-252: art_internal.hpp#L252
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 535-535: art_internal.hpp#L535
Redundant blank line at the end of a code block should be deleted. (whitespace/blank_line)

mutex_art.hpp

[notice] 94-94: mutex_art.hpp#L94
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)

olc_art.hpp

[notice] 208-208: olc_art.hpp#L208
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 2055-2055: olc_art.hpp#L2055
Should have a space between // and comment. (whitespace/comments)


[notice] 1834-1982: olc_art.hpp#L1834-L1982
Complex Method


[notice] 2335-2591: olc_art.hpp#L2335-L2591
Complex Method

test/test_art_span.cpp

[notice] 47-47: test/test_art_span.cpp#L47
At least two spaces is best between code and comments. (whitespace/comments)


[notice] 158-158: test/test_art_span.cpp#L158
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 91-91: test/test_art_span.cpp#L91
Missing space after ,. (whitespace/comma)

art.hpp

[notice] 94-94: mutex_art.hpp#L94
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 158-158: art.hpp#L158
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 164-164: art.hpp#L164
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 208-208: olc_art.hpp#L208
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


[notice] 987-987: art.hpp#L987
Redundant blank line at the start of a code block should be deleted. (whitespace/blank_line)


[notice] 1007-1007: art.hpp#L1007
Should have a space between // and comment. (whitespace/comments)


[notice] 945-945: art.hpp#L945
Should have a space between // and comment. (whitespace/comments)

art_internal_impl.hpp

[notice] 129-129: art_internal_impl.hpp#L129
Redundant blank line at the start of a code block should be deleted. (whitespace/blank_line)


[notice] 621-621: art_internal_impl.hpp#L621
Do not leave a blank line after "public:". (whitespace/blank_line)


[notice] 1819-1819: art_internal_impl.hpp#L1819
Lines should be <= 80 characters long. (whitespace/line_length)


[notice] 2742-2742: art_internal_impl.hpp#L2742
Lines should be <= 80 characters long. (whitespace/line_length)

🪛 Cppcheck (2.10-2)
test/test_key_encode_decode.cpp

[error] 85-85: There is an unknown macro here somewhere. Configuration is required. If UNODB_DETAIL_DISABLE_CLANG_WARNING is a macro then please configure it.

(unknownMacro)

test/test_art_key.cpp

[error] 85-85: There is an unknown macro here somewhere. Configuration is required. If UNODB_DETAIL_DISABLE_CLANG_WARNING is a macro then please configure it.

(unknownMacro)

art_internal.cpp

[style] 31-31: The function 'dump_key' is never used.

(unusedFunction)


[style] 44-44: The function 'dump_val' is never used.

(unusedFunction)

test/test_art_iter.cpp

[error] 85-85: There is an unknown macro here somewhere. Configuration is required. If UNODB_DETAIL_DISABLE_CLANG_WARNING is a macro then please configure it.

(unknownMacro)

benchmark/micro_benchmark_utils.cpp

[style] 26-26: The function 'destroy_tree' is never used.

(unusedFunction)

test/test_art_span.cpp

[error] 85-85: There is an unknown macro here somewhere. Configuration is required. If UNODB_DETAIL_DISABLE_CLANG_WARNING is a macro then please configure it.

(unknownMacro)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (109)
.gitignore (2)

53-54: Consider version controlling the shell scripts.

The shell scripts cf_off.sh, cf_on.sh, and compile1.sh appear to be build or configuration related. If these scripts are part of the build process or developer workflow, they should be version controlled to ensure consistency across the team.

Please clarify if these are:

  1. Developer-specific workflow scripts (in which case they should stay in .gitignore)
  2. Part of the build process (in which case they should be version controlled)

Also applies to: 57-57


57-58: Verify the intention behind ignoring the docs directory.

Documentation is typically version controlled to maintain a history of changes and ensure all developers have access to the latest documentation. If /docs/ contains generated documentation, consider:

  1. Version controlling the source documentation
  2. Creating a specific ignore pattern for generated docs (e.g., /docs/generated/)
✅ Verification successful

Ignoring the docs directory is correct for Doxygen-generated documentation

The presence of a Doxyfile confirms this is a C++ project using Doxygen for documentation generation. It's standard practice to ignore the generated documentation directory while keeping the source documentation (code comments) and Doxfile under version control. The documentation can be regenerated at any time from these versioned sources.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if docs directory exists and what type of files it contains
# to determine if these are source docs or generated docs

# Check if docs directory exists
if [ -d "docs" ]; then
    echo "Contents of docs directory:"
    find docs -type f -exec file {} \;
fi

Length of output: 17


Script:

#!/bin/bash
# Search for documentation tool configurations and references
echo "=== Searching for documentation tool configurations ==="
fd -e yaml -e yml -e json -e js -e toml | xargs rg -l "docs?|documentation" || true

echo -e "\n=== Searching for documentation generation patterns ==="
rg -i "generate.*docs?|docs?.*generate" || true

echo -e "\n=== Checking recent git history for docs directory ==="
git log --diff-filter=D --summary | rg "delete.*docs/" || true

Length of output: 3071

art.cpp (2)

60-61: Convenience overload looks fine

This simple overload that redirects to std::cerr is straightforward and clear. No further changes needed.


68-70: Template instantiations appear consistent

The explicit instantiations for std::uint64_t and unodb::key_view are aligned with the new variable-length key support. This ensures the templated class is available to the linker for these key types.

olc_art.cpp (3)

Line range hint 38-59: Robust iterator dump, but TODO comment needs action

The debug logic here is similar to art.cpp. It prints valuable iterator state and versioning. The TODO reminds us to dump actual variable-length key bytes. Consider addressing it soon to maintain consistency with the refactor objective of supporting variable-length keys.

Would you like assistance in dumping those prefix bytes to help debug variable-length keys?


68-70: No issues with the convenience method

Redirecting the dump to standard error is consistent with the approach in art.cpp. No issues noted.


78-79: Template instantiations for OLC DB

By explicitly instantiating olc_db for both std::uint64_t and unodb::key_view, the codebase aligns with the new variable-length key support. This is presumably needed for linking.

art_internal.cpp (4)

16-16: Header inclusion is justified

Including "heap.hpp" is appropriate, as the code now calls allocate_aligned and free_aligned. No issues found.


44-49: Value dump logic is consistent

dump_val outputs the value in hex, mirroring dump_key. Though static analysis flags it as unused, it can be retained for on-demand debugging. No immediate issues found.

🧰 Tools
🪛 Cppcheck (2.10-2)

[style] 44-44: The function 'dump_val' is never used.

(unusedFunction)


51-60: Specialized basic_art_key::dump usage is acceptable

These explicit specializations ensure that each key type can be dumped via std::cerr. This is a good approach for debugging. No further action needed.


61-75: Capacity expansion function is correct but deserves bounds check

The logic for computing next power-of-two capacity is properly encapsulated. Confirm that off cannot exceed cap to avoid over-reads in std::memcpy. If guaranteed by higher-level logic, consider a debug assertion here for safety.

mutex_art.hpp (12)

16-18: Includes look good
No issues with adding <type_traits> and <cassert>. They are aligned with the code's needs for type inspection and assertions.


21-21: Assert header inclusion
Including "assert.hpp" is consistent with the rest of the codebase. No concerns here.


26-37: Template introduction and type aliases
Defining mutex_db as a template class parameterized by Key, alongside using key_type = Key; and updated get_result using typename db<Key>::get_result, appears correct and enhances type safety.


39-45: Internal get0 method
Good use of locking with std::unique_lock to protect the ART. Returning a valid lock only when a key is found helps release resources early if not needed.


53-57: insert0 method concurrency
Lock acquisition via std::lock_guard is correct for internal insertion. This method’s naming clarifies it’s an internal routine.


60-63: remove0 method concurrency
Likewise, removing an entry under a std::lock_guard ensures thread safety. The naming convention matches insert0.


65-84: Constructor, get, and empty

  • The default constructor is marked noexcept, which is beneficial for exception-safety.
  • get(Key search_key) properly wraps the underlying get0 call with correct conversion to art_key_type.
  • empty() uses a lock guard internally but is short enough to not raise concurrency concerns.

85-100: Public insert method
Insert logic is now aggregated in insert0, which is good. The pure attribute on bool insert(...) is a nice optimization instructing that the function has no side effects beyond returning a value, from the compiler’s standpoint. Everything looks well-structured.

🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 94-94: mutex_art.hpp#L94
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


101-109: Public remove method
Similar approach to insert. The code is clear, uses art_key_type, and calls remove0. Good usage of locks.


112-112: Iterator and scan methods
All methods properly lock the mutex during the scan and delegate to the underlying db’s scanning logic. This is consistent with the concurrency model.

Also applies to: 122-122, 153-155, 177-179


200-200: Stats methods
Calls to db_.template get_node_count<NodeType>(), get_growing_inode_count<NodeType>(), and get_shrinking_inode_count<NodeType>() preserve template correctness and read well.

Also applies to: 211-211, 222-222


258-258: Underlying db instance
Storing db<Key> db_ is consistent with the templated approach. This ensures data is parameterized by Key.

art_common.hpp (9)

21-27: Extended includes
Including <cstring> and <span> is appropriate given the need to work with raw memory in key encoders/decoders.


30-35: Forward declarations
Declarations of template <typename Key> class db; and olc_db; are correct for referencing these classes without pulling in full definitions.


36-45: Key handling doc
The added documentation clarifies that values and keys are managed as non-owning spans. This is crucial for correctly understanding memory usage and lifetimes.


46-87: visitor class template
Designing visitor with a protected constructor and friend declarations for db<key_type> and olc_db<key_type> is well structured. This ensures that only intended classes can instantiate or manipulate the visitor’s internals.


91-105: Initial buffer capacity
Defining INITIAL_BUFFER_CAPACITY as 256 is reasonable, balancing typical scenarios for variable length keys. The disclaimers and TODO notes are clear.


106-120: Utility methods
dump_key, dump_val, and ensure_capacity are essential for debugging and buffer expansion. The approach is consistent with the rest of the code.


128-142: key_encoder class
Excellent approach for building binary-comparable keys. The layering and usage of an internal buffer with fallback to dynamic allocation is well justified.


180-210: Integer encoding
Encoding both signed and unsigned integers by offsetting their MSB has clarity and ensures lexicographical ordering. This is a robust approach for key comparisons.


280-381: key_decoder class
Decoding logic correctly reverses the process done in key_encoder. The symmetrical offset approach for signed and reversed endianness handling for unsigned matches the encoding strategy.

test/db_test_utils.hpp (21)

32-33: Switch to std::map
Replacing #include <unordered_map> with #include <map> implies a shift to an ordered map. This is consistent with the new custom comparator-based approach.


51-54: Template instantiations
extern template class unodb::db<std::uint64_t>; etc. helps reduce compile overhead for repeated instantiations across translation units.


57-60: Thread type alias
Conditionally using std::thread vs. unodb::qsbr_thread for OLC DB ensures consistent concurrency under different DB implementations.


75-81: Test values
Storing various test bytes in arrays is a straightforward approach. The newly introduced array-based value_views are consistent with variable-length values.


91-91: assert_value_eq for mutex_db
Verifying ownership of the lock is a good check. Ensures you actually locked the resource before verifying the data.


Line range hint 106-135: Result assertion utility
do_assert_result_eq and assert_result_eq are well-structured. Checking key_found(result) before verifying the value is robust.


128-135: OLC-specific variant
With OLC DB, you wrap calls in quiescent_state_on_scope_exit. Good concurrency management detail.


140-141: ASSERT_VALUE_FOR_KEY macro
detail::assert_result_eq approach is consistent with Google Test patterns, simplifying repeated checks.


145-160: tree_verifier do_insert
Splitting insertion logic with a partial template specialization for OLC DB is sensible. The concurrency approach is correct for each DB variant.


Line range hint 166-194: do_remove with stats checks
Verifies the old node counts, memory usage, and inodes prior to performing removal. If removal fails, logs the failure and performs a thorough check. Good coverage of corner cases.


223-232: Removing missing keys
The specialized approach (do_try_remove_missing_key) for OLC DB is consistent with the main logic. No issues found.


Line range hint 253-299: insert
Inserting keys and verifying memory usage changes if stats are enabled is thorough. The fallback logic to a tree-based map extends the test coverage.


313-320: Range insertion
Mapping from start_key to start_key + count is a straightforward approach for test coverage.


Line range hint 325-331: preinsert_key_range_to_verifier_only
Allows populating the verifier’s map without inserting into the DB, useful for advanced test scenarios.


336-336: Insert preinserted key range
Helper method to finalize insertion for a set of keys, continuing to keep code DRY.


342-353: Removing keys with concurrency
Similar approach as insert, with specialized logic for OLC DB.


355-366: try_remove
Non-verifying removal method that simply discards the result. Useful in tests that only validate concurrency or performance.


370-370: attempt_remove_missing_keys method
Systematically checks erase from values and calls do_try_remove_missing_key on the DB, ensuring absent keys remain absent in both data structures.


411-412: check_absent_keys
This helps confirm that no leftover state remains for the specified keys, improving negative test coverage.


483-493: Custom comparator
The fallback to compare(lhs, rhs) only if lhs/rhs are spans is correct. Otherwise, a standard < suffices for integral keys.


509-515: Type aliases & external template instantiations
using u64_db = unodb::db<std::uint64_t>; and the external instantiations further unify the test environment with the new template-based database classes.

art_internal.hpp (3)

42-43: Use of non-inline function is correct
The function signature and placement look consistent with the rest of the file. No issues found.


45-55: Three-way compare function is well-implemented
Utilizing std::memcmp followed by length checks is a standard approach for lexicographic comparison.


127-135: Comparison logic for fixed-width vs. variable-length keys is handled properly
The function cleanly distinguishes between std::is_same_v<KeyType, key_view> and fixed-width types. No logical flaws are evident.

test/test_art_span.cpp (2)

600-610: Correctness check
Node4 deletion logic and verification steps look well-structured. The test ensures presence and absence of expected keys.


107-107: Well-handled negative test
Verifying that removing an already deleted key returns false is a good practice to check code robustness.

benchmark/micro_benchmark_node_utils.hpp (4)

53-53: Efficient next_key calculation
The bitwise approach for skipping zero bits is a neat solution. No issues found.


237-239: Concise key generation
The function generate_keys_to_limit is straightforward and returns a vector of ascending keys until a limit is reached.


445-447: Growing nodes assertion
Ensuring the correct number of newly grown inodes helps maintain tree integrity. The checks appear consistent with the logic.


672-673: Bulk deletion utility is sound
Loop-based deletion over a vector of keys is simple and effective, aligning with the rest of the benchmark utilities.

art.hpp (6)

36-45: Forward declarations look fine.

The template forward declarations for inode, inode_4, inode_16, inode_48, and inode_256 appear appropriate. They help organize the code and reference each class later in this file without causing circular dependencies.


59-68: Appropriate usage of template aliases.

The inode_defs and art_policy definitions effectively parametrize the adaptive radix tree for different key types and database classes. This design is clear and consistent.


70-80: Consider verifying the minimal required methods.

All relevant typedefs (inode_base, leaf_type, etc.) appear consistent with the broader architecture. As these template aliases are integral to the ART node structure, ensure that all the methods required by the downstream code (e.g., destructor, copy, and move) are adequately tested.


88-120: High-level structure of the db class is solid.

The top-level db class design demonstrates a thorough approach to encapsulating ART-based operations (get, insert, remove). No immediate red flags spotted. Verify concurrency requirements if multiple threads are expected to interact with this class, though it’s not explicitly stated.

🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 94-94: mutex_art.hpp#L94
Line ends in whitespace. Consider deleting these extra spaces. (whitespace/end_of_line)


133-142: Ensure robust testing of get(Key).

The logic to convert an external key type to art_key_type is straightforward. Confirm that test coverage includes edge cases (e.g., extremely large or zero-length keys, if feasible) to ensure the function doesn't break with corner inputs.


160-163: Insertion and removal wrappers align with the underlying logic.

The insert(Key, value_view) and remove(Key) methods effectively wrap the internal _0 variants. The approach is consistent: both rely on the same path compression logic. No issues found.

Also applies to: 174-177

art_internal_impl.hpp (5)

80-99: Leaf class enhancements successfully enable variable-length key support.

The basic_leaf updates (using art_key_type and storing value_size) are clear and well-integrated. The runtime checks within the constructor help prevent overflow, and usage of std::memcpy for data storage is appropriate.


Line range hint 311-327: Deleter implementation is clean.

The basic_db_leaf_deleter and basic_db_inode_deleter do a proper job freeing aligned memory. The stats handling ensures consistent memory usage tracking.


Line range hint 2252-2374: N48 node logic is coherent.

The approach to indirect via child_indexes is typical for an ART N48 node. The code carefully ensures that each index references the correct children.pointer_array. No obvious logical errors spotted.


Line range hint 2695-2731: N256 node transition from N48 node is well-structured.

Initialization merges children via a straightforward loop. Verifying no concurrency races or invalid references is recommended if multiple writers can exist. Otherwise, the approach is consistent with the rest of the ART design.


Line range hint 2885-2917: delete_subtree and dump methods provide valuable introspection.

The top-down traversal for each child leverages the for_each_child helper, promoting code reuse and clarity. This design is good for debugging large ART structures and ensures consistent node cleanup.

olc_art.hpp (1)

Line range hint 34-114: Great use of templating for variable-length key support
This newly introduced templating approach (e.g., template <typename Key> class olc_db, olc_inode_*, and olc_art_policy) is neatly aligned with the PR objective of supporting variable-length keys. The refactoring to template-based classes enables broader key type flexibility. The code structure looks clean and follows modern C++ best practices by separating policy and data.

test/db_test_utils.cpp (2)

19-20: TODO regarding variable length keys
The mention of adding variable length keys to mutex_art.cpp is consistent with the PR's overall objective. The code still compiles and runs, so this placeholder is fine for now.


24-26: Template class instantiations look good
Introducing tree_verifier<u64_db>, tree_verifier<u64_mutex_db>, and tree_verifier<u64_olc_db> aligns nicely with the shift to 64-bit keys. No issues spotted with this approach.

mutex_art.cpp (2)

1-1: File includes its header
Although CodeFactor suggests including the header with the same name/path as the file (mutex_art.hpp), line 13 already does so. If the tooling insists on an additional override (like “mutex_art.HPP”), you can likely ignore it or conform to your local coding convention.

🧰 Tools
🪛 GitHub Check: CodeFactor

[notice] 1-1: mutex_art.cpp#L1
mutex_art.cpp should include its header file mutex_art.HPP. (build/include)


27-29: Template instantiations for mutex_db
The explicit instantiations of unodb::mutex_db<std::uint64_t> and unodb::mutex_db<unodb::key_view> broaden coverage for different key types, which dovetails with the PR’s variable-length key support direction.

benchmark/micro_benchmark_utils.cpp (2)

26-28: LGTM! Parameter rename improves clarity.

The parameter rename from db to instance makes the code more readable and better reflects its purpose.

🧰 Tools
🪛 Cppcheck (2.10-2)

[style] 26-26: The function 'destroy_tree' is never used.

(unusedFunction)


33-38: Verify template instantiation changes across the codebase.

The template instantiations have been updated to use std::uint64_t explicitly. While the changes look correct, we should verify the impact across the codebase.

✅ Verification successful

Template instantiation changes are consistent with the codebase

The explicit std::uint64_t template instantiations in benchmark/micro_benchmark_utils.cpp align with the usage patterns across the codebase, particularly in benchmark-related code and core implementations. No inconsistencies were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining unparameterized db usages and verify consistency
# of template parameter usage across the codebase

echo "Checking for unparameterized db usages..."
rg -l "unodb::(db|mutex_db|olc_db)[^<]" --type cpp

echo "Verifying consistent uint64_t template parameter usage..."
rg -l "unodb::(db|mutex_db|olc_db)<(?!std::uint64_t)" --type cpp

Length of output: 877


Script:

#!/bin/bash
# Search for all db template instantiations and their parameters
echo "Checking db template instantiations..."
rg "unodb::(db|mutex_db|olc_db)<" -A 1 --type cpp

# Use ast-grep to find template specializations
echo -e "\nChecking template specializations..."
ast-grep --pattern 'template $_ unodb::$_<$_>'

# Look for any Key type definitions or aliases
echo -e "\nChecking Key type definitions..."
rg "using.*Key" --type cpp
rg "typedef.*Key" --type cpp

Length of output: 13259

benchmark/micro_benchmark_mutex.cpp (1)

26-27: LGTM! Namespace qualification is consistent with template refactoring.

The change to use unodb::benchmark::mutex_db aligns with the broader template refactoring effort and maintains consistency across the codebase.

examples/example_art_stats.cpp (1)

31-31: LGTM! Template parameter addition is consistent.

The change to use unodb::db<std::uint64_t> aligns with the PR's objective of supporting variable length keys and template parameters.

examples/example_art.cpp (2)

34-34: LGTM! Explicit template parameter improves type safety.

The change from unodb::db to unodb::db<std::uint64_t> makes the key type explicit, which is a good practice.


90-90: LGTM! Template parameter consistency maintained.

The change to unodb::db<std::uint64_t>::key_found maintains consistency with the templated type.

test/test_art_key.cpp (2)

63-77: LGTM! Comprehensive byte-wise key testing.

The test thoroughly verifies both the encoding/decoding process and byte-wise access to the key.


32-37: Consider prioritizing variable length key support.

The TODO comments indicate important pending work for variable length keys. This should be prioritized as it's a key objective of the PR.

✅ Verification successful

Variable length key support is indeed a critical pending task

The codebase contains extensive planning for variable length key support across multiple components, with architectural changes needed in:

  • Key storage and comparison mechanisms
  • Leaf node structure and key prefix handling
  • Iterator and scanning implementations
  • Test coverage expansion
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any existing variable length key implementations or tests
rg -l "variable.*length.*key|var.*len.*key" .

Length of output: 303


Script:

#!/bin/bash
# Check the context of variable length key mentions
rg "variable.*length.*key|var.*len.*key" -C 2

Length of output: 10704

benchmark/micro_benchmark_olc.cpp (1)

25-26: LGTM! Namespace organization improves code structure.

The change to use unodb::benchmark::olc_db improves code organization by properly namespacing benchmark-specific components.

examples/example_olc_art.cpp (1)

37-37: LGTM! Consistent template usage across examples.

The change to unodb::olc_db<std::uint64_t> maintains consistency with other example files and the overall template refactoring.

benchmark/micro_benchmark_concurrency.hpp (3)

75-81: LGTM! Type change and initialization look good.

The change from unodb::key to std::uint64_t is consistent with the PR's objective of standardizing key handling.


170-185: 🧹 Nitpick (assertive)

Consider batching operations for better performance.

The worker functions could potentially benefit from batching operations to reduce synchronization overhead.

Consider applying this pattern:

 static void parallel_get_worker(const Db &test_db, std::uint64_t start,
                                std::uint64_t length) {
+  constexpr std::size_t batch_size = 64;
   for (std::uint64_t i = start; i < start + length; ++i) {
-    get_existing_key(test_db, i);
+    if (i % batch_size == 0) {
+      // Process batch
+      for (std::uint64_t j = i; j < std::min(i + batch_size, start + length); ++j) {
+        get_existing_key(test_db, j);
+      }
+    }
   }
 }

Likely invalid or redundant comment.


142-157: Consider atomic operations for thread safety.

While the parameter rename from db to instance improves clarity, the use of std::uint64_t for thread-related calculations might need atomic operations to ensure thread safety.

Run this script to check for potential thread safety issues:

benchmark/micro_benchmark_n256.cpp (1)

79-175: LGTM! Namespace changes improve code organization.

The consistent update of namespaces from unodb to unodb::benchmark across all benchmark templates improves code organization without affecting functionality.

benchmark/micro_benchmark_n48.cpp (1)

89-205: LGTM! Namespace changes are consistent with other files.

The changes mirror those in micro_benchmark_n256.cpp, maintaining consistency across the benchmark suite.

benchmark/micro_benchmark_n16.cpp (1)

89-205: LGTM! Namespace changes maintain consistency.

The changes follow the same pattern as other benchmark files, ensuring consistency across the codebase.

benchmark/micro_benchmark_utils.hpp (4)

47-50: Well-structured type aliases improve code clarity.

The introduction of type aliases using std::uint64_t improves type safety and makes the code's intent clearer. The forward declarations and subsequent type aliases are well-organized.

Also applies to: 58-60


88-89: Consistent parameter naming improves readability.

The change from db to instance in parameter names is more descriptive and consistent with the parameter's role.

Also applies to: 99-100, 149-150, 159-160, 208-209, 218-219


268-273: Consistent template instantiation declarations.

The extern template declarations are properly updated to use std::uint64_t, maintaining consistency with the type aliases defined earlier.


1-1: 🧹 Nitpick (assertive)

Update copyright notice to include year range.

The copyright notice should include the full year range to accurately reflect the file's history.

-// Copyright 2019-2025 UnoDB contributors
+// Copyright 2019-2025 UnoDB contributors

Likely invalid or redundant comment.

test/test_art.cpp (1)

44-46: LGTM: Type alias update aligns with variable length key support.

The update to ARTTypes to use explicit uint64 variants (u64_db, u64_mutex_db, u64_olc_db) is consistent with the PR's objective of supporting variable length keys and making key types more flexible.

test/test_art_scan.cpp (3)

41-41: TODO comment aligns with PR objectives.

The TODO comment correctly identifies the need for unit tests for std::span<std::byte> as part of the variable length key support initiative.


49-55: LGTM: Clean decode function implementation.

The decode function provides a clear and concise way to convert key_view to uint64_t, which is essential for the test cases. The implementation is straightforward and follows good practices.


86-87: Type updates align with the new key handling approach.

The function signature and vector type updates to use std::uint64_t are consistent with the codebase's transition to more explicit key type handling.

Also applies to: 96-96

test/CMakeLists.txt (1)

67-70: LGTM: Comprehensive test target integration.

The new test targets (test_art_key, test_key_encode_decode, test_art_span) are properly integrated across:

  • Regular test targets
  • Coverage testing
  • Valgrind testing

This ensures thorough testing of the new variable length key functionality.

Also applies to: 89-90, 99-106

CMakeLists.txt (2)

708-709: LGTM! Test targets align with PR objectives.

The new test targets (test_art_key, test_key_encode_decode, test_art_span) appropriately cover the variable length key support and template refactoring changes.


95-95: Consider keeping the "-Wmissing-declarations" warning.

Removing this warning might allow undeclared global functions to slip through, potentially leading to ODR violations and maintenance issues. If there are specific cases where this warning is problematic, consider using targeted suppressions instead.

✅ Verification successful

The "-Wmissing-declarations" warning can be safely removed.

The codebase follows good declaration practices with proper class encapsulation and scoping. All standalone functions are either template/inline functions in headers, test utilities, or necessary system overrides. No undeclared global functions were found that could lead to ODR violations.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any global functions that might be missing declarations
# Look for function definitions that might be missing declarations
rg -A 2 "^[^#\s].*\b\w+\([^)]*\)\s*\{" --type cpp

Length of output: 39532

test/test_art_oom.cpp (2)

64-65: LGTM! Parameter type changes align with the PR objective.

The change from unodb::key to std::uint64_t for the k parameter in both functions is consistent with the broader refactoring to support variable length keys.

Also applies to: 79-80


100-102: LGTM! Type alias update supports template-based key handling.

The update to use u64_db, u64_mutex_db, and u64_olc_db types aligns with the template refactoring to support key as a template parameter.

test/test_key_encode_decode.cpp (1)

48-57: LGTM! Well-structured test helper class.

The my_key_encoder class follows testing best practices by:

  • Cleanly exposing protected methods for testing
  • Maintaining encapsulation while providing necessary test access
benchmark/micro_benchmark.cpp (1)

369-461: LGTM! Comprehensive benchmark coverage with appropriate configurations.

The benchmark templates:

  • Use the correct database types (unodb::benchmark::db, mutex_db, olc_db)
  • Have appropriate range parameters
  • Use suitable time units

art_internal.cpp Outdated Show resolved Hide resolved
mutex_art.hpp Outdated Show resolved Hide resolved
test/db_test_utils.hpp Outdated Show resolved Hide resolved
test/db_test_utils.hpp Outdated Show resolved Hide resolved
art_internal.hpp Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
test/test_key_encode_decode.cpp Outdated Show resolved Hide resolved
test/test_key_encode_decode.cpp Outdated Show resolved Hide resolved
benchmark/micro_benchmark.cpp Show resolved Hide resolved
test/test_art_iter.cpp Show resolved Hide resolved
@thompsonbry
Copy link
Author

@coderabbitai pause
@coderabbitai resolve
@coderabbitai ignore

Copy link

coderabbitai bot commented Jan 28, 2025

@thompsonbry I'll pause the automatic reviews and resolve all existing review comments. However, I don't have the ability to ignore future comments.

✅ Actions performed

Comments resolved.


Reviews paused.

@thompsonbry
Copy link
Author

@coderabbitai pause
@coderabbitai resolve
@coderabbitai ignore

Copy link

coderabbitai bot commented Jan 29, 2025

Tip

For best results, initiate chat on the files or code changes.

@thompsonbry I've already paused the automatic reviews and resolved all existing review comments in response to your previous request. As mentioned before, I don't have the ability to ignore future comments. Let me know if you need anything else!

Bryan Thompson added 3 commits January 29, 2025 13:39
Surveys all open TODO(thompsonbry) and all FIXMEs.  Resolves those
which can be resolved at this time.

@coderabbitai pause
@coderabbitai resolve
@coderabbitai ignore
@thompsonbry
Copy link
Author

@laurynas-biveinis Follow up items for you:

Review CI

  • Please take up the Deep State errors. I can't reproduce them.
  • Please take up the super lint errors. I can't see them online (maybe I am blind?)
  • OOM tests -- there is something odd here. They are nearly all disabled to unblock CI. gcc works but clang fails.
  • There are some CodeFactor complaints about build/include. It wants the first line of the source file to be the .hpp file. But we can't do that because of global.hpp. Maybe there is a way to turn these messages off? Else I will just ignore them.

Copy link
Author

@thompsonbry thompsonbry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laurynas-biveinis I've done a full pass over the diff and called out a few things for you to take a look at.

CMakeLists.txt Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
@@ -147,7 +156,7 @@ void dense_iter_full_fwd_scan(benchmark::State &state) {
for (auto i = 0; i < full_scan_multiplier; ++i) {
std::uint64_t sum = 0;
auto fn = [&sum](const unodb::visitor<typename Db::iterator> &v) {
sum += v.get_key();
sum += decode(v.get_key());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laurynas-biveinis it looks like decode() was added to keep the read of the internal key and update the sum.

The key_decoder initialization is pretty light weight, but maybe we should change the sum to a sum of hashes of the encoded key? I suspect the decode is cheaper, but we can't decode all keys once we get into variable length keys.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

const std::string_view s(reinterpret_cast<const char*>(val.data()),
auto fn = [](const unodb::visitor<unodb::db<std::uint64_t>::iterator>& vis) {
const auto& key{vis.get_key()};
unodb::key_decoder dec{key};
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar comment here. In the example, we should be thinking about modeling what we want people to be doing.

Calling decode here makes sense if you have a simple primitive key type. But it does not always make sense for complex key types using the variable length key mechanism.

Just something to think about. Maybe even a different example for the use case of secondary indices, except that we do not support a fixed width type for the Value and to me that would be part of the ideal secondary index pattern.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right and I think we should already split this example. Or just here the decodable key example

test/test_art.cpp Outdated Show resolved Hide resolved
art.hpp Show resolved Hide resolved
art_internal.hpp Show resolved Hide resolved
if constexpr (std::is_same_v<Key, key_view>) {
return art_key_type{get_key_view()};
} else {
// Use memcpy since alignment is not guaranteed because the
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laurynas-biveinis Take a note of this. We are loosing the 8-byte alignment because the key is no longer explicitly present, instead we have the key length, the value length, and the data starts after that. That might be worth making explicit in the leaf data record, e.g, align(8) for the data[].

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's align, and use something like std::max_align_t for that (16 is its common value)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's align, and use something like std::max_align_t for that (16 is its common value)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the somewhat extensive dm thread, I think we should just leave this as it is at the instant. The only benchmark regression is in the scan. That code is going to continue to evolve as the variable length key support is brought in and I expect to resolve that regression before #661 is closed out (e.g., we will compare fewer bytes per leaf visited).

The other thing that we need to do to cleanly address the leaf data layout is template the tree for the Value as well as the key. When doing that, we should create a union of the leaf type which is optimized for at least the case where both Key and Value are fixed length.

I do think it is worth optimizing the leaf for the case where just the key or just the value are fixed length. The latter supports the common case of variable length composite keys to record identifiers for secondary indices. The former case (int => bytes) is the case originally supported by the library. I am not sure how much maximum efficiency matters there, but ensuring that we do not regress this matters.

Created #673 to track this

// NOLINTNEXTLINE(modernize-avoid-c-arrays)
std::byte value_start[1];
std::byte data[1];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@laurynas-biveinis This is where we would need to align(8) if we wanted to avoid the memcpy() call above for the uint64_t case.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, and add asserts that the data start in the buffer is also aligned

art_internal_impl.hpp Show resolved Hide resolved
Copy link

codecov bot commented Jan 30, 2025

Codecov Report

Attention: Patch coverage is 96.55766% with 40 lines in your changes missing coverage. Please review.

Project coverage is 97.98%. Comparing base (3185758) to head (18cd288).
Report is 20 commits behind head on master.

Files with missing lines Patch % Lines
art.hpp 94.68% 22 Missing ⚠️
art_internal.hpp 88.15% 9 Missing ⚠️
art_internal.cpp 70.00% 6 Missing ⚠️
art_internal_impl.hpp 97.36% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #661      +/-   ##
==========================================
- Coverage   98.46%   97.98%   -0.48%     
==========================================
  Files          33       32       -1     
  Lines        6651     7061     +410     
==========================================
+ Hits         6549     6919     +370     
- Misses        102      142      +40     
Flag Coverage Δ
Debug 97.97% <96.55%> (+0.30%) ⬆️
Release 96.59% <96.46%> (-1.23%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

This fixes ARTCorrectnessTest.TooLongValue
@thompsonbry
Copy link
Author

Microbenchmarks for varkeys-template e9c3776

dev-dsk-bryant-2b-a6dd7191 %
dev-dsk-bryant-2b-a6dd7191 % benchmark/micro_benchmark
benchmark/micro_benchmark
2025-01-30T15:17:06+00:00
Running benchmark/micro_benchmark
Run on (48 X 3095.6 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x24)
  L1 Instruction 32 KiB (x24)
  L2 Unified 1024 KiB (x24)
  L3 Unified 36608 KiB (x1)
Load Average: 0.96, 0.73, 0.35
------------------------------------------------------------------------------------------------------------------------------------------
Benchmark                                                                                Time             CPU   Iterations UserCounters...
------------------------------------------------------------------------------------------------------------------------------------------
dense_insert<unodb::benchmark::db>/100                                                5.75 us         5.76 us       121059 items_per_second=17.3542M/s
dense_insert<unodb::benchmark::db>/512                                                28.2 us         28.2 us        24848 items_per_second=18.1502M/s
dense_insert<unodb::benchmark::db>/4096                                                238 us          238 us         2947 items_per_second=17.2176M/s
dense_insert<unodb::benchmark::db>/32768                                              1923 us         1923 us          364 items_per_second=17.0397M/s
dense_insert<unodb::benchmark::db>/262144                                            18612 us        18612 us           37 items_per_second=14.085M/s
dense_insert<unodb::benchmark::db>/2097152                                          184189 us       184188 us            3 items_per_second=11.3859M/s
dense_insert<unodb::benchmark::db>/16777216                                        1940919 us      1940892 us            1 items_per_second=8.64408M/s
dense_insert<unodb::benchmark::db>/30000000                                        3156778 us      3156713 us            1 items_per_second=9.50356M/s
dense_insert<unodb::benchmark::mutex_db>/100                                        689043 us       689036 us            1 items_per_second=145.13/s
dense_insert<unodb::benchmark::mutex_db>/512                                          35.2 us         35.2 us        19965 items_per_second=14.5282M/s
dense_insert<unodb::benchmark::mutex_db>/4096                                          292 us          292 us         2402 items_per_second=14.0478M/s
dense_insert<unodb::benchmark::mutex_db>/32768                                        2364 us         2365 us          296 items_per_second=13.8582M/s
dense_insert<unodb::benchmark::mutex_db>/262144                                      22489 us        22489 us           31 items_per_second=11.6567M/s
dense_insert<unodb::benchmark::mutex_db>/2097152                                    213729 us       213721 us            3 items_per_second=9.81256M/s
dense_insert<unodb::benchmark::mutex_db>/16777216                                  2165535 us      2165523 us            1 items_per_second=7.74742M/s
dense_insert<unodb::benchmark::mutex_db>/30000000                                  3575153 us      3575120 us            1 items_per_second=8.39133M/s
dense_insert<unodb::benchmark::olc_db>/100                                          743741 us       743729 us            1 items_per_second=134.458/s
dense_insert<unodb::benchmark::olc_db>/512                                            58.4 us         58.4 us        11986 items_per_second=8.76969M/s
dense_insert<unodb::benchmark::olc_db>/4096                                            482 us          482 us         1460 items_per_second=8.5028M/s
dense_insert<unodb::benchmark::olc_db>/32768                                          3868 us         3868 us          181 items_per_second=8.47158M/s
dense_insert<unodb::benchmark::olc_db>/262144                                        35335 us        35335 us           20 items_per_second=7.41874M/s
dense_insert<unodb::benchmark::olc_db>/2097152                                      399518 us       399509 us            2 items_per_second=5.24932M/s
dense_insert<unodb::benchmark::olc_db>/16777216                                    3262627 us      3262511 us            1 items_per_second=5.14242M/s
dense_insert<unodb::benchmark::olc_db>/30000000                                    6003233 us      6003139 us            1 items_per_second=4.99739M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/100                                  59.8 us         60.3 us        11619 items_per_second=1.65764M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/512                                   313 us          315 us         2221 items_per_second=1.62297M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/4096                                 2502 us         2522 us          277 items_per_second=1.62439M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/32768                               20582 us        20777 us           34 items_per_second=1.5771M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/262144                             193914 us       197536 us            4 items_per_second=1.32707M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/2097152                           1761149 us      1784299 us            1 items_per_second=1.17534M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/10000000                          9174377 us      9301956 us            1 items_per_second=1.07504M/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/100                         3170504 us      3170492 us            1 items_per_second=31.5408/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/512                             321 us          324 us         2161 items_per_second=1.58045M/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/4096                           2561 us         2586 us          270 items_per_second=1.58383M/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/32768                         21158 us        21364 us           33 items_per_second=1.53376M/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/262144                       200028 us       201701 us            4 items_per_second=1.29967M/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/2097152                     1786751 us      1802390 us            1 items_per_second=1.16354M/s
sparse_insert_dups_allowed<unodb::benchmark::mutex_db>/10000000                    9419047 us      9489241 us            1 items_per_second=1.05383M/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/100                           3180013 us      3179990 us            1 items_per_second=31.4466/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/512                               343 us          345 us         2029 items_per_second=1.48559M/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/4096                             2688 us         2709 us          259 items_per_second=1.51198M/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/32768                           21941 us        22112 us           32 items_per_second=1.48194M/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/262144                         195664 us       197253 us            4 items_per_second=1.32897M/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/2097152                       1814365 us      1829093 us            1 items_per_second=1.14655M/s
sparse_insert_dups_allowed<unodb::benchmark::olc_db>/10000000                      9333803 us      9402601 us            1 items_per_second=1.06354M/s
dense_full_scan<unodb::benchmark::db>/100                                             42.5 us         42.5 us        16488 items_per_second=117.762M/s
dense_full_scan<unodb::benchmark::db>/512                                              342 us          342 us         2038 items_per_second=74.848M/s
dense_full_scan<unodb::benchmark::db>/4096                                            2826 us         2826 us          248 items_per_second=72.4761M/s
dense_full_scan<unodb::benchmark::db>/32768                                          20431 us        20431 us           34 items_per_second=80.1926M/s
dense_full_scan<unodb::benchmark::db>/262144                                        289885 us       289884 us            2 items_per_second=45.2153M/s
dense_full_scan<unodb::benchmark::db>/2097152                                      2883767 us      2883752 us            1 items_per_second=36.3615M/s
dense_full_scan<unodb::benchmark::db>/16777216                                    23103876 us     23103707 us            1 items_per_second=36.3085M/s
dense_full_scan<unodb::benchmark::db>/20000000                                    34077017 us     34076625 us            1 items_per_second=29.3456M/s
dense_full_scan<unodb::benchmark::mutex_db>/100                                        123 us          123 us         5677 items_per_second=40.5593M/s
dense_full_scan<unodb::benchmark::mutex_db>/512                                        714 us          714 us          980 items_per_second=35.8475M/s
dense_full_scan<unodb::benchmark::mutex_db>/4096                                      5672 us         5672 us          123 items_per_second=36.1056M/s
dense_full_scan<unodb::benchmark::mutex_db>/32768                                    45399 us        45398 us           15 items_per_second=36.0895M/s
dense_full_scan<unodb::benchmark::mutex_db>/262144                                  431727 us       431723 us            2 items_per_second=30.3602M/s
dense_full_scan<unodb::benchmark::mutex_db>/2097152                                3967892 us      3967875 us            1 items_per_second=26.4266M/s
dense_insert_value_lengths<unodb::benchmark::db>/800/value len log10:4                 346 us          346 us         2014 bytes_per_second=26.4291Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/6400/value len log10:0                373 us          373 us         1876 bytes_per_second=130.882Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/6400/value len log10:1                363 us          363 us         1930 bytes_per_second=151.446Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/6400/value len log10:2                380 us          380 us         1843 bytes_per_second=160.674Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/6400/value len log10:3                707 us          708 us          988 bytes_per_second=94.8732Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/6400/value len log10:4               9659 us         9660 us           71 bytes_per_second=7.58215Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/51200/value len log10:0              2846 us         2846 us          246 bytes_per_second=137.268Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/51200/value len log10:1              2771 us         2771 us          253 bytes_per_second=158.609Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/51200/value len log10:2              3033 us         3033 us          231 bytes_per_second=160.965Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/51200/value len log10:3              9692 us         9692 us           72 bytes_per_second=55.4184Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/51200/value len log10:4             83083 us        83082 us            9 bytes_per_second=7.05249Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:0            25747 us        25746 us           27 bytes_per_second=121.376Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:1            25353 us        25352 us           28 bytes_per_second=138.671Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:2            32527 us        32527 us           21 bytes_per_second=120.094Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:3            93773 us        93773 us            7 bytes_per_second=45.8222Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:4          1520769 us      1520754 us            1 bytes_per_second=3.08235Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/100/value len log10:0          7.12 us         7.13 us        97969 bytes_per_second=107.058Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/100/value len log10:1          7.12 us         7.13 us        98401 bytes_per_second=120.434Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/100/value len log10:2          7.23 us         7.24 us        96682 bytes_per_second=131.768Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/100/value len log10:3          11.1 us         11.2 us        62653 bytes_per_second=93.8406Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/100/value len log10:4          41.0 us         41.1 us        16174 bytes_per_second=27.8725Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/800/value len log10:0          56.7 us         56.7 us        12348 bytes_per_second=107.683Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/800/value len log10:1          55.8 us         55.8 us        12537 bytes_per_second=122.975Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/800/value len log10:2          57.7 us         57.7 us        12121 bytes_per_second=132.209Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/800/value len log10:3          94.1 us         94.2 us         7436 bytes_per_second=89.1128Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/800/value len log10:4           362 us          362 us         1928 bytes_per_second=25.2766Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/6400/value len log10:0          455 us          455 us         1539 bytes_per_second=107.382Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/6400/value len log10:1          447 us          447 us         1566 bytes_per_second=122.875Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/6400/value len log10:2          468 us          468 us         1495 bytes_per_second=130.362Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/6400/value len log10:3          839 us          839 us          835 bytes_per_second=79.9803Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/6400/value len log10:4         9788 us         9789 us           70 bytes_per_second=7.48246Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/51200/value len log10:0        3516 us         3516 us          199 bytes_per_second=111.102Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/51200/value len log10:1        3474 us         3474 us          201 bytes_per_second=126.506Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/51200/value len log10:2        3753 us         3753 us          186 bytes_per_second=130.114Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/51200/value len log10:3       10412 us        10412 us           66 bytes_per_second=51.585Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/51200/value len log10:4       84153 us        84153 us            9 bytes_per_second=6.96279Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/409600/value len log10:0      31626 us        31625 us           22 bytes_per_second=98.8134Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/409600/value len log10:1      31482 us        31481 us           22 bytes_per_second=111.673Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/409600/value len log10:2      38940 us        38939 us           18 bytes_per_second=100.316Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/409600/value len log10:3     104526 us       104524 us            6 bytes_per_second=41.1088Mi/s
dense_insert_value_lengths<unodb::benchmark::mutex_db>/409600/value len log10:4    1529288 us      1529205 us            1 bytes_per_second=3.06532Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/100/value len log10:0            11.8 us         11.8 us        59496 bytes_per_second=64.8873Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/100/value len log10:1            11.8 us         11.8 us        59077 bytes_per_second=72.4943Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/100/value len log10:2            12.6 us         12.6 us        55581 bytes_per_second=75.7983Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/100/value len log10:3            17.4 us         17.4 us        40164 bytes_per_second=60.2355Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/100/value len log10:4            48.4 us         48.4 us        13886 bytes_per_second=23.6325Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/800/value len log10:0            94.3 us         94.3 us         7416 bytes_per_second=64.701Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/800/value len log10:1            96.4 us         96.4 us         7263 bytes_per_second=71.2513Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/800/value len log10:2            94.3 us         94.3 us         7425 bytes_per_second=80.9408Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/800/value len log10:3             140 us          140 us         4997 bytes_per_second=59.9514Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/800/value len log10:4             406 us          406 us         1721 bytes_per_second=22.546Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/6400/value len log10:0            764 us          764 us          917 bytes_per_second=63.9494Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/6400/value len log10:1            774 us          774 us          904 bytes_per_second=70.9725Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/6400/value len log10:2            759 us          759 us          923 bytes_per_second=80.437Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/6400/value len log10:3           1194 us         1195 us          587 bytes_per_second=56.2055Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/6400/value len log10:4          10347 us        10347 us           67 bytes_per_second=7.0786Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/51200/value len log10:0          6118 us         6118 us          114 bytes_per_second=63.8509Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/51200/value len log10:1          6213 us         6213 us          113 bytes_per_second=70.7336Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/51200/value len log10:2          6089 us         6089 us          115 bytes_per_second=80.1863Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/51200/value len log10:3         13206 us        13206 us           53 bytes_per_second=40.6716Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/51200/value len log10:4         87888 us        87888 us            8 bytes_per_second=6.66683Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/409600/value len log10:0        53356 us        53355 us           13 bytes_per_second=58.5697Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/409600/value len log10:1        54890 us        54889 us           13 bytes_per_second=64.0496Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/409600/value len log10:2        54518 us        54517 us           12 bytes_per_second=71.6526Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/409600/value len log10:3       125814 us       125812 us            6 bytes_per_second=34.1531Mi/s
dense_insert_value_lengths<unodb::benchmark::olc_db>/409600/value len log10:4      1602635 us      1602614 us            1 bytes_per_second=2.92491Mi/s
dense_insert_dup_attempts<unodb::benchmark::db>/100                                   2.49 us         2.48 us       282944 items_per_second=40.2641M/s
dense_insert_dup_attempts<unodb::benchmark::db>/512                                   12.6 us         12.5 us        55477 items_per_second=40.8791M/s
dense_insert_dup_attempts<unodb::benchmark::db>/4096                                  93.9 us         93.9 us         7459 items_per_second=43.6414M/s
dense_insert_dup_attempts<unodb::benchmark::db>/32768                                  675 us          674 us         1039 items_per_second=48.5841M/s
dense_insert_dup_attempts<unodb::benchmark::db>/262144                                7998 us         7997 us           87 items_per_second=32.7822M/s
dense_insert_dup_attempts<unodb::benchmark::db>/2097152                              76548 us        76545 us            9 items_per_second=27.3975M/s
dense_insert_dup_attempts<unodb::benchmark::db>/16777216                            590692 us       590689 us            1 items_per_second=28.4028M/s
dense_insert_dup_attempts<unodb::benchmark::db>/30000000                           1260644 us      1260634 us            1 items_per_second=23.7975M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/100                             4.13 us         4.12 us       169955 items_per_second=24.2788M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/512                             21.2 us         21.2 us        33026 items_per_second=24.1512M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/4096                             162 us          162 us         4330 items_per_second=25.3606M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/32768                           1213 us         1212 us          577 items_per_second=27.0285M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/262144                         12267 us        12265 us           57 items_per_second=21.3725M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/2097152                       108651 us       108646 us            6 items_per_second=19.3025M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/16777216                      832793 us       832789 us            1 items_per_second=20.1458M/s
dense_insert_dup_attempts<unodb::benchmark::mutex_db>/30000000                     1715804 us      1715778 us            1 items_per_second=17.4848M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/100                               7.18 us         7.18 us        97444 items_per_second=13.9295M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/512                               39.0 us         39.0 us        17960 items_per_second=13.1425M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/4096                               302 us          302 us         2321 items_per_second=13.5799M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/32768                             2406 us         2406 us          291 items_per_second=13.6214M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/262144                           22838 us        22836 us           30 items_per_second=11.4793M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/2097152                         187814 us       187812 us            4 items_per_second=11.1662M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/16777216                       1482383 us      1482357 us            1 items_per_second=11.3179M/s
dense_insert_dup_attempts<unodb::benchmark::olc_db>/30000000                       3013951 us      3013909 us            1 items_per_second=9.95385M/s

dev-dsk-bryant-2b-a6dd7191 % benchmark/micro_benchmark_key_prefix
benchmark/micro_benchmark_key_prefix
2025-01-30T16:44:28+00:00
Running benchmark/micro_benchmark_key_prefix
Run on (48 X 3100.06 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x24)
  L1 Instruction 32 KiB (x24)
  L2 Unified 1024 KiB (x24)
  L3 Unified 36608 KiB (x1)
Load Average: 0.54, 0.93, 0.97
--------------------------------------------------------------------------------------------------------------------------
Benchmark                                                                Time             CPU   Iterations UserCounters...
--------------------------------------------------------------------------------------------------------------------------
unpredictable_get_shared_length<unodb::benchmark::db>                0.901 us        0.904 us       771710 items_per_second=23.2235M/s
unpredictable_get_shared_length<unodb::benchmark::mutex_db>           1.21 us         1.22 us       576887 items_per_second=17.2808M/s
unpredictable_get_shared_length<unodb::benchmark::olc_db>             1.72 us         1.72 us       406364 items_per_second=12.1934M/s
unpredictable_leaf_key_prefix_split<unodb::benchmark::db>             20.9 us         20.9 us        33348 items_per_second=12.0512M/s
unpredictable_leaf_key_prefix_split<unodb::benchmark::mutex_db>       25.8 us         25.8 us        27180 items_per_second=9.7693M/s
unpredictable_leaf_key_prefix_split<unodb::benchmark::olc_db>         40.9 us         40.8 us        17170 items_per_second=6.1747M/s
unpredictable_cut_key_prefix<unodb::benchmark::db>                    20.9 us         20.8 us        33631 items_per_second=12.0986M/s
unpredictable_cut_key_prefix<unodb::benchmark::mutex_db>              24.4 us         24.4 us        28681 items_per_second=10.3368M/s
unpredictable_cut_key_prefix<unodb::benchmark::olc_db>                38.0 us         38.0 us        18432 items_per_second=6.63332M/s
unpredictable_prepend_key_prefix<unodb::benchmark::db>                13.6 us         13.6 us        51495 items_per_second=18.54M/s
unpredictable_prepend_key_prefix<unodb::benchmark::mutex_db>          16.7 us         16.7 us        41920 items_per_second=15.0851M/s
unpredictable_prepend_key_prefix<unodb::benchmark::olc_db>            42.4 us         42.4 us        16526 items_per_second=5.94578M/s

@thompsonbry
Copy link
Author

Benchmarking master at 36a6520 (Jan 18th, 2025)

benchmark/micro_benchmark && benchmark/micro_benchmark_key_prefix
2025-01-30T20:06:30+00:00
Running benchmark/micro_benchmark
Run on (48 X 3100.41 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x24)
  L1 Instruction 32 KiB (x24)
  L2 Unified 1024 KiB (x24)
  L3 Unified 36608 KiB (x1)
Load Average: 1.17, 0.62, 0.28
-------------------------------------------------------------------------------------------------------------------------------
Benchmark                                                                     Time             CPU   Iterations UserCounters...
-------------------------------------------------------------------------------------------------------------------------------
dense_insert<unodb::db>/100                                                5.99 us         6.00 us       116435 items_per_second=16.6717M/s
dense_insert<unodb::db>/512                                                28.7 us         28.7 us        23901 items_per_second=17.812M/s
dense_insert<unodb::db>/4096                                                243 us          243 us         2884 items_per_second=16.8731M/s
dense_insert<unodb::db>/32768                                              1954 us         1954 us          359 items_per_second=16.7696M/s
dense_insert<unodb::db>/262144                                            19051 us        19051 us           36 items_per_second=13.7599M/s
dense_insert<unodb::db>/2097152                                          188179 us       188176 us            3 items_per_second=11.1446M/s
dense_insert<unodb::db>/16777216                                        1958803 us      1958777 us            1 items_per_second=8.56515M/s
dense_insert<unodb::db>/30000000                                        3189730 us      3189695 us            1 items_per_second=9.40529M/s
dense_insert<unodb::mutex_db>/100                                        715425 us       715424 us            1 items_per_second=139.777/s
dense_insert<unodb::mutex_db>/512                                          35.5 us         35.5 us        19671 items_per_second=14.4076M/s
dense_insert<unodb::mutex_db>/4096                                          298 us          298 us         2351 items_per_second=13.7577M/s
dense_insert<unodb::mutex_db>/32768                                        2405 us         2405 us          291 items_per_second=13.6253M/s
dense_insert<unodb::mutex_db>/262144                                      22909 us        22909 us           30 items_per_second=11.4428M/s
dense_insert<unodb::mutex_db>/2097152                                    215198 us       215197 us            4 items_per_second=9.74526M/s
dense_insert<unodb::mutex_db>/16777216                                  1341916 us      1341912 us            1 items_per_second=12.5025M/s
dense_insert<unodb::mutex_db>/30000000                                  3567701 us      3567575 us            1 items_per_second=8.40907M/s
dense_insert<unodb::olc_db>/100                                          741144 us       741130 us            1 items_per_second=134.929/s
dense_insert<unodb::olc_db>/512                                            59.6 us         59.6 us        11734 items_per_second=8.58624M/s
dense_insert<unodb::olc_db>/4096                                            496 us          496 us         1419 items_per_second=8.26524M/s
dense_insert<unodb::olc_db>/32768                                          3937 us         3938 us          178 items_per_second=8.32161M/s
dense_insert<unodb::olc_db>/262144                                        34630 us        34630 us           20 items_per_second=7.56982M/s
dense_insert<unodb::olc_db>/2097152                                      290223 us       290213 us            2 items_per_second=7.22625M/s
dense_insert<unodb::olc_db>/16777216                                    2407459 us      2407445 us            1 items_per_second=6.96889M/s
dense_insert<unodb::olc_db>/30000000                                    5170292 us      5170215 us            1 items_per_second=5.80247M/s
sparse_insert_dups_allowed<unodb::db>/100                                  59.4 us         59.8 us        11717 items_per_second=1.67345M/s
sparse_insert_dups_allowed<unodb::db>/512                                   309 us          311 us         2251 items_per_second=1.64584M/s
sparse_insert_dups_allowed<unodb::db>/4096                                 2485 us         2501 us          280 items_per_second=1.63753M/s
sparse_insert_dups_allowed<unodb::db>/32768                               20325 us        20475 us           34 items_per_second=1.60039M/s
sparse_insert_dups_allowed<unodb::db>/262144                             192530 us       196495 us            4 items_per_second=1.3341M/s
sparse_insert_dups_allowed<unodb::db>/2097152                           1741600 us      1762429 us            1 items_per_second=1.18992M/s
sparse_insert_dups_allowed<unodb::db>/10000000                          9058649 us      9174741 us            1 items_per_second=1.08995M/s
sparse_insert_dups_allowed<unodb::mutex_db>/100                         3073803 us      3073681 us            1 items_per_second=32.5343/s
sparse_insert_dups_allowed<unodb::mutex_db>/512                             317 us          319 us         2196 items_per_second=1.60644M/s
sparse_insert_dups_allowed<unodb::mutex_db>/4096                           2548 us         2562 us          274 items_per_second=1.59883M/s
dense_tree_sparse_deletes<unodb::db>/64000/deletes:800                     1495 us         1497 us          468 items_per_second=534.282k/s
dense_tree_sparse_deletes<unodb::db>/64000/deletes:64000                  37191 us        37355 us           19 items_per_second=1.71329M/s
dense_tree_sparse_deletes<unodb::db>/512000/deletes:800                   11716 us        11718 us           60 items_per_second=68.2738k/s
dense_tree_sparse_deletes<unodb::db>/512000/deletes:512000               357271 us       358713 us            2 items_per_second=1.42733M/s
dense_tree_sparse_deletes<unodb::db>/4096000/deletes:800                 101216 us       101218 us            7 items_per_second=7.90373k/s
dense_tree_sparse_deletes<unodb::db>/4096000/deletes:4096000            3286887 us      3297432 us            1 items_per_second=1.24218M/s
dense_tree_sparse_deletes<unodb::mutex_db>/1000/deletes:800                 452 us          454 us         1539 items_per_second=1.76139M/s
dense_tree_sparse_deletes<unodb::mutex_db>/1000/deletes:1000                559 us          562 us         1246 items_per_second=1.77866M/s
dense_tree_sparse_deletes<unodb::mutex_db>/8000/deletes:800                 571 us          573 us         1223 items_per_second=1.39621M/s
dense_tree_sparse_deletes<unodb::mutex_db>/8000/deletes:8000               4516 us         4535 us          154 items_per_second=1.7639M/s
dense_tree_sparse_deletes<unodb::mutex_db>/64000/deletes:800               1508 us         1510 us          464 items_per_second=529.791k/s
dense_tree_sparse_deletes<unodb::mutex_db>/64000/deletes:64000            38082 us        38238 us           18 items_per_second=1.67371M/s
dense_tree_sparse_deletes<unodb::mutex_db>/512000/deletes:800             11694 us        11696 us           60 items_per_second=68.3977k/s
dense_tree_sparse_deletes<unodb::mutex_db>/512000/deletes:512000         363438 us       364884 us            2 items_per_second=1.40319M/s
dense_tree_sparse_deletes<unodb::mutex_db>/4096000/deletes:800           101489 us       101490 us            7 items_per_second=7.88259k/s
dense_tree_sparse_deletes<unodb::mutex_db>/4096000/deletes:4096000      3360315 us      3370635 us            1 items_per_second=1.2152M/s
dense_tree_sparse_deletes<unodb::olc_db>/1000/deletes:800                   520 us          522 us         1343 items_per_second=1.53244M/s
dense_tree_sparse_deletes<unodb::olc_db>/1000/deletes:1000                  641 us          643 us         1088 items_per_second=1.55411M/s
dense_tree_sparse_deletes<unodb::olc_db>/8000/deletes:800                   689 us          691 us         1012 items_per_second=1.15707M/s
dense_tree_sparse_deletes<unodb::olc_db>/8000/deletes:8000                 5191 us         5214 us          134 items_per_second=1.53435M/s
dense_tree_sparse_deletes<unodb::olc_db>/64000/deletes:800                 1996 us         1998 us          350 items_per_second=400.375k/s
dense_tree_sparse_deletes<unodb::olc_db>/64000/deletes:64000              45040 us        45235 us           16 items_per_second=1.41483M/s
dense_tree_sparse_deletes<unodb::olc_db>/512000/deletes:800               19537 us        19539 us           36 items_per_second=40.943k/s
dense_tree_sparse_deletes<unodb::olc_db>/512000/deletes:512000           433867 us       435489 us            2 items_per_second=1.17569M/s
dense_tree_sparse_deletes<unodb::olc_db>/4096000/deletes:800             169834 us       169836 us            4 items_per_second=4.71043k/s
dense_tree_sparse_deletes<unodb::olc_db>/4096000/deletes:4096000        4138776 us      4150909 us            1 items_per_second=986.772k/s
dense_tree_increasing_keys<unodb::db>/100                                  60.8 ms         60.8 ms           12 items_per_second=32.9033M/s
dense_tree_increasing_keys<unodb::db>/512                                  70.8 ms         70.8 ms           10 items_per_second=28.2413M/s
dense_tree_increasing_keys<unodb::db>/4096                                 69.1 ms         69.1 ms           10 items_per_second=28.9482M/s
dense_tree_increasing_keys<unodb::db>/32768                                73.3 ms         73.3 ms           10 items_per_second=27.2952M/s
dense_tree_increasing_keys<unodb::db>/262144                               84.3 ms         84.3 ms            8 items_per_second=23.719M/s
dense_tree_increasing_keys<unodb::db>/2097152                              82.5 ms         82.5 ms            8 items_per_second=24.2552M/s
dense_tree_increasing_keys<unodb::db>/16777216                              100 ms          100 ms            7 items_per_second=19.9351M/s
dense_tree_increasing_keys<unodb::db>/30000000                             97.6 ms         97.6 ms            7 items_per_second=20.5019M/s
dense_tree_increasing_keys<unodb::mutex_db>/100                            86.7 ms         86.7 ms            8 items_per_second=23.0803M/s
dense_tree_increasing_keys<unodb::mutex_db>/512                            95.8 ms         95.8 ms            7 items_per_second=20.8783M/s
dense_tree_increasing_keys<unodb::mutex_db>/4096                           94.3 ms         94.3 ms            7 items_per_second=21.213M/s
dense_tree_increasing_keys<unodb::mutex_db>/32768                           100 ms          100 ms            7 items_per_second=19.9212M/s
dense_tree_increasing_keys<unodb::mutex_db>/262144                          111 ms          111 ms            6 items_per_second=18.0218M/s
dense_tree_increasing_keys<unodb::mutex_db>/2097152                         109 ms          109 ms            6 items_per_second=18.3425M/s
dense_tree_increasing_keys<unodb::mutex_db>/16777216                        128 ms          128 ms            5 items_per_second=15.6716M/s
dense_tree_increasing_keys<unodb::mutex_db>/30000000                        125 ms          125 ms            6 items_per_second=15.9621M/s
dense_tree_increasing_keys<unodb::olc_db>/100                               208 ms          208 ms            3 items_per_second=9.63755M/s
dense_tree_increasing_keys<unodb::olc_db>/512                               229 ms          229 ms            3 items_per_second=8.72469M/s
dense_tree_increasing_keys<unodb::olc_db>/4096                              232 ms          232 ms            3 items_per_second=8.63359M/s
dense_tree_increasing_keys<unodb::olc_db>/32768                             243 ms          243 ms            3 items_per_second=8.22523M/s
dense_tree_increasing_keys<unodb::olc_db>/262144                            260 ms          260 ms            3 items_per_second=7.69987M/s
dense_tree_increasing_keys<unodb::olc_db>/2097152                           263 ms          263 ms            3 items_per_second=7.61031M/s
dense_tree_increasing_keys<unodb::olc_db>/16777216                          292 ms          292 ms            2 items_per_second=6.84131M/s
dense_tree_increasing_keys<unodb::olc_db>/30000000                          292 ms          292 ms            2 items_per_second=6.85188M/s
dense_insert_value_lengths<unodb::db>/100/value len log10:0                5.80 us         5.80 us       120646 bytes_per_second=131.517Mi/s
dense_insert_value_lengths<unodb::db>/100/value len log10:1                5.67 us         5.68 us       123293 bytes_per_second=151.187Mi/s
dense_insert_value_lengths<unodb::db>/100/value len log10:2                5.91 us         5.92 us       117266 bytes_per_second=161.061Mi/s
dense_insert_value_lengths<unodb::db>/100/value len log10:3                9.38 us         9.40 us        74411 bytes_per_second=111.549Mi/s
dense_insert_value_lengths<unodb::db>/100/value len log10:4                39.0 us         39.0 us        17028 bytes_per_second=29.3199Mi/s
dense_insert_value_lengths<unodb::db>/800/value len log10:0                46.9 us         46.9 us        14902 bytes_per_second=130.108Mi/s
dense_insert_value_lengths<unodb::db>/800/value len log10:1                45.7 us         45.8 us        15299 bytes_per_second=150.046Mi/s
dense_insert_value_lengths<unodb::db>/800/value len log10:2                47.5 us         47.5 us        14706 bytes_per_second=160.457Mi/s
dense_insert_value_lengths<unodb::db>/800/value len log10:3                77.5 us         77.6 us         9008 bytes_per_second=108.185Mi/s
dense_insert_value_lengths<unodb::db>/800/value len log10:4                 346 us          346 us         2017 bytes_per_second=26.4254Mi/s
dense_insert_value_lengths<unodb::db>/6400/value len log10:0                374 us          374 us         1873 bytes_per_second=130.643Mi/s
dense_insert_value_lengths<unodb::db>/6400/value len log10:1                365 us          365 us         1918 bytes_per_second=150.492Mi/s
dense_insert_value_lengths<unodb::db>/6400/value len log10:2                380 us          380 us         1846 bytes_per_second=160.505Mi/s
dense_insert_value_lengths<unodb::db>/6400/value len log10:3                705 us          705 us          994 bytes_per_second=95.1806Mi/s
dense_insert_value_lengths<unodb::db>/6400/value len log10:4               9796 us         9796 us           71 bytes_per_second=7.47669Mi/s
dense_insert_value_lengths<unodb::db>/51200/value len log10:0              2853 us         2853 us          245 bytes_per_second=136.901Mi/s
dense_insert_value_lengths<unodb::db>/51200/value len log10:1              2800 us         2800 us          251 bytes_per_second=156.926Mi/s
dense_insert_value_lengths<unodb::db>/51200/value len log10:2              3045 us         3046 us          229 bytes_per_second=160.321Mi/s
dense_insert_value_lengths<unodb::db>/51200/value len log10:3              9253 us         9253 us           74 bytes_per_second=58.0449Mi/s
dense_insert_value_lengths<unodb::db>/51200/value len log10:4             84228 us        84225 us            9 bytes_per_second=6.95677Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:0            26293 us        26292 us           27 bytes_per_second=118.857Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:1            26061 us        26061 us           27 bytes_per_second=134.899Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:2            32921 us        32921 us           21 bytes_per_second=118.656Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:3            91937 us        91937 us            7 bytes_per_second=46.7374Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:4          1512622 us      1512601 us            1 bytes_per_second=3.09897Mi/s
dense_insert_value_lengths<unodb::mutex_db>/100/value len log10:0          7.02 us         7.03 us        99489 bytes_per_second=108.522Mi/s
dense_insert_value_lengths<unodb::mutex_db>/100/value len log10:1          7.03 us         7.04 us        99748 bytes_per_second=121.892Mi/s
dense_insert_value_lengths<unodb::mutex_db>/100/value len log10:2          7.39 us         7.41 us        94490 bytes_per_second=128.784Mi/s
dense_insert_value_lengths<unodb::mutex_db>/100/value len log10:3          11.3 us         11.4 us        61435 bytes_per_second=92.2541Mi/s
dense_insert_value_lengths<unodb::mutex_db>/100/value len log10:4          41.5 us         41.5 us        16057 bytes_per_second=27.5823Mi/s
dense_insert_value_lengths<unodb::mutex_db>/800/value len log10:0          58.0 us         58.0 us        12071 bytes_per_second=105.204Mi/s
dense_insert_value_lengths<unodb::mutex_db>/800/value len log10:1          57.2 us         57.2 us        12252 bytes_per_second=120.011Mi/s
dense_insert_value_lengths<unodb::mutex_db>/800/value len log10:2          58.9 us         58.9 us        11884 bytes_per_second=129.469Mi/s
dense_insert_value_lengths<unodb::mutex_db>/800/value len log10:3          94.0 us         94.1 us         7441 bytes_per_second=89.2288Mi/s
dense_insert_value_lengths<unodb::mutex_db>/800/value len log10:4           363 us          363 us         1918 bytes_per_second=25.2024Mi/s
dense_insert_value_lengths<unodb::mutex_db>/6400/value len log10:0          461 us          461 us         1519 bytes_per_second=105.946Mi/s
dense_insert_value_lengths<unodb::mutex_db>/6400/value len log10:1          455 us          455 us         1541 bytes_per_second=120.757Mi/s
dense_insert_value_lengths<unodb::mutex_db>/6400/value len log10:2          475 us          475 us         1473 bytes_per_second=128.413Mi/s
dense_insert_value_lengths<unodb::mutex_db>/6400/value len log10:3          833 us          834 us          842 bytes_per_second=80.5321Mi/s
dense_insert_value_lengths<unodb::mutex_db>/6400/value len log10:4         9923 us         9923 us           70 bytes_per_second=7.38106Mi/s
dense_insert_value_lengths<unodb::mutex_db>/51200/value len log10:0        3595 us         3595 us          195 bytes_per_second=108.659Mi/s
dense_insert_value_lengths<unodb::mutex_db>/51200/value len log10:1        3561 us         3561 us          197 bytes_per_second=123.416Mi/s
dense_insert_value_lengths<unodb::mutex_db>/51200/value len log10:2        3832 us         3832 us          183 bytes_per_second=127.427Mi/s
dense_insert_value_lengths<unodb::mutex_db>/51200/value len log10:3       10089 us        10089 us           68 bytes_per_second=53.2394Mi/s
dense_insert_value_lengths<unodb::mutex_db>/51200/value len log10:4       85274 us        85273 us            9 bytes_per_second=6.8713Mi/s
dense_insert_value_lengths<unodb::mutex_db>/409600/value len log10:0      32290 us        32289 us           22 bytes_per_second=96.7807Mi/s
dense_insert_value_lengths<unodb::mutex_db>/409600/value len log10:1      32273 us        32272 us           22 bytes_per_second=108.937Mi/s
dense_insert_value_lengths<unodb::mutex_db>/409600/value len log10:2      39258 us        39258 us           18 bytes_per_second=99.5022Mi/s
dense_insert_value_lengths<unodb::mutex_db>/409600/value len log10:3      99724 us        99723 us            6 bytes_per_second=43.0879Mi/s
dense_insert_value_lengths<unodb::mutex_db>/409600/value len log10:4    1520367 us      1520353 us            1 bytes_per_second=3.08317Mi/s
dense_insert_value_lengths<unodb::olc_db>/100/value len log10:0            11.7 us         11.7 us        59665 bytes_per_second=65.0404Mi/s
dense_insert_value_lengths<unodb::olc_db>/100/value len log10:1            11.8 us         11.8 us        59357 bytes_per_second=72.785Mi/s
dense_insert_value_lengths<unodb::olc_db>/100/value len log10:2            12.8 us         12.8 us        54733 bytes_per_second=74.6056Mi/s
dense_insert_value_lengths<unodb::olc_db>/100/value len log10:3            17.5 us         17.5 us        39915 bytes_per_second=59.8242Mi/s
dense_insert_value_lengths<unodb::olc_db>/100/value len log10:4            48.4 us         48.4 us        13858 bytes_per_second=23.6375Mi/s
dense_insert_value_lengths<unodb::olc_db>/800/value len log10:0            95.3 us         95.4 us         7341 bytes_per_second=64.01Mi/s
dense_insert_value_lengths<unodb::olc_db>/800/value len log10:1            95.5 us         95.6 us         7304 bytes_per_second=71.8548Mi/s
dense_insert_value_lengths<unodb::olc_db>/800/value len log10:2            95.6 us         95.6 us         7318 bytes_per_second=79.7975Mi/s
dense_insert_value_lengths<unodb::olc_db>/800/value len log10:3             139 us          139 us         5028 bytes_per_second=60.3006Mi/s
dense_insert_value_lengths<unodb::olc_db>/800/value len log10:4             408 us          408 us         1717 bytes_per_second=22.4205Mi/s
dense_insert_value_lengths<unodb::olc_db>/6400/value len log10:0            769 us          769 us          910 bytes_per_second=63.4725Mi/s
dense_insert_value_lengths<unodb::olc_db>/6400/value len log10:1            772 us          772 us          907 bytes_per_second=71.1731Mi/s
dense_insert_value_lengths<unodb::olc_db>/6400/value len log10:2            774 us          774 us          903 bytes_per_second=78.8879Mi/s
dense_insert_value_lengths<unodb::olc_db>/6400/value len log10:3           1203 us         1204 us          581 bytes_per_second=55.7839Mi/s
dense_insert_value_lengths<unodb::olc_db>/6400/value len log10:4          10317 us        10318 us           68 bytes_per_second=7.09863Mi/s
dense_insert_value_lengths<unodb::olc_db>/51200/value len log10:0          6103 us         6103 us          114 bytes_per_second=64.0056Mi/s
dense_insert_value_lengths<unodb::olc_db>/51200/value len log10:1          6152 us         6152 us          114 bytes_per_second=71.4275Mi/s
dense_insert_value_lengths<unodb::olc_db>/51200/value len log10:2          6131 us         6131 us          114 bytes_per_second=79.6408Mi/s
dense_insert_value_lengths<unodb::olc_db>/51200/value len log10:3         13249 us        13249 us           52 bytes_per_second=40.5397Mi/s
dense_insert_value_lengths<unodb::olc_db>/51200/value len log10:4         86988 us        86987 us            8 bytes_per_second=6.7359Mi/s
dense_insert_value_lengths<unodb::olc_db>/409600/value len log10:0        53322 us        53320 us           13 bytes_per_second=58.6082Mi/s
dense_insert_value_lengths<unodb::olc_db>/409600/value len log10:1        54061 us        54060 us           13 bytes_per_second=65.0317Mi/s
dense_insert_value_lengths<unodb::olc_db>/409600/value len log10:2        55211 us        55210 us           12 bytes_per_second=70.752Mi/s
dense_insert_value_lengths<unodb::olc_db>/409600/value len log10:3       125501 us       125501 us            6 bytes_per_second=34.2379Mi/s
dense_insert_value_lengths<unodb::olc_db>/409600/value len log10:4      1542133 us      1542118 us            1 bytes_per_second=3.03965Mi/s
dense_insert_dup_attempts<unodb::db>/32768                                  560 us          559 us         1251 items_per_second=58.6162M/s
dense_insert_dup_attempts<unodb::db>/262144                                7447 us         7445 us           93 items_per_second=35.2107M/s
dense_insert_dup_attempts<unodb::db>/2097152                              71139 us        71135 us           10 items_per_second=29.4811M/s
dense_insert_dup_attempts<unodb::db>/16777216                            560253 us       560241 us            1 items_per_second=29.9464M/s
dense_insert_dup_attempts<unodb::db>/30000000                           1202460 us      1202443 us            1 items_per_second=24.9492M/s
dense_insert_dup_attempts<unodb::mutex_db>/100                             3.64 us         3.64 us       192508 items_per_second=27.5067M/s
dense_insert_dup_attempts<unodb::mutex_db>/512                             18.7 us         18.7 us        37458 items_per_second=27.3765M/s
dense_insert_dup_attempts<unodb::mutex_db>/4096                             142 us          142 us         4941 items_per_second=28.914M/s
dense_insert_dup_attempts<unodb::mutex_db>/32768                           1050 us         1049 us          668 items_per_second=31.2292M/s
dense_insert_dup_attempts<unodb::mutex_db>/262144                         11268 us        11266 us           62 items_per_second=23.2681M/s
dense_insert_dup_attempts<unodb::mutex_db>/2097152                       100195 us       100191 us            7 items_per_second=20.9315M/s
dense_insert_dup_attempts<unodb::mutex_db>/16777216                      766546 us       766533 us            1 items_per_second=21.8871M/s
dense_insert_dup_attempts<unodb::mutex_db>/30000000                     1597123 us      1597096 us            1 items_per_second=18.7841M/s
dense_insert_dup_attempts<unodb::olc_db>/100                               7.11 us         7.10 us        98610 items_per_second=14.0772M/s
dense_insert_dup_attempts<unodb::olc_db>/512                               38.3 us         38.2 us        18311 items_per_second=13.3907M/s
dense_insert_dup_attempts<unodb::olc_db>/4096                               295 us          295 us         2375 items_per_second=13.8952M/s
dense_insert_dup_attempts<unodb::olc_db>/32768                             2385 us         2384 us          294 items_per_second=13.7421M/s
dense_insert_dup_attempts<unodb::olc_db>/262144                           22516 us        22515 us           31 items_per_second=11.6429M/s
dense_insert_dup_attempts<unodb::olc_db>/2097152                         186140 us       186133 us            4 items_per_second=11.2669M/s
dense_insert_dup_attempts<unodb::olc_db>/16777216                       1483655 us      1483632 us            1 items_per_second=11.3082M/s
dense_insert_dup_attempts<unodb::olc_db>/30000000                       3059797 us      3059712 us            1 items_per_second=9.80484M/s
2025-01-30T21:25:51+00:00
Running benchmark/micro_benchmark_key_prefix
Run on (48 X 3100.11 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x24)
  L1 Instruction 32 KiB (x24)
  L2 Unified 1024 KiB (x24)
  L3 Unified 36608 KiB (x1)
Load Average: 1.07, 1.20, 1.12
---------------------------------------------------------------------------------------------------------------
Benchmark                                                     Time             CPU   Iterations UserCounters...
---------------------------------------------------------------------------------------------------------------
unpredictable_get_shared_length<unodb::db>                0.859 us        0.863 us       811578 items_per_second=24.3406M/s
unpredictable_get_shared_length<unodb::mutex_db>           1.19 us         1.19 us       587785 items_per_second=17.6365M/s
unpredictable_get_shared_length<unodb::olc_db>             1.74 us         1.74 us       402268 items_per_second=12.0837M/s
unpredictable_leaf_key_prefix_split<unodb::db>             19.1 us         19.1 us        36676 items_per_second=13.2095M/s
unpredictable_leaf_key_prefix_split<unodb::mutex_db>       22.8 us         22.8 us        30727 items_per_second=11.0643M/s
unpredictable_leaf_key_prefix_split<unodb::olc_db>         38.7 us         38.6 us        18150 items_per_second=6.53124M/s
unpredictable_cut_key_prefix<unodb::db>                    20.6 us         20.5 us        34125 items_per_second=12.2644M/s
unpredictable_cut_key_prefix<unodb::mutex_db>              24.2 us         24.1 us        29051 items_per_second=10.4513M/s
unpredictable_cut_key_prefix<unodb::olc_db>                38.5 us         38.4 us        18231 items_per_second=6.56225M/s
unpredictable_prepend_key_prefix<unodb::db>                12.4 us         12.4 us        56563 items_per_second=20.3995M/s
unpredictable_prepend_key_prefix<unodb::mutex_db>          15.8 us         15.7 us        44462 items_per_second=16.0111M/s
unpredictable_prepend_key_prefix<unodb::olc_db>            41.6 us         41.5 us        16854 items_per_second=6.06765M/s

@thompsonbry
Copy link
Author

@laurynas-biveinis The set of benchmarks that are by "benchmarks/micro_benchmarks" is substantially different between those two versions. I was not expecting that. Also, the benchmark names have subtle changes (::benchmark was added) which might make it impossible to use tooling to make these comparisons.

However, spot checks do not show performance regressions where I can find the same db benchmark in both cases.

dense_insert<unodb::benchmark::db>/30000000 3156778 us 3156713 us 1 items_per_second=9.50356M/s
dense_insert<unodb::db>/30000000 3189730 us 3189695 us 1 items_per_second=9.40529M/s

sparse_insert_dups_allowed<unodb::benchmark::db>/10000000 9174377 us 9301956 us 1 items_per_second=1.07504M/s
sparse_insert_dups_allowed<unodb::db>/10000000 9058649 us 9174741 us 1 items_per_second=1.08995M/s

dense_insert_dup_attempts<unodb::benchmark::db>/30000000                           1260644 us      1260634 us            1 items_per_second=23.7975M/s
dense_insert_dup_attempts<unodb::db>/30000000                           1202460 us      1202443 us            1 items_per_second=24.9492M/s

@laurynas-biveinis
Copy link
Owner

laurynas-biveinis commented Jan 31, 2025 via email

@laurynas-biveinis
Copy link
Owner

@laurynas-biveinis The set of benchmarks that are by "benchmarks/micro_benchmarks" is substantially different between those two versions. I was not expecting that. Also, the benchmark names have subtle changes (::benchmark was added) which might make it impossible to use tooling to make these comparisons.

Can we push a ::benchmark-adding patch to master?

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
13.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@thompsonbry
Copy link
Author

@laurynas-biveinis A more complete survey of the benchmark comparison vs master.

::benchmark:: means varkeys branch. Results are master then varkeys.

The only clear regressions are in the iterator scans. I think that we will pick up that performance once we finish landing the variable length key support because we will stop comparing full keys in the leaves in the scan and switch to tracking the key in the iterator buffer and only comparing the trailing suffix of the key against the leaf.

Based on these data, I think that we do not have a blocker to merge based on performance.


dense_insert<unodb::db>/30000000                                        3189730 us      3189695 us            1 items_per_second=9.40529M/s
dense_insert<unodb::benchmark::db>/30000000                                        3156778 us      3156713 us            1 items_per_second=9.50356M/s

sparse_insert_dups_allowed<unodb::db>/10000000                          9058649 us      9174741 us            1 items_per_second=1.08995M/s
sparse_insert_dups_allowed<unodb::benchmark::db>/10000000                          9174377 us      9301956 us            1 items_per_second=1.07504M/s

dense_full_scan<unodb::db>/20000000                                    30352339 us     30351922 us            1 items_per_second=32.9468M/s
dense_full_scan<unodb::benchmark::db>/20000000                                    34077017 us     34076625 us            1 items_per_second=29.3456M/s
# Regression ^^^

dense_iter_full_fwd_scan<unodb::db>/268435456                         476324599 us    476321086 us            1 items_per_second=28.178M/s
dense_iter_full_fwd_scan<unodb::benchmark::db>/268435456                         587648829 us    587640055 us            1 items_per_second=22.8401M/s
# Regression ^^^

dense_iter_keyrange_fwd_scan<unodb::db>/268435456                     471978358 us    471974756 us            1 items_per_second=28.4375M/s
dense_iter_keyrange_fwd_scan<unodb::benchmark::db>/268435456                     660341463 us    660330631 us            1 items_per_second=20.3258M/s
# Regression ^^^

dense_tree_sparse_deletes<unodb::db>/4096000/deletes:4096000            3286887 us      3297432 us            1 items_per_second=1.24218M/s
dense_tree_sparse_deletes<unodb::benchmark::db>/4096000/deletes:4096000            3279353 us      3291594 us            1 items_per_second=1.24438M/s

dense_tree_increasing_keys<unodb::db>/30000000                             97.6 ms         97.6 ms            7 items_per_second=20.5019M/s
dense_tree_increasing_keys<unodb::benchmark::db>/30000000                              101 ms          101 ms            7 items_per_second=19.7964M/s
# Wobbler.  Might be a small regression, but probably noise.

dense_insert_value_lengths<unodb::db>/409600/value len log10:0            26293 us        26292 us           27 bytes_per_second=118.857Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:1            26061 us        26061 us           27 bytes_per_second=134.899Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:2            32921 us        32921 us           21 bytes_per_second=118.656Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:3            91937 us        91937 us            7 bytes_per_second=46.7374Mi/s
dense_insert_value_lengths<unodb::db>/409600/value len log10:4          1512622 us      1512601 us            1 bytes_per_second=3.09897Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:0            25747 us        25746 us           27 bytes_per_second=121.376Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:1            25353 us        25352 us           28 bytes_per_second=138.671Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:2            32527 us        32527 us           21 bytes_per_second=120.094Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:3            93773 us        93773 us            7 bytes_per_second=45.8222Mi/s
dense_insert_value_lengths<unodb::benchmark::db>/409600/value len log10:4          1520769 us      1520754 us            1 bytes_per_second=3.08235Mi/s
# Wobbler.  Better on smaller values and slightly worse on log10:3.  Likely entirely noise.

dense_insert_dup_attempts<unodb::db>/30000000                           1202460 us      1202443 us            1 items_per_second=24.9492M/s
dense_insert_dup_attempts<unodb::benchmark::db>/30000000                           1260644 us      1260634 us            1 items_per_second=23.7975M/s
# Wobbler.  Small regression?  Or just noise.

.gitignore Show resolved Hide resolved
art.cpp Show resolved Hide resolved
art.hpp Show resolved Hide resolved
art.hpp Show resolved Hide resolved
art.hpp Show resolved Hide resolved
test/CMakeLists.txt Show resolved Hide resolved
test/db_test_utils.hpp Show resolved Hide resolved
test/db_test_utils.hpp Show resolved Hide resolved
test/test_art_span.cpp Show resolved Hide resolved
test/test_key_encode_decode.cpp Show resolved Hide resolved
@thompsonbry
Copy link
Author

Closing and replacing with #675 due to a local repository SNAFU.

@thompsonbry thompsonbry closed this Feb 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants