Skip to content

Add insert() and erase() to editable json_documents - #5631

Closed
nlohmann wants to merge 8 commits into
json-view/19-edit-setfrom
json-view/20-edit-structure
Closed

nlohmann wants to merge 8 commits into
json-view/19-edit-setfrom
json-view/20-edit-structure

Conversation

@nlohmann

@nlohmann nlohmann commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Part of the stack for the zero-copy view (#5295).

Summary

Editable documents can now change the structure of arrays and objects:

  • insert(array, index, value) inserts before an element (index <= size()) and returns a view of the new element;
  • erase(object, key) removes all members with the key and returns their number;
  • erase(array, index) removes an element;
  • erase(json_pointer) removes the member or element a pointer names and returns the number of removed values.

A view of an erased value keeps its last value. Views of other values keep referring to them when elements move.

Errors are those of basic_json: type_error.307/309 and out_of_range.401/403/405.

bench_edit.cpp joins the comparison harness. It parses, applies the same logical edits with each library's own API (a handful at fixed places, or one in every record), and serializes; all outputs must describe the same value. compare.py builds and runs it with the other two programs.

Benchmarks

bench_edit at this PR, on Apple M1, best of 25 rounds. Each run parses, applies the edits, and serializes. json_view's time is the base (1.00×); higher factors are slower:

document edits json_view yyjson Boost.JSON json
twitter patch 463 µs 1.08× 2.91× 4.95×
citm_catalog patch 756 µs 1.21× 2.58× 5.91×
canada patch 10.7 ms 0.35× 0.61× 1.67×
jeopardy update 71.4 ms 1.20× 2.13× 3.70×
status (small) patch 2.78 µs 0.99× 2.30× 4.15×
rpc (tiny) patch 0.40 µs 0.87× 1.01× 2.39×

Serializing (dump()) takes about half of json_view's time on twitter and most of it on canada. It gets faster later in the stack, in the PRs that add the compact writer, Żmij, and floats written from their digits. At the top of the stack (same machine and method, patch):

  • twitter 309 µs (yyjson 1.65×), citm_catalog 567 µs;
  • canada 5.69 ms, still behind yyjson (3.86 ms), whose float writer is faster.

x86-64 numbers are still missing.

Tests

  • The differential test also inserts and erases members and elements, directly and through JSON pointers.
  • The errors.
  • Views across inserts and erasures.
  • Duplicate keys and large objects.

Documentation

  • API pages for insert and erase, with examples.
  • The editing section of the feature page names them.

Public API

No breaking change. The new members exist only for editable documents.


Written by Claude Code.

🤖 Generated with Claude Code

@nlohmann
nlohmann added this pull request to stack #5636 September 29, 2026 14:20
@nlohmann nlohmann changed the title json view/20 edit structure Add insert() and erase() to editable json_documents Sep 29, 2026
@github-actions github-actions Bot added documentation L tests python Pull requests that update Python code labels Sep 29, 2026
@nlohmann
nlohmann removed this pull request from stack #5636 September 30, 2026 13:19
@nlohmann
nlohmann force-pushed the json-view/19-edit-set branch from 711ddc4 to c675bcd Compare September 30, 2026 13:20
@nlohmann
nlohmann force-pushed the json-view/20-edit-structure branch from 0e14d93 to 274be40 Compare September 30, 2026 13:20
@nlohmann
nlohmann added this pull request to stack #5739 September 30, 2026 13:21
@nlohmann
nlohmann force-pushed the json-view/19-edit-set branch from c675bcd to ad5feb1 Compare September 30, 2026 15:34
@nlohmann
nlohmann force-pushed the json-view/20-edit-structure branch 3 times, most recently from 580f0f9 to 9c0bd2b Compare September 30, 2026 18:06
@nlohmann nlohmann added the review needed It would be great if someone could review the proposed changes. label Sep 30, 2026
@nlohmann
nlohmann marked this pull request as ready for review September 30, 2026 18:16
- insert(array, index, value): insert before an element (index <= size)
- erase(object, key): remove all members with the key; returns their
  number
- erase(array, index): remove an element
- erase(json_pointer): remove the member or element a pointer names

The errors are those of basic_json (type_error.307/309,
out_of_range.401/403/405). A view of an erased value keeps its last value,
and views of other values keep referring to them when elements move.

Tests: the differential test now also inserts and erases members and
elements, directly and through JSON pointers; plus the errors, views
across inserts and erasures, duplicate keys, and large objects.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
bench_edit.cpp joins the comparison: parse, apply the same logical edits
with each library's own API (a handful at fixed places, or one in every
record), and serialize; all outputs must describe the same value.
compare.py builds and runs it with the other two programs.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Add API reference pages for basic_json_document::insert and
basic_json_document::erase, matching the style of set.md and
push_back.md: signatures, parameters, return values, exception safety,
exceptions with their exact ids and messages, complexity, notes on
duplicate keys and view/iterator validity, and an example.

Add example programs basic_json_document__insert.cpp and
basic_json_document__erase.cpp with their expected output, each
comparing an edit on an editable document with the same edit on a
plain json value to show what is preserved: member order, the
spelling of untouched numbers, and, for insert, that a view taken
before the insert keeps referring to the same element after its index
shifts.

Register both new pages in mkdocs.yml, docSet.sql, and the member list
of basic_json_document/index.md, add cross-references to them from
set.md and push_back.md, and mention insert/erase in the "Editing a
document" section of features/json_view.md.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
@nlohmann
nlohmann force-pushed the json-view/19-edit-set branch from d52db33 to 467ccfd Compare September 30, 2026 19:19
@nlohmann
nlohmann force-pushed the json-view/20-edit-structure branch from 9c0bd2b to a496c70 Compare September 30, 2026 19:19
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Comment thread tests/benchmarks/json_view/bench_edit.cpp Dismissed
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
@nlohmann
nlohmann removed this pull request from stack #5739 October 6, 2026 09:26
@nlohmann

nlohmann commented Oct 6, 2026

Copy link
Copy Markdown
Owner Author

The zero-copy view stack (#5295) was rebased onto develop and regrouped from 20 PRs into 10, one squashed commit each. The changes of this PR are now in #5630 (the bench_edit benchmark went to #5627); its review comments stay here for reference.


Written by Claude Code.

@nlohmann nlohmann closed this Oct 6, 2026
@nlohmann
nlohmann deleted the json-view/20-edit-structure branch October 12, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation L python Pull requests that update Python code review needed It would be great if someone could review the proposed changes. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants