2.0.2: Changes (dependency update — 2026-02-28):
    * Bump `rand` 0.9 → 0.10: replace `use rand::Rng` with `use rand::RngExt` in
      `src/crypto_hash/mod.rs` and `src/rust_hash/mod.rs` (`fill` moved to `RngExt` in rand 0.10)
    * Fix bench warning: replace deprecated `criterion::black_box` with `std::hint::black_box`
      in `benches/throughput.rs` (deprecated since criterion 0.8, stabilised in Rust 1.66)

2.0.1: update readme and publish
2.0.1-RC1: Changes (Benchmark correctness):
    * Fix `benches/throughput.rs`: `IdsService::stop()` clears the cache — benchmarks were
      measuring on-the-fly `make_id()` fallback instead of genuine cache hits
    * Replace `b.iter()` with `iter_custom` using batched timed windows: setup (service
      creation + cache fill) and teardown (thread join via `stop()`) are fully excluded from
      measurement
    * Worker threads sleep for 10 ms when the cache is full; the timed window starts
      immediately after `filled_event()` fires, guaranteeing zero Mutex contention
    * `CACHE_SIZE (1 000) > BENCH_BATCH (500)` invariant enforced — every measured `get_id()`
      call is a guaranteed cache hit with no on-the-fly fallback
    * Add `criterion::black_box` on all return values to prevent dead-code elimination by LLVM
    * Remove duplicate `svc.stop()` call that was present after `bench_rust_service_get_id`
    * Cache-hit throughput now correctly reflects Mutex + VecDeque::pop_front overhead:
        - `crypto_hash` (SHA3-256 / SHA3-512): ~75–130 ns  (~7–10× faster than standalone)
        - `rust_hash`:                          ~100–150 ns (~6–8×  faster than standalone)

2.0.0-RC1: Changes (BREAKING — Rust 2026 modernisation):
    * BREAKING: Traits `Encode`, `Uids`, `Service` now have required methods instead of `unimplemented!()` defaults
    * BREAKING: `rust_hash::create_id()` now returns `u64` directly (no longer `Result<u64, rand::Error>`)
    * BREAKING: `get_cache_len()` is now `&self` instead of `&mut self`
    * Bump `rand` 0.8 → 0.9 (API: `thread_rng()` → `rand::rng()`, `gen_range` → `random_range`, `try_fill_bytes` → `fill`)
    * Remove `lazy_static` dependency — replaced by `std::sync::LazyLock` (stable since Rust 1.80)
    * Remove `num_cpus` dependency — replaced by `std::thread::available_parallelism()` (stable since Rust 1.59)
    * Remove `simplelog` from main dependencies (moved to dev-dependencies)
    * Remove all `extern crate` declarations (obsolete since Rust 2018 edition)
    * Replace busy-spin in `filled_at_percent_event` with `std::sync::Condvar` — eliminates 100 % CPU waste
    * Improve Mutex poisoning handling: `unwrap_or_else(|e| e.into_inner())` throughout
    * Unify licence headers: MIT everywhere (was GPL in file headers, MIT in Cargo.toml)
    * Rewrite all doc-comments with modern style (no `extern crate`, no `fn main()` wrappers)
    * Add `criterion` benchmarks in `benches/throughput.rs`
    * Modernise CI/CD: add `fmt`, `clippy -D warnings`, `cargo audit`; pin image to `rust:1.92`
    * All thread names are now descriptive (e.g. `ids-crypto-0`, `ids-rh-1`)
    * Add `rust-version = "1.80"` to `Cargo.toml`
    * 47 tests pass (27 unit + 20 doc-tests), 0 clippy warnings

1.3.7: Changes:
    * Update Cargo.toml categories
1.3.6: Changes:
    * Update Cargo.toml header
    * Update documentation
1.3.5: Changes:
    * Update dependencies and test with rust 1.66
    * Solve new clippy
1.3.4: Changes:
    * Remove use of dependency chrono
1.3.3: Changes:
    * Update dependencies and test with rust 1.57
1.3.2: Changes:
    * Update dependencies and test with rust 1.51
    * Solve new clippy warning
1.3.1: Changes:
    * Update dependencies and test with rust 1.37
1.3.0: Changes:
    * Change dependencies rust-crypto to sha3.
        * Note it improve the throughput to around 25% faster
    * Update dependencies
    * Change back to use thread_rng() instead of using one random generator per thread.
1.2.1: Changes:
    * Update dependencies
    * Add function
        * _pub fn filled_at_percent_event(&mut self, percentage : u8) -> mpsc::Receiver<bool>_
    * Change the default number of thread from constant to the number of CPU's
    * Solve issue #3
1.2.0: Changes:
    * Refactor and split libs.rs to mod.rs
    * Add module rust_hash
    * Change Random number generators from one instance to one instance per thread
    * Minors improvement
1.1.0: Changes:
    * Solve issues 1 & 2 with Raspberry and Windows 10 by changing multi threads management
    * Add functions:
        * _fn stop(&mut self)_
        * _fn get_id_from_cache(&mut self) -> Option\<Vec\<u8\>\>_
        * _fn filled_event(&mut self) -> mpsc::Receiver\<bool\>_
        * _fn as_json(&self) -> String_ to Trait Encode
     * Solve all clippy warnings
     * Tests with Raspberry Pi3
     * Tests with Windows 10
     * Change default to sha256 and 100_000 cache size
1.0.2: Changes:
    * random block size from _hash size_ to _2 * hash size_ see [Birthday problem](https://en.m.wikipedia.org/wiki/Birthday_problem#Probability_table)
    * Change default from sha512 to sha256
1.0.1: Add ten_million example
1.0.0: Refactor to no generic service, it uses cryptographic hash algorithm only. The internal multi-threads model is more efficient. The API is not compatible with 0.1.6.
0.1.6: add function to read configuration from toml file _read_configuration_from_toml_
0.1.5: Update readme and comments
0.1.4: Add two helper function to create on fly id _create_id_as_u128_ and _create_id_as_string_
0.1.0: to :0.1.3: Non functional, some adaptation for crates.io and bitbucket pipelines
