leptris 1.9.16 → 1.9.17
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 +16 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/ffi.rb +19 -6
- data/lib/leptris/xml/node.rb +5 -2
- data/lib/leptris/xml/node_set.rb +3 -3
- 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: 790fde1b932902a17438b2abed525393ebb61464a61ff35081384409277a42cc
|
|
4
|
+
data.tar.gz: 356b2a9a9426c03a25c42577952f3634127162e449e3540816b99a8bf6cd354f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8fdfd7ed098ae1501040d5f82808c57813f5f2f8dec606d6ac966bd916cff635dd510ebf68e235a4a3e9c0da6a5a10cc9765ffe20eb06a476876dc2cf6dbc2fc
|
|
7
|
+
data.tar.gz: 26142e64a808758e72332fa8aaef029b7fee19c82c3f634f6f0ec9ba7afe7990261f958173a124f2f89ced5270c253f53256f4b12eafc99235a066e38c5b7f3a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ 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.17] - 2026-08-27
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Element-hinted batch materialization**: the XPath result-set
|
|
13
|
+
batch (`leptris_xpath_result_get_nodes_ex`) fills an out_kinds
|
|
14
|
+
array the binding discarded; `Node.wrap` now accepts a known
|
|
15
|
+
`node_type:` so element entries skip the per-node get_type
|
|
16
|
+
dispatch. ELEMENT is the only hintable value — XPath's data
|
|
17
|
+
model reports CDATA as TEXT, so a TEXT hint cannot distinguish
|
|
18
|
+
Text from CDATA (different content getters); comments/CDATA/PIs
|
|
19
|
+
keep the get_type fallback. Cold 500-element materialization:
|
|
20
|
+
0.131 s -> 0.110 s (~15%). Upstream note: a full-type out_kinds
|
|
21
|
+
(or kinds on `leptris_node_children`) belongs to the #560/#562
|
|
22
|
+
ask family.
|
|
23
|
+
|
|
8
24
|
## [1.9.16] - 2026-08-27
|
|
9
25
|
|
|
10
26
|
### Changed
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/ffi.rb
CHANGED
|
@@ -747,14 +747,27 @@ module Leptris
|
|
|
747
747
|
end
|
|
748
748
|
|
|
749
749
|
# XPath result-set batch (leptris_xpath_result_get_nodes_ex):
|
|
750
|
-
#
|
|
751
|
-
# the
|
|
750
|
+
# the call fills out_kinds in the 4-value XPATH_NODE space
|
|
751
|
+
# (ELEMENT/ATTRIBUTE/TEXT/OTHER). ELEMENT is the only value
|
|
752
|
+
# that maps unambiguously — XPath's data model reports CDATA
|
|
753
|
+
# as TEXT, so a TEXT hint cannot distinguish Text from CDATA
|
|
754
|
+
# (different content getters) — everything else falls back to
|
|
755
|
+
# get_type in the wrapper. Returns [pointers, element_hints].
|
|
756
|
+
XPATH_KIND_HINT = { XPATH_NODE_ELEMENT => NODE_ELEMENT }.freeze
|
|
757
|
+
|
|
752
758
|
def self.fetch_result_nodes(result_ptr, count)
|
|
753
|
-
return [] if count.zero?
|
|
759
|
+
return [[], nil] if count.zero?
|
|
754
760
|
with_pointer_buffer(count) do |buffer|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
761
|
+
kinds = ::FFI::MemoryPointer.new(:int, count)
|
|
762
|
+
begin
|
|
763
|
+
copied = leptris_xpath_result_get_nodes_ex(
|
|
764
|
+
result_ptr, buffer, kinds, count)
|
|
765
|
+
hints = kinds.get_array_of_int(0, copied)
|
|
766
|
+
.map { |k| XPATH_KIND_HINT[k] }
|
|
767
|
+
[buffer.get_array_of_pointer(0, copied), hints]
|
|
768
|
+
ensure
|
|
769
|
+
kinds.free
|
|
770
|
+
end
|
|
758
771
|
end
|
|
759
772
|
end
|
|
760
773
|
|
data/lib/leptris/xml/node.rb
CHANGED
|
@@ -12,7 +12,10 @@ class Leptris::XML::Node
|
|
|
12
12
|
@node_type = node_type
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
# node_type: callers holding a batch-fetched kind (the XPath
|
|
16
|
+
# result-set batch fills out_kinds) pass it so the wrap skips the
|
|
17
|
+
# get_type dispatch; nil (the default) dispatches as before.
|
|
18
|
+
def self.wrap(c_ptr, document, parent: nil, node_type: nil)
|
|
16
19
|
# Per-document weak-ref cache. Returns the existing wrapper when the
|
|
17
20
|
# same c_ptr is wrapped twice (common in children/sibling walks,
|
|
18
21
|
# repeated xpath queries, traverse-then-access patterns). The cache
|
|
@@ -21,7 +24,7 @@ class Leptris::XML::Node
|
|
|
21
24
|
return cached
|
|
22
25
|
end
|
|
23
26
|
|
|
24
|
-
node_type
|
|
27
|
+
node_type ||= Leptris::XML::FFI.leptris_node_get_type(c_ptr)
|
|
25
28
|
node =
|
|
26
29
|
case node_type
|
|
27
30
|
when Leptris::XML::FFI::NODE_ELEMENT
|
data/lib/leptris/xml/node_set.rb
CHANGED
|
@@ -81,11 +81,11 @@ class Leptris::XML::NodeSet
|
|
|
81
81
|
# not just elements); the batch accessor under-copies
|
|
82
82
|
# mixed-kind results (upstream leptris#477), so per-index
|
|
83
83
|
# fetch covers the remainder.
|
|
84
|
-
pointers = Leptris::XML::FFI.fetch_result_nodes(@result_ptr, n)
|
|
84
|
+
pointers, kinds = Leptris::XML::FFI.fetch_result_nodes(@result_ptr, n)
|
|
85
85
|
nodes = []
|
|
86
|
-
pointers.
|
|
86
|
+
pointers.each_with_index do |ptr, i|
|
|
87
87
|
next if ptr.null?
|
|
88
|
-
nodes << Leptris::XML::Node.wrap(ptr, @document)
|
|
88
|
+
nodes << Leptris::XML::Node.wrap(ptr, @document, node_type: kinds[i])
|
|
89
89
|
end
|
|
90
90
|
(pointers.length...n).each do |i|
|
|
91
91
|
ptr = Leptris::XML::FFI.leptris_xpath_result_get_node(@result_ptr, i)
|