The single features/json_view.md page grew to ~600 lines covering eight
topics. Split it into features/json_view/ with an overview page and
pages for ownership and lifetime, differences from basic_json, reading
values, generic code, editing, and images.
The new differences page collects what was spread over several sections
("What is the same", "What is different", "Duplicate keys", and notes in
the conversion and serialization sections) under one summary table, and
adds the parts of the basic_json interface a view does not have. The
other pages now link to it instead of restating the rules.
Internal links across the documentation point to the new pages.
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
3.7 KiB
Images
save() writes a document as an image: a byte buffer that
load() reads back into a document without parsing — no lexing, no building
the node index, nothing but copying the nodes and pointing the text and the decoded strings at the image. Where
parse_copy() still has to scan the whole input,
load() turns that scan into a copy of the node index alone.
Why
A document that is parsed once and then read many times — a configuration loaded at startup, a template rendered on
every request, a large reference dataset a worker process needs in memory — pays for parsing once but can amortize
save()'s cost across every later load. That makes images useful for a
cache: save a document the first time it is parsed (to a file, a shared-memory segment, an in-process cache), and
load() it on every later use instead of parsing the source text again.
They are just as useful for handing a parsed document to another process (or a forked worker) running the same build
of the library, since load() turns the transfer into a copy of the node
index plus pointers into the received bytes, not a re-parse.
Choosing a check
load() takes an
image_check that trades validation against speed:
image_check::full(the default) checks everything the parser itself guarantees, so a checked image is exactly as safe to read and serialize as a freshly parsed document — the right choice whenever the image did not come straight from this process's ownsave(), such as a file or a network peer.image_check::boundsonly checks structure and bounds — cheaper, since it skips scanning the text and the decoded strings — and fits a cache the process trusts, one it wrote and reads back itself.image_check::noneskips validation entirely, for an image trusted as much as the process's own memory.
See load()'s Notes for exactly what each level does and does not
guarantee.
??? example "Example: cache a parsed configuration as an image"
```cpp
--8<-- "examples/basic_json_document__save.cpp"
```
Output:
```json
--8<-- "examples/basic_json_document__save.output"
```
!!! warning "Experimental"
The image format is versioned but not yet stable, and may change in an incompatible way before it is declared
stable. It is little-endian only (on big-endian targets, `save()` and `load()` do not exist), and tied to the
library build that wrote it — use it to cache a document or to hand one to another process running the *same*
build, not as a long-term storage format; keep the original JSON text if a saved document needs to be readable by
a future library version.
Credits
The idea of a document you can read without parsing comes from zero-copy formats such as
FlatBuffers and YaFF; the check
load() runs follows the idea of FlatBuffers' Verifier. No code is taken from
either.
See also
- Zero-copy JSON views - overview
save()- write a document as an imageload()- read an image back into a document
Version history
- Added in version 3.13.0.