leptris 1.9.19-aarch64-linux → 1.9.21-aarch64-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 +34 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/pull.rb +23 -10
- data/lib/leptris/xml/searchable.rb +9 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a10b8e5a3f59b43792a986200af06e1d8f5ed09006b94272adf423546b9b5d3
|
|
4
|
+
data.tar.gz: 0f23a65d72a713b0221e6d67b68ef11b0f1244472ab17470924d41afe1018c0e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b926e9e47f7b86dec2a7ca0768052a31b430849a020ceb10b4cd970b51299b750da3928bae592e254994170c0891a003c1be3e6a73179ea0b38f9fa8b079d26a
|
|
7
|
+
data.tar.gz: 8201fa8740f34c221fc72f26e1572ad4199af57042aecdb6ad7b0f3b120172a1b0fa2c6e6963b400b966547433a50e47417c9043e5444acbc059d669be74c617
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ All notable changes to Leptris will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.9.21] - 2026-08-27
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **`#at` / `#%` take the single-node seam**: the generic entry now
|
|
13
|
+
dispatches on syntax (like `#search`) and calls `at_xpath` /
|
|
14
|
+
`at_css` directly instead of routing through
|
|
15
|
+
`search().first` and its NodeSet container — the round-XIV fast
|
|
16
|
+
path's last un-routed caller. Measured: `at("item > name")` 0.026 s
|
|
17
|
+
-> 0.020 s per 2000 iterations (**-23%**, now at parity with
|
|
18
|
+
`at_css`); scalar semantics for XPath-shaped expressions keep the
|
|
19
|
+
full-wrapper behavior.
|
|
20
|
+
|
|
21
|
+
## [1.9.20] - 2026-08-27
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **Pull event loop allocation trim**: `Parser#next_event` reads the
|
|
26
|
+
event's type/name/text through layout-derived offsets
|
|
27
|
+
(`PullEventStruct.offset_of` — the struct stays the ABI's single
|
|
28
|
+
source of truth) instead of allocating a struct wrapper per event;
|
|
29
|
+
`capture_attrs` builds its hash without the enumerator machinery
|
|
30
|
+
and answers nil for zero attributes. Streaming a 300-element
|
|
31
|
+
document: 2.9 ms -> 2.3 ms per parse (**-20%**). The remaining
|
|
32
|
+
per-event cost is FFI dispatch — the batch ask is filed upstream
|
|
33
|
+
(leptris/leptris#589).
|
|
34
|
+
|
|
35
|
+
### Meta
|
|
36
|
+
|
|
37
|
+
- Streaming-path benchmarks added to the round's report: pull with
|
|
38
|
+
events measured 145x slower than DOM-parsing the same bytes
|
|
39
|
+
(dispatch-dominated); iterparse's 60% system-time signature
|
|
40
|
+
documented on leptris/leptris#563 (C-side release churn).
|
|
41
|
+
|
|
8
42
|
## [1.9.19] - 2026-08-27
|
|
9
43
|
|
|
10
44
|
Lockstep with libleptris 1.9.3 — unblocks the 1.9.18 release
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/pull.rb
CHANGED
|
@@ -60,6 +60,14 @@ module Leptris::XML::Pull
|
|
|
60
60
|
self
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
# Hot-loop offsets: derived from PullEventStruct's layout (the
|
|
64
|
+
# struct stays the single source of truth for the ABI), read via
|
|
65
|
+
# get_int/get_pointer so the per-event struct-wrapper allocation
|
|
66
|
+
# disappears from streaming loops.
|
|
67
|
+
NAME_OFFSET = Leptris::XML::FFI::PullEventStruct.offset_of(:name)
|
|
68
|
+
TEXT_OFFSET = Leptris::XML::FFI::PullEventStruct.offset_of(:text)
|
|
69
|
+
private_constant :NAME_OFFSET, :TEXT_OFFSET
|
|
70
|
+
|
|
63
71
|
# Advances the cursor and returns the next Event, or nil after the
|
|
64
72
|
# end of the document. Attribute values are captured during
|
|
65
73
|
# start_element because the C accessors are valid only for the
|
|
@@ -67,26 +75,31 @@ module Leptris::XML::Pull
|
|
|
67
75
|
def next_event
|
|
68
76
|
raw = Leptris::XML::FFI.leptris_pull_next(@handle)
|
|
69
77
|
return nil if raw.null?
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
text = read_owned(event[:text])
|
|
78
|
+
type = TYPES[raw.get_int(0)]
|
|
79
|
+
name_ptr = raw.get_pointer(NAME_OFFSET)
|
|
80
|
+
text_ptr = raw.get_pointer(TEXT_OFFSET)
|
|
74
81
|
attrs = type == :start_element ? capture_attrs : nil
|
|
75
|
-
Event.new(
|
|
82
|
+
Event.new(
|
|
83
|
+
type: type,
|
|
84
|
+
name: name_ptr.null? ? nil : name_ptr.read_string.force_encoding(Encoding::UTF_8),
|
|
85
|
+
text: text_ptr.null? ? nil : text_ptr.read_string.force_encoding(Encoding::UTF_8),
|
|
86
|
+
attrs: attrs
|
|
87
|
+
)
|
|
76
88
|
end
|
|
77
89
|
|
|
78
90
|
private
|
|
79
91
|
|
|
80
|
-
def read_owned(ptr)
|
|
81
|
-
ptr.null? ? nil : ptr.read_string.force_encoding(Encoding::UTF_8)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
92
|
def capture_attrs
|
|
85
93
|
count = Leptris::XML::FFI.leptris_pull_attr_count(@handle)
|
|
86
|
-
|
|
94
|
+
return nil if count.zero?
|
|
95
|
+
hash = {}
|
|
96
|
+
i = 0
|
|
97
|
+
while i < count
|
|
87
98
|
hash[Leptris::XML::FFI.leptris_pull_attr_name(@handle, i)] =
|
|
88
99
|
Leptris::XML::FFI.leptris_pull_attr_value(@handle, i)
|
|
100
|
+
i += 1
|
|
89
101
|
end
|
|
102
|
+
hash
|
|
90
103
|
end
|
|
91
104
|
end
|
|
92
105
|
|
|
@@ -50,9 +50,16 @@ module Leptris::XML::Searchable
|
|
|
50
50
|
end
|
|
51
51
|
alias_method :/, :search
|
|
52
52
|
|
|
53
|
+
# Single-node seam (round XIV): dispatch on syntax like #search,
|
|
54
|
+
# then call the at_* fast paths directly — no NodeSet container,
|
|
55
|
+
# no result handle, one fewer dispatch than search().first.
|
|
53
56
|
def at(*args)
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
paths = args.first.is_a?(Array) ? args.first : [args.first]
|
|
58
|
+
if paths.map(&:to_s).all? { |p| looks_like_xpath?(p) }
|
|
59
|
+
at_xpath(*paths)
|
|
60
|
+
else
|
|
61
|
+
at_css(*args)
|
|
62
|
+
end
|
|
56
63
|
end
|
|
57
64
|
alias_method :%, :at
|
|
58
65
|
|