Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
bitcoinleveldb-hash
A minimal, no_std-friendly implementation of LevelDB's 32‑bit hash primitive, extracted for use in Bitcoin-related and embedded contexts.
Overview
bitcoinleveldb-hash implements the 32‑bit hash function used internally by Google's LevelDB, exposed as a single low‑level function that operates on raw pointers. This hash is used by LevelDB for:
- Hash table bucketing
- Bloom filter key hashing
- Lightweight checksumming / sharding logic
The implementation in this crate is a faithful Rust port of the original C++ routine, preserving:
- Exact 32‑bit wrapping arithmetic
- Little‑endian decoding semantics
- Tail‑byte mixing behavior
- Seed‑dependent initialization
The function signature:
This is intentionally low level and unsafe‑adjacent (raw address, explicit length). The interface is suitable for high‑performance code where you already manipulate buffers as (ptr, len) pairs (e.g. database internals, FFI, or custom allocators).
The algorithm is structurally similar to a 32‑bit Murmur‑style hash: it performs block‑wise mixing using a fixed multiplier and shift, then folds remaining bytes with a small tail routine. Specifically, it uses constant M = 0xc6a4a793 and a right shift R = 24 during finalization, closely mirroring LevelDB's original implementation.
Features
- Deterministic LevelDB‑compatible hash: Intended to produce the same output as LevelDB's C++
Hash()function for identical inputs and seed. - Low‑level pointer interface: Accepts
*const u8and a byte length; ideal where copying or slice conversion would be overhead. no_stdfriendly core: The fundamental logic relies only oncoreand raw pointers; logging uses macros from thelogecosystem but can be compiled out.- Seeded hashing: The
seedparameter allows domain separation and mitigation of trivial collision patterns.
Safety model
The function is declared pub fn (not unsafe fn), but internally uses unsafe blocks to read from data. As a user, you must uphold the following invariants:
datamust be a valid, non‑null pointer to at leastnbytes of readable memory.- The region
[data, data.add(n))must be fully initialized. - The memory region may be aliased, but only read (no concurrent mutation that would cause undefined behavior with raw reads).
Violating these invariants results in undefined behavior. If you prefer a safe, slice‑based wrapper, add one in your own crate, for example:
use leveldb_hash;
Usage
Add to Cargo.toml:
[]
= "0.1.19"
Basic example
use leveldb_hash;
Using as a bucket index
use leveldb_hash;
This mirrors LevelDB's use of a 32‑bit hash for indexing into small hash tables.
Bloom‑filter style application
For a Bloom filter, one can derive multiple indices from a single hash by simple linear transformations:
use leveldb_hash;
This pattern parallels the construction used in LevelDB's own Bloom filter implementation.
Algorithmic notes
The internal structure of leveldb_hash is:
-
Initialization
const M: u32 = 0xc6a4a793; const R: u32 = 24; let mut h: u32 = seed ^ ;The input length is mixed with a fixed multiplier and XORed with the seed. This introduces sensitivity to both size and seed at the beginning of the chain.
-
Block processing (4 bytes at a time, little‑endian):
while offset + 4 <= nEach 32‑bit word is added, multiplied by
M, and subjected to a right‑shift XOR. This creates diffusion and avalanche behavior typical of non‑cryptographic hash functions. -
Tail processing (1–3 bytes): Remaining bytes are folded into
hwith left shifts by 8 and 16, then multiplied and mixed again:match remaining
All arithmetic uses wrapping_* operations to match the C++ semantics on 32‑bit unsigned integers.
This hash is not cryptographically secure. It is suitable for internal indexing, partitioning, and approximate data structures (Bloom filters, count‑min sketches), but not for adversarial settings where second‑preimage or collision resistance is required.
Logging and diagnostics
The implementation calls trace!, debug!, and error! macros. If you enable the log crate in your application and configure a logger (e.g. env_logger), you can observe the internal processing for debugging or verification:
With RUST_LOG=trace, you will see per‑chunk trace output, including offsets and intermediate hash values.
In production builds, you can disable logging or set higher log levels to eliminate runtime logging overhead.
Interoperability with LevelDB and Bitcoin code
Because this crate targets bit‑for‑bit compatibility with LevelDB's C++ hash algorithm, it can be used to:
- Reproduce LevelDB hash table indices computed by other implementations.
- Port filter policies (e.g. Bloom filters) from C++ LevelDB / Bitcoin Core to Rust.
- Validate that a Rust reimplementation of storage logic produces identical layout to an existing LevelDB store.
When interoperating, ensure you:
- Use the same byte order (little‑endian, as encoded in LevelDB keys/values).
- Match the seed exactly.
- Hash the same serialized key representation, including prefixes and varint‑encoded fields if present.
Repository and maintenance
This crate lives inside the bitcoin-rs repository:
- Repository: https://github.com/klebs6/bitcoin-rs
Issues and pull requests should be filed there, under the appropriate module or crate directory.
License
bitcoinleveldb-hash is distributed under the MIT license.
See the LICENSE file in the repository for full terms.