canon 0.3.78 → 0.3.80

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 031d0a1ecb48c26cb773e79d791d7ae090fa1231eb3132fbdf3d9138b0afcab6
4
- data.tar.gz: 63dd55aa45a123cc1c39e6072033363def2bd0f6b6fc8de9ab88edd8a7f16ae4
3
+ metadata.gz: 03660ad8d01c97bba27092e57acb568055fde2f6605c305a18fe21dc7b4cdf44
4
+ data.tar.gz: '03969484d25b60e1edb7ea412ade79bb0926f0b5df7ecb7a2125d145874c9bfb'
5
5
  SHA512:
6
- metadata.gz: a77a02d18d89482275d8e288951b7bda5f4bb144fea76e08e21ce484df42ee4928d666cb45b7cba0f63d025b3bbda59f4e2550ed81e6190f7154cbe4c2c79931
7
- data.tar.gz: 4bb93c91e98b9f04ff0513a17559a4eed805c5f7d8a3385dfd3f11e5af929c31d327eab1228c616b5712ace68cdcd8fdabcd49dbb25e5af14b3fb2160c40cc0f
6
+ metadata.gz: a25bbfeb7036590d0dc8564687f658ebe19d16aeff23df92233762417f0942eeb8a378a51d34fc577cb1e09d4abd80d74896519fcafb9edb01c678bec4c58e82
7
+ data.tar.gz: 258dc823ca4fdac8975571ccf176c83ebd8ee59b201573af7f874311810aaad06b7fee980996634a0b62553443e2d99125fe940d1df1656bf3b974994494b0c2
@@ -179,13 +179,19 @@ module Canon
179
179
  # @return [Array<TreeNode>]
180
180
  def descendants
181
181
  # Iterative pre-order walk — the recursive form allocated an
182
- # intermediate array per level.
182
+ # intermediate array per level; the explicit stack allocates
183
+ # nothing per visited node.
183
184
  result = []
184
185
  stack = children.reverse_each.to_a
185
186
  until stack.empty?
186
187
  node = stack.pop
187
188
  result << node
188
- stack.concat(node.children.reverse_each.to_a) if node.children.any?
189
+ kids = node.children
190
+ i = kids.length - 1
191
+ while i >= 0
192
+ stack << kids[i]
193
+ i -= 1
194
+ end
189
195
  end
190
196
  result
191
197
  end
@@ -137,8 +137,17 @@ module Canon
137
137
  return false unless node1.label == node2.label
138
138
  return false unless text_equivalent?(node1, node2)
139
139
 
140
- # Check attribute KEYS match, not values — value diffs are reported as UPDATE
141
- return false unless node1.attributes.keys == node2.attributes.keys
140
+ # Attribute KEYS match, not values — value diffs are reported
141
+ # as UPDATE. Canon AttributeNode lists compare by value, so
142
+ # identical raw lists prove equal keys without the per-pair
143
+ # keys-array allocations.
144
+ attrs1 = node1.attributes
145
+ attrs2 = node2.attributes
146
+ if attrs1.is_a?(Array) && attrs1.first.is_a?(Canon::Xml::Nodes::AttributeNode)
147
+ return false unless attrs1 == attrs2
148
+ elsif node1.attributes.keys != node2.attributes.keys
149
+ return false
150
+ end
142
151
 
143
152
  true
144
153
  end
data/lib/canon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Canon
4
- VERSION = "0.3.78"
4
+ VERSION = "0.3.80"
5
5
  end
@@ -325,16 +325,24 @@ strip_doctype: false)
325
325
  result
326
326
  end
327
327
 
328
- # Parse a QName into prefix and local name
328
+ # Parse a QName into prefix and local name. Memoized per
329
+ # builder — document qnames repeat massively (tens of calls per
330
+ # distinct name), and each uncached call allocates the result
331
+ # array plus split parts. Callers only destructure, so sharing
332
+ # the frozen pair is safe.
329
333
  #
330
334
  # @param qname [String] QName like "prefix:local" or "local"
331
335
  # @return [Array<(String, String)>] [prefix, local_name] - prefix may be nil
332
336
  def parse_qname(qname)
333
- if qname.include?(":")
334
- parts = qname.split(":", 2)
335
- [parts[0], parts[1]]
336
- else
337
- [nil, qname]
337
+ cache = (@qname_cache ||= {})
338
+ cache.fetch(qname) do
339
+ pair = if qname.include?(":")
340
+ parts = qname.split(":", 2)
341
+ [parts[0], parts[1]]
342
+ else
343
+ [nil, qname]
344
+ end
345
+ cache[qname] = pair.freeze
338
346
  end
339
347
  end
340
348
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.78
4
+ version: 0.3.80
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-07 00:00:00.000000000 Z
11
+ date: 2026-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs