Skip to content

v2.1.1

Latest

Choose a tag to compare

@ingim ingim released this 04 Aug 20:28
· 7 commits to main since this release

A second pass over the crate's surface, after reading 2.1.0 back. The
container is untouched — no .zt file changes meaning — and so is every
operation. What changed is which of them exist.

⚠️ This breaks the API in a patch release

That is not what a patch number means. It is deliberate and it is a one-off:
2.1.0 had a single user, updated in the same breath, and spending 3.0.0 on a
surface that had been public for a week would have priced the next real major
bump out of the range where it belongs.

Anything depending on ztensor = "2.1" resolves into this and will not
compile. Pin =2.1.0 if that is a problem. From here on the number means what
it says.

Removed

  • The nine Tensor methods that were self.data()?.<the same name>() —
    bytes, map, locate, caps, dtype, logical, nbytes, prefetch,
    evict. They read as whole-tensor operations and were not: each addressed
    the "data" part, while verify on the same receiver covered every part,
    with nothing to tell them apart. verify stays as it was; the rest move one
    call along — t.data()?.map(), and t.parts() for the ones that are not
    "data".
  • Bytes — it was Cow<'a, [u8]> with two methods renamed and a name that
    collides with the bytes crate. Part::bytes returns the Cow now.
  • Source::index and Source::from_parts_with — both restated
    Options. Use Source::options().map(false).open(path) and
    Source::options().vocabulary(&v).from_parts(stores, catalog).
  • Tensor::entry — no caller, and it leaked provide::Entry into the
    reader's surface.
  • PositionalResolver / CasResolver — a closure with a struct around it,
    and ShardResolver is already implemented for closures. Now
    read::positional(root) and read::cas(dir). DirectoryResolver stays a
    type: it holds a scan index and a digest cache.

Changed

  • PartBuilder::external takes what the caller knows: a shard name and a
    byte range, external("00001", offset..end). It used to take a
    format::Part, so referencing a blob meant hand-assembling a manifest
    record and importing format::Part under an alias to keep it apart from
    read::Part. That collision is gone with it.
  • Renames, each towards a convention the crate or std already had:
    Verified::checked → is_checked, Provenance::root → as_root,
    Catalog::entry → get_key_value, provide::Opaque → provide::Decode
    (read → decode), Store::with_opaque → with_decoder.
  • read::shard_identity is no longer re-exported at the crate root, so it
    sits with its two siblings manifest_of and canonical_violations.

Fixed

  • A part with two payloads is refused. p.bytes(&data).length(4) compiled,
    silently dropped data, and wrote a file whose blob was never filled in.
  • A digest on a part the writer writes is refused — it could only agree
    with the computed digest or be wrong. PartBuilder::digest is new, and is
    for external parts.
  • An external part with an encoding is refused rather than silently
    dropping the encoding.

The full entry, including why the closure-builder shape rules out catching the
first of those in the type system, is in
CHANGELOG.md.

Full Changelog: v2.1.0...v2.1.1