leptris 1.9.304.0-ppc64le-linux → 1.9.306.0-ppc64le-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Rakefile +1 -1
- data/lib/leptris/version.rb +1 -1
- data/lib/libleptris.so +0 -0
- data/vendor-src/README.md +1 -1
- data/vendor-src/libleptris/CHANGELOG.md +33 -0
- data/vendor-src/libleptris/CMakeLists.txt +1 -1
- data/vendor-src/libleptris/benchmarks/CMakeLists.txt +2 -0
- data/vendor-src/libleptris/benchmarks/modification/bench_append_attr_pugixml.cpp +36 -0
- data/vendor-src/libleptris/benchmarks/modification/bench_append_split.cpp +59 -0
- data/vendor-src/libleptris/src/leptris/dom/element_modify.c +33 -4
- data/vendor-src/libleptris/vcpkg.json +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b52c3a85fab2e17ea780a4a42824f5f5ef0a1e76de6e9785d9f1bf61f0a4e2a7
|
|
4
|
+
data.tar.gz: 8c493949121bf7418a97beabd4fee8329b1f2ee9ee0dc8219b7ec07bc2cf74ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d3aaf0027ab03316068eabb5173873cfb76f7c851f716270f5fb25355a31421309f33b7c9af262fba85f14b25688ac660c93e06b9a56e81c9484c7f16b2a262a
|
|
7
|
+
data.tar.gz: 2ae6b417a8f8a62d820d7af559e3a7f873b65f49da35739daae899187441b6b54e81ea6a0d01a27be5dc6089cb15d11ea5f7dd54ec63e37e3f7f23843dd29767
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 1.9.306.0 — 2026-10-05
|
|
2
|
+
|
|
3
|
+
Rides libleptris v1.9.306 (pin 1.9.304 -> 1.9.306): the Lane 18
|
|
4
|
+
mutation-path cycle — the adoption gate's mut-block fast bail
|
|
5
|
+
(#1531), cross-document splice adoption (#1528), and the Lane 18
|
|
6
|
+
gate bench made honest (warm both sides of the append row;
|
|
7
|
+
create/append split, leptris/leptris#1533). No binding-surface
|
|
8
|
+
change; the spec suite runs against the 1.9.306 engine.
|
|
9
|
+
|
|
1
10
|
## [1.9.304.0] - 2026-10-05
|
|
2
11
|
|
|
3
12
|
### Fixed
|
data/Rakefile
CHANGED
|
@@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec)
|
|
|
8
8
|
# Pin for `rake compile` and the platform-gem builds. Keep in lockstep
|
|
9
9
|
# with .github/workflows/build.yml (which calls `rake compile`) and the
|
|
10
10
|
# CHANGELOG when libleptris releases.
|
|
11
|
-
LIBLEPTRIS_VERSION = "1.9.
|
|
11
|
+
LIBLEPTRIS_VERSION = "1.9.306"
|
|
12
12
|
# Vendored alongside libleptris for fn:normalize-unicode (TODO
|
|
13
13
|
# .restructure/20): built per platform with a RELOCATABLE @rpath
|
|
14
14
|
# install name, loaded by ffi.rb before libleptris so the
|
data/lib/leptris/version.rb
CHANGED
data/lib/libleptris.so
CHANGED
|
Binary file
|
data/vendor-src/README.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.9.306] - 2026-10-05
|
|
4
|
+
|
|
5
|
+
<!-- Edit this section with the actual release notes. -->
|
|
6
|
+
<!-- See https://keepachangelog.com for format guidance. -->
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- (describe changes here)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [1.9.305] - 2026-10-05
|
|
14
|
+
|
|
15
|
+
### Performance
|
|
16
|
+
|
|
17
|
+
- **DOM: the #1528 adoption gate no longer taxes the append hot
|
|
18
|
+
path** — the first cut called `get_document` per splice, whose
|
|
19
|
+
namebp fast-out resolves the name slot before the check: append
|
|
20
|
+
measured 21.5 → 30.3 ns/child (+40%, 1.5x pugixml) and the
|
|
21
|
+
document build/free cycle +51% on the Lane 18 bench. `append_child`
|
|
22
|
+
now proves same-document in two hot loads — a child inside the
|
|
23
|
+
document's CURRENT mut-block extent was carved from this
|
|
24
|
+
document's own malloc by the create call just executed, so
|
|
25
|
+
nothing foreign can alias into it. Rolled-over-block children and
|
|
26
|
+
every other shape take the full adoption check; `prepend`/
|
|
27
|
+
`insert` keep it unconditionally. Measured paired-interleaved on
|
|
28
|
+
fresh Release trees: append 21.5 → 22.4 ns/child median (+0.8 ns,
|
|
29
|
+
+4%, the floor for a sound O(1) check), mutcycle +0.4 ns,
|
|
30
|
+
attr-parse within run noise. `CrossDocumentAdoption` stays green
|
|
31
|
+
on normal and ASAN builds; the binding fast paths all forward to
|
|
32
|
+
these public seams, so every route is covered.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
3
36
|
## [1.9.304] - 2026-10-05
|
|
4
37
|
|
|
5
38
|
### Fixed
|
|
@@ -210,6 +210,8 @@ endif()
|
|
|
210
210
|
# ----------------------------------------------------------------------------
|
|
211
211
|
leptris_add_benchmark(bench_serialize serialization/bench_leptris_serialize.c)
|
|
212
212
|
leptris_add_benchmark(bench_modify_leptris modification/bench_leptris_modify.c)
|
|
213
|
+
# Lane 18 (#1179 tail): the create/append split behind the gate row.
|
|
214
|
+
leptris_add_benchmark(bench_append_split modification/bench_append_split.cpp)
|
|
213
215
|
|
|
214
216
|
# Lane 18 (#1179): append + attr-parse vs pugixml (the lane bar is
|
|
215
217
|
# <=1x on both shapes). Needs C++ (pugixml.hpp) and the pugixml
|
|
@@ -19,6 +19,22 @@ int main(void) {
|
|
|
19
19
|
const int N_PARSE = 20000;
|
|
20
20
|
|
|
21
21
|
/* ---- append: 200k element children on one root ---- */
|
|
22
|
+
{
|
|
23
|
+
/* Warmup pass, untimed: the leptris row runs first in this
|
|
24
|
+
* bench, and its first-touch page faults (mut blocks + name
|
|
25
|
+
* blocks, ~9 MB at 200k children) landed in the timed row
|
|
26
|
+
* while pugixml's row ran second on a warm allocator — a
|
|
27
|
+
* systematic order bias. Both sides get the same warmup
|
|
28
|
+
* treatment; the timed rows below are steady-state. */
|
|
29
|
+
LeptrisDocument d = leptris_document_create();
|
|
30
|
+
LeptrisElement root = leptris_element_create(d, "root");
|
|
31
|
+
leptris_document_set_root(d, root);
|
|
32
|
+
for (int i = 0; i < N_APPEND; i++) {
|
|
33
|
+
LeptrisElement c = leptris_element_create(d, "c");
|
|
34
|
+
leptris_element_append_child(root, c);
|
|
35
|
+
}
|
|
36
|
+
leptris_document_free(d);
|
|
37
|
+
}
|
|
22
38
|
{
|
|
23
39
|
double t0 = now_ns();
|
|
24
40
|
LeptrisDocument d = leptris_document_create();
|
|
@@ -101,6 +117,26 @@ int main(void) {
|
|
|
101
117
|
printf("attrparse leptris: %7.1f ns/doc (%zu bytes)\n",
|
|
102
118
|
(t1 - t0) / N_PARSE, xml.size());
|
|
103
119
|
}
|
|
120
|
+
{
|
|
121
|
+
/* Door A (leptris#1436, shipped v1.9.272): the opt-in fast
|
|
122
|
+
* path — duplicate detection and source positions off. The
|
|
123
|
+
* default row above carries full conformance work pugixml
|
|
124
|
+
* does none of; this row shows the speed callers can opt
|
|
125
|
+
* into when their pipeline guarantees uniqueness and skips
|
|
126
|
+
* position reporting. */
|
|
127
|
+
LeptrisParseFlags flags = static_cast<LeptrisParseFlags>(
|
|
128
|
+
LEPTRIS_PARSE_SKIP_DUP_DETECTION |
|
|
129
|
+
LEPTRIS_PARSE_SKIP_SOURCE_POSITIONS);
|
|
130
|
+
double t0 = now_ns();
|
|
131
|
+
for (int i = 0; i < N_PARSE; i++) {
|
|
132
|
+
LeptrisDocument d = leptris_parse_string_flags(
|
|
133
|
+
xml.data(), xml.size(), flags, NULL);
|
|
134
|
+
leptris_document_free(d);
|
|
135
|
+
}
|
|
136
|
+
double t1 = now_ns();
|
|
137
|
+
printf("attrparse leptris+flags: %7.1f ns/doc (Door A)\n",
|
|
138
|
+
(t1 - t0) / N_PARSE);
|
|
139
|
+
}
|
|
104
140
|
{
|
|
105
141
|
double t0 = now_ns();
|
|
106
142
|
for (int i = 0; i < N_PARSE; i++) {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* bench_append_split — Lane 18 (#1179 tail): where does the
|
|
2
|
+
* create+append ns/child go? Three rows over the same shape:
|
|
3
|
+
* create only, append only (children pre-created), and the
|
|
4
|
+
* create+append pair the gate bench measures. The split decides
|
|
5
|
+
* which half a lever belongs to. */
|
|
6
|
+
#include "leptris.h"
|
|
7
|
+
#include <chrono>
|
|
8
|
+
#include <cstdio>
|
|
9
|
+
|
|
10
|
+
static double now_ns() {
|
|
11
|
+
return (double)std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
12
|
+
std::chrono::steady_clock::now().time_since_epoch())
|
|
13
|
+
.count();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
int main(void) {
|
|
17
|
+
const int N = 200000;
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
LeptrisDocument d = leptris_document_create();
|
|
21
|
+
LeptrisElement root = leptris_element_create(d, "root");
|
|
22
|
+
leptris_document_set_root(d, root);
|
|
23
|
+
double t0 = now_ns();
|
|
24
|
+
for (int i = 0; i < N; i++)
|
|
25
|
+
leptris_element_create(d, "c");
|
|
26
|
+
double t1 = now_ns();
|
|
27
|
+
printf("create only : %6.1f ns/elem\n", (t1 - t0) / N);
|
|
28
|
+
leptris_document_free(d);
|
|
29
|
+
}
|
|
30
|
+
{
|
|
31
|
+
LeptrisDocument d = leptris_document_create();
|
|
32
|
+
LeptrisElement root = leptris_element_create(d, "root");
|
|
33
|
+
leptris_document_set_root(d, root);
|
|
34
|
+
LeptrisElement* kids = new LeptrisElement[N];
|
|
35
|
+
for (int i = 0; i < N; i++)
|
|
36
|
+
kids[i] = leptris_element_create(d, "c");
|
|
37
|
+
double t0 = now_ns();
|
|
38
|
+
for (int i = 0; i < N; i++)
|
|
39
|
+
leptris_element_append_child(root, kids[i]);
|
|
40
|
+
double t1 = now_ns();
|
|
41
|
+
printf("append only : %6.1f ns/elem\n", (t1 - t0) / N);
|
|
42
|
+
delete[] kids;
|
|
43
|
+
leptris_document_free(d);
|
|
44
|
+
}
|
|
45
|
+
{
|
|
46
|
+
LeptrisDocument d = leptris_document_create();
|
|
47
|
+
LeptrisElement root = leptris_element_create(d, "root");
|
|
48
|
+
leptris_document_set_root(d, root);
|
|
49
|
+
double t0 = now_ns();
|
|
50
|
+
for (int i = 0; i < N; i++) {
|
|
51
|
+
LeptrisElement c = leptris_element_create(d, "c");
|
|
52
|
+
leptris_element_append_child(root, c);
|
|
53
|
+
}
|
|
54
|
+
double t1 = now_ns();
|
|
55
|
+
printf("create+app : %6.1f ns/elem\n", (t1 - t0) / N);
|
|
56
|
+
leptris_document_free(d);
|
|
57
|
+
}
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
@@ -273,6 +273,17 @@ LeptrisElement leptris_element_create_child(LeptrisElement parent, const char* n
|
|
|
273
273
|
return elem;
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
/* #1528 hot bail: the child was carved from THIS document's
|
|
277
|
+
* current mut block — the live extent [end - BLOCK_COUNT, cursor)
|
|
278
|
+
* is this doc's own malloc, so nothing foreign can alias into it.
|
|
279
|
+
* Two loads off the doc struct the create call just touched. */
|
|
280
|
+
static int node_in_current_mut_block(struct leptris_document* doc,
|
|
281
|
+
LeptrisElement child) {
|
|
282
|
+
return doc && doc->mut_elem_cursor &&
|
|
283
|
+
child >= doc->mut_elem_end - MUT_ELEM_BLOCK_COUNT &&
|
|
284
|
+
child < doc->mut_elem_cursor;
|
|
285
|
+
}
|
|
286
|
+
|
|
276
287
|
/* #1528: a node arriving from a DIFFERENT document is adopted by
|
|
277
288
|
* deep copy (the set_root precedent, #371). Splicing the raw
|
|
278
289
|
* pointer leaves the tree holding nodes — and text content — from
|
|
@@ -285,7 +296,17 @@ LeptrisElement leptris_element_create_child(LeptrisElement parent, const char* n
|
|
|
285
296
|
static LeptrisNode* adopt_for_splice(LeptrisNode* node,
|
|
286
297
|
struct leptris_document* target) {
|
|
287
298
|
if (!node || !target) return node;
|
|
288
|
-
/*
|
|
299
|
+
/* Hot bail (Lane 18 bar): an UNATTACHED namebp element is
|
|
300
|
+
* authoritatively stamped with its create-time document
|
|
301
|
+
* (#1189) — the freshly-created-then-appended shape. Two loads
|
|
302
|
+
* and a pointer compare, no name-slot resolution (get_document
|
|
303
|
+
* computes elem_name before its fast-out, which cost the
|
|
304
|
+
* append bench +40%). */
|
|
305
|
+
if (node->type == LEPTRIS_NODE_TYPE_ELEMENT &&
|
|
306
|
+
!leptris_elem_parent((LeptrisElement)node) &&
|
|
307
|
+
leptris_elem_has_namebp((LeptrisElement)node) &&
|
|
308
|
+
leptris_elem_namebp_doc((LeptrisElement)node) == target)
|
|
309
|
+
return node; /* Type-safe walk to the chain top: get_document reads
|
|
289
310
|
* element-form fields and misreads non-element structs. */
|
|
290
311
|
LeptrisNode* top = node;
|
|
291
312
|
for (;;) {
|
|
@@ -311,9 +332,17 @@ LeptrisStatus leptris_element_append_child(LeptrisElement parent, LeptrisElement
|
|
|
311
332
|
struct leptris_document* doc = leptris_element_get_document(parent);
|
|
312
333
|
|
|
313
334
|
/* #1528: a foreign document's node is adopted by copy, never
|
|
314
|
-
* spliced raw.
|
|
315
|
-
|
|
316
|
-
|
|
335
|
+
* spliced raw. The freshly-created-then-appended shape proves
|
|
336
|
+
* same-doc in two hot loads: a child inside the CURRENT mut
|
|
337
|
+
* block extent [end - BLOCK_COUNT, cursor) was carved from
|
|
338
|
+
* THIS document's block by the create call just executed — no
|
|
339
|
+
* foreign allocation can live inside it. Everything else takes
|
|
340
|
+
* the full check (Lane 18 append bar). */
|
|
341
|
+
if (!(node_in_current_mut_block(doc, child))) {
|
|
342
|
+
child = (LeptrisElement)adopt_for_splice((LeptrisNode*)child,
|
|
343
|
+
doc);
|
|
344
|
+
if (!child) return LEPTRIS_ERROR_MEMORY;
|
|
345
|
+
}
|
|
317
346
|
|
|
318
347
|
/* Call internal void function, assume success */
|
|
319
348
|
leptris_element_append_child_internal_doc(parent, (LeptrisNode*)child, doc);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
|
|
3
3
|
"name": "leptris",
|
|
4
|
-
"version": "1.9.
|
|
4
|
+
"version": "1.9.306",
|
|
5
5
|
"description": "High-performance XML parser and XPath 1.0 engine in C (libleptris)",
|
|
6
6
|
"homepage": "https://github.com/leptris/leptris",
|
|
7
7
|
"license": "MIT",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.306.0
|
|
5
5
|
platform: ppc64le-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -425,6 +425,7 @@ files:
|
|
|
425
425
|
- vendor-src/libleptris/benchmarks/matrix/bench2html.rb
|
|
426
426
|
- vendor-src/libleptris/benchmarks/matrix/bench_matrix.cpp
|
|
427
427
|
- vendor-src/libleptris/benchmarks/modification/bench_append_attr_pugixml.cpp
|
|
428
|
+
- vendor-src/libleptris/benchmarks/modification/bench_append_split.cpp
|
|
428
429
|
- vendor-src/libleptris/benchmarks/modification/bench_leptris_modify.c
|
|
429
430
|
- vendor-src/libleptris/benchmarks/modification/bench_node_creation.c
|
|
430
431
|
- vendor-src/libleptris/benchmarks/parse/bench_parse_ab.cpp
|