Skip to content

Switch typed-read extension point to Base.read(::MDBValueIO, T).#55

Merged
maleadt merged 1 commit into
mainfrom
tb/io
May 22, 2026
Merged

Switch typed-read extension point to Base.read(::MDBValueIO, T).#55
maleadt merged 1 commit into
mainfrom
tb/io

Conversation

@maleadt

@maleadt maleadt commented May 21, 2026

Copy link
Copy Markdown
Collaborator

Replace LMDB.mdb_unpack(::Type{T}, ::Ref{MDB_val}) — the package's typed-read customization point — with a plain IO view over the LMDB-owned MDB_val. Users now plug in custom decoders by defining the idiomatic Base.read(io::IO, ::Type{MyType}), which works against any byte stream and is the convention every other Julia decoder uses.

  struct PrefixedBlob end
  function Base.read(io::IO, ::Type{PrefixedBlob})
      skip(io, 8)
      return read(io, String)
  end

  LMDB.tryget(txn, dbi, key, PrefixedBlob)

MDBValueIO <: IO exposes position / seek / seekstart / seekend / skip / bytesavailable / eof and overrides unsafe_read so Base's primitive read(io, T) for Int8…Float64/Bool/Char/Ptr inherits zero-allocation. The default read(io, String) and read(io, Vector{E}) consume the rest of the buffer and copy out.

Internal call sites in cur.jl / dbi.jl / dicts.jl switch from mdb_unpack(T, ref) to read(MDBValueIO(ref[]), T). The package exposes LMDB.MDBValueIO for users who override Base.read.


Last piece of functionality I had locally, will focus on cleaning up things tomorrow.

Replace `LMDB.mdb_unpack(::Type{T}, ::Ref{MDB_val})` — the package's
typed-read customization point — with a plain `IO` view over the
LMDB-owned `MDB_val`. Users now plug in custom decoders by defining
the idiomatic `Base.read(io::IO, ::Type{MyType})`, which works against
any byte stream and is the convention every other Julia decoder uses.

  struct PrefixedBlob end
  function Base.read(io::IO, ::Type{PrefixedBlob})
      skip(io, 8)
      return read(io, String)
  end

  LMDB.tryget(txn, dbi, key, PrefixedBlob)

`MDBValueIO <: IO` exposes `position` / `seek` / `seekstart` / `seekend`
/ `skip` / `bytesavailable` / `eof` and overrides `unsafe_read` so
Base's primitive `read(io, T)` for `Int8…Float64`/`Bool`/`Char`/`Ptr`
inherits zero-allocation. The default `read(io, String)` and
`read(io, Vector{E})` consume the rest of the buffer and copy out.

Internal call sites in `cur.jl` / `dbi.jl` / `dicts.jl` switch from
`mdb_unpack(T, ref)` to `read(MDBValueIO(ref[]), T)`. The package
exposes `LMDB.MDBValueIO` for users who override `Base.read`.

`mdb_unpack` is dropped — breaking change for the (rare) caller who
defined their own `mdb_unpack` method.

Preserves PR #52's GC-safety fix: `common.jl` keeps the
deferred-pointer-extraction pattern from #52 (the upstream commit
this is based on pre-dates that fix). `MDBValue(::String)` and the
eager-extraction variants stay deleted; `cconvert(::Ptr{MDB_val}, x)`
returns an `MDBArg` carrier with an uninitialized box, and
`unsafe_convert(::Ptr{MDB_val}, ::MDBArg{D})` does the extraction
inside ccall's preserve window.

Tested locally on Julia 1.10, 1.11, 1.12, 1.13.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.11%. Comparing base (9bec48d) to head (f5735d3).

Files with missing lines Patch % Lines
src/common.jl 64.44% 16 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #55      +/-   ##
==========================================
- Coverage   83.40%   82.11%   -1.29%     
==========================================
  Files           9        9              
  Lines         717      755      +38     
==========================================
+ Hits          598      620      +22     
- Misses        119      135      +16     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maleadt
maleadt merged commit 581c7d7 into main May 22, 2026
8 of 10 checks passed
@maleadt
maleadt deleted the tb/io branch May 22, 2026 05:32
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.

1 participant