Skip to content

Update Rust crate fastcdc to v5 - #2710

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/fastcdc-5.x
Open

Update Rust crate fastcdc to v5#2710
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/fastcdc-5.x

Conversation

@renovate

@renovate renovate Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
fastcdc dependencies major 3.2.15.0.0

Release Notes

nlfiedler/fastcdc-rs (fastcdc)

v5.0.0

Compare Source

Breaking Changes
  • v2020 now requires even min_size, avg_size, and max_size. The
    "rolling two bytes each time" scan tests candidates in byte pairs starting
    at min_size / 2, avg_size / 2, and max_size / 2; an odd value
    truncates when halved and silently shifts those boundaries by one byte
    (issue #​52). For example min_size = 65 let the scan return a chunk as
    short as 64 bytes, violating the documented minimum. FastCDC,
    StreamCDC, and AsyncStreamCDC now debug_assert that all three sizes
    are even, as does the underlying cut/cut_gear scan itself. Callers
    using an odd size such as the max_size = 65535 from prior examples must
    switch to an even value (e.g. 65534); the built-in examples and doctests
    have been updated accordingly. Release builds are unaffected by the
    assertion (consistent with the existing MINIMUM_MIN/AVERAGE_MIN/etc.
    range checks), but odd sizes remain unsupported either way. (#​52)
Fixed
  • v2020 forced/tail chunks could report a stale hash. The leftover at
    the very end of a source is not required to be even (unlike min_size/
    avg_size/max_size, a file's length isn't under the caller's control),
    and the scan never folded that trailing odd byte into the hash before
    forcing a cut, so the returned fingerprint silently omitted the chunk's
    last byte. The trailing byte is now folded into the hash (matching what a
    byte-at-a-time scan would accumulate) without being tested as its own
    boundary candidate. Cut points for even-sized parameters are unchanged;
    only the hash of a chunk ending in a natural odd-length leftover changes.
    (#​52)
  • Iterator::size_hint upper bound could violate the trait contract. In
    ronomon, v2016, and v2020, a non-empty tail shorter than min_size
    still yields one final chunk, but size_hint computed its upper bound as
    remaining / min_size, which floors to 0 in that case — understating the
    actual number of items left. Now uses remaining.div_ceil(min_size) for the
    upper bound and reports a lower bound of 1 while data remains. Chunk
    boundaries are unchanged. (#​50)
  • v2020::AsyncStreamCDC and the v2020_cut example could select different
    masks than FastCDC/StreamCDC for the same avg_size.
    The sync
    constructors round avg_size.log2() to the nearest bit (so e.g. 12288
    selects the same bucket as 16384), but AsyncStreamCDC and the example
    used usize::ilog2, which floors instead (selecting the 8192 bucket).
    Both now go through a new shared v2020::select_masks function, so all
    three front-ends pick identical masks for identical arguments.
    Boundary change: Only affects AsyncStreamCDC output and the
    v2020_cut example's output, and only for non-power-of-two avg_size
    values; FastCDC and StreamCDC cut points are unchanged. (#​51)
Performance
  • v2020::cut_gear inner loop: restored array-typed GEAR lookups. The 4.0.0
    change from &[u64; 256] to &[u64] reintroduced a panic_bounds_check on
    every GEAR table lookup in the hot scan (4 of them per loop iteration).
    cut_gear now converts the tables to &[u64; 256] once via try_into, which
    the compiler can prove in-bounds for a u8-derived index. Cut points and
    hashes are unchanged (the existing fixture tests pin them); emitted asm drops
    from 8 to 4 panic_bounds_check sites in cut_gear, and an interleaved A/B
    measured ~7–14% throughput on random/text/zeros across chunk sizes (M1 Pro and
    a dedicated-CPU x86 VM). The &[u64]/Cow public signature is unchanged.
Added
  • v2020::FastCDC::rechunk — re-points an existing FastCDC at a new source
    and resets iteration, reusing the already-computed normalization masks and gear
    tables. The cheap way to chunk many in-memory buffers with identical parameters:
    avoids recomputing masks and (for a non-zero seed) re-allocating the gear tables
    on every FastCDC::new. The iterator already yields each chunk's offset/length
    without copying, so callers needing the chunk bytes can slice the source. Cut
    points are identical to a freshly constructed FastCDC.

v4.0.1

Compare Source

Fixed
  • Restore rounded-log mask selection. The 4.0.0 cleanup replaced the private
    logarithm2() helper (rounded log2) with usize::ilog2() (floored log2),
    which silently changed cut points for any avg_size that is not a power of
    two. Power-of-two sizes were unaffected. Cut points now match 3.2.1 again.

v4.0.0

Compare Source

Many changes suggested by Claude Code that seem worth making despite breaking the API. The changes needed are minor, just changing u32 to usize for the common use case.

Breaking Changes

Size parameter types changed from u32 to usize across all three modules (v2016, v2020, ronomon):

  • All public constructors: new(), with_level(), with_level_and_seed() for FastCDC, StreamCDC, and AsyncStreamCDC
  • Public constants MINIMUM_MIN, MINIMUM_MAX, AVERAGE_MIN, AVERAGE_MAX, MAXIMUM_MIN, MAXIMUM_MAX are now usize instead of u32
  • cut_gear() gear parameters changed from &[u64; 256] to &[u64]
  • get_gear_with_seed() return type changed from (Box<[u64; 256]>, Box<[u64; 256]>) to (Cow<'static, [u64]>, Cow<'static, [u64]>)
  • Error::Display output format changed (e.g. "chunker error: Empty""no more data")
  • Bounds checks on chunk size parameters changed from assert!() to debug_assert!(), meaning invalid sizes will no longer panic in release builds
Minor Changes
  • MASKS constant in v2016 is now pub (was private)
  • Normalization enum in both v2016 and v2020 now derives Eq and PartialEq
  • Normalization::bits() in v2016 is now pub (was private), and got a doc comment in v2020
Bug Fixes & Performance Improvements
  • size_hint() corrected in all three iterators: the lower bound was incorrectly returning the upper bound; now returns 1.min(upper_bound), which is semantically correct
  • Buffer extraction optimized in StreamCDC and AsyncStreamCDC: replaced drain(..).collect() + resize() with extend_from_slice() + copy_within(), avoiding unnecessary reallocation
  • get_gear_with_seed() optimized: when seed == 0, the static GEAR tables are borrowed directly via Cow::Borrowed instead of heap-allocating a copy
  • mask() in ronomon changed from 2u32.pow(bits) - 1 to (1u32 << bits) - 1 (equivalent but avoids potential debug-mode panics on overflow)

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.


This change is Reviewable

@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nativelink Ready Ready Preview Aug 22, 2026 6:44pm
nativelink-aidm Ready Ready Preview Aug 22, 2026 6:44pm

Request Review

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.

0 participants