Class: Ucode::Glyphs::UniversalSet::ManifestAccumulator
- Inherits:
-
Object
- Object
- Ucode::Glyphs::UniversalSet::ManifestAccumulator
- Defined in:
- lib/ucode/glyphs/universal_set/manifest_accumulator.rb
Overview
Thread-safe accumulator that observes the Builder's per-
codepoint attempts and produces the final
Models::UniversalSetManifest plus the per-block
breakdown the ManifestWriter emits as reports/by_block.json.
Mirrors the Repo::BuildReportAccumulator pattern from Mode 1: the orchestrating command passes this instance to the builder, which calls #record_build (or #record_skip) from inside its worker pool. After the drain completes, #to_manifest returns the immutable snapshot.
Semantics
codepoints_assignedcounts every codepoint the builder attempted (passed the block_filter guard).codepoints_builtcounts codepoints whose resolver returned a glyph.codepoints_skippedcounts codepoints that resolved to nil (no tier produced a glyph) — these are the "gaps" the gaps report enumerates.codepoints_failedcounts exceptions recorded via #record_failure.
by_tier counts the winning tier per codepoint (one increment
per built codepoint). The map uses the wire form ("tier-1",
"pillar-1", ...) so the manifest is stable across Ruby symbol
changes.
by_block is a hash keyed by block_id, with built / skipped /
failed counters per block. Computed from the codepoint stream
the Builder drains — the accumulator reads CodePoint#block_id
directly. Block ids follow the canonical underscore form.
Instance Method Summary collapse
-
#by_block ⇒ Hash{String=>Hash}
Per-block built/skipped/failed counts, deep-copied so callers can't mutate accumulator state.
-
#failures ⇒ Array<Hash>
Recorded failures (each with codepoint, block_id, error_class, message).
-
#gaps ⇒ Array<Integer>
Codepoints that resolved to nil, sorted.
-
#initialize(unicode_version:, ucode_version:, source_config_sha256:) ⇒ ManifestAccumulator
constructor
A new instance of ManifestAccumulator.
-
#record_build(codepoint, result, svg:) ⇒ void
Observer entry — the builder calls this for every codepoint the resolver produced a glyph for.
-
#record_failure(codepoint, error) ⇒ void
Record an exception.
-
#record_skip(codepoint) ⇒ void
Observer entry — the builder calls this when the resolver returned nil for a codepoint.
-
#to_manifest ⇒ Ucode::Models::UniversalSetManifest
Immutable snapshot.
Constructor Details
#initialize(unicode_version:, ucode_version:, source_config_sha256:) ⇒ ManifestAccumulator
Returns a new instance of ManifestAccumulator.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 56 def initialize(unicode_version:, ucode_version:, source_config_sha256:) @unicode_version = unicode_version @ucode_version = ucode_version @source_config_sha256 = source_config_sha256 @totals = { codepoints_assigned: 0, codepoints_built: 0, codepoints_skipped: 0, codepoints_failed: 0 } @by_tier = Hash.new(0) @by_block = Hash.new do |h, block_id| h[block_id] = { built: 0, skipped: 0, failed: 0 } end @entries = [] @gaps = [] @failures = [] @mutex = Mutex.new end |
Instance Method Details
#by_block ⇒ Hash{String=>Hash}
Returns per-block built/skipped/failed counts, deep-copied so callers can't mutate accumulator state.
143 144 145 146 147 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 143 def by_block synchronize do @by_block.transform_values(&:dup) end end |
#failures ⇒ Array<Hash>
Returns recorded failures (each with codepoint, block_id, error_class, message).
156 157 158 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 156 def failures synchronize { @failures.dup } end |
#gaps ⇒ Array<Integer>
Returns codepoints that resolved to nil, sorted.
150 151 152 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 150 def gaps synchronize { @gaps.sort } end |
#record_build(codepoint, result, svg:) ⇒ void
This method returns an undefined value.
Observer entry — the builder calls this for every codepoint the resolver produced a glyph for. Records the entry and bumps the built counter + per-tier + per-block rollups.
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 80 def record_build(codepoint, result, svg:) entry = build_entry(codepoint.cp, result, svg) tier_wire = wire_tier(result.tier) synchronize do @totals[:codepoints_assigned] += 1 @totals[:codepoints_built] += 1 @by_tier[tier_wire] += 1 @by_block[codepoint.block_id][:built] += 1 @entries << entry end end |
#record_failure(codepoint, error) ⇒ void
This method returns an undefined value.
Record an exception. The builder rescues per-codepoint errors and routes them here so one bad codepoint doesn't abort the run.
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 114 def record_failure(codepoint, error) synchronize do @totals[:codepoints_assigned] += 1 unless codepoint.nil? @totals[:codepoints_failed] += 1 @by_block[codepoint&.block_id][:failed] += 1 unless codepoint.nil? @failures << { codepoint: codepoint&.cp, block_id: codepoint&.block_id, error_class: error.class.name, message: error. } end end |
#record_skip(codepoint) ⇒ void
This method returns an undefined value.
Observer entry — the builder calls this when the resolver returned nil for a codepoint. Counts the attempt and adds it to the gaps list for the gaps report.
98 99 100 101 102 103 104 105 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 98 def record_skip(codepoint) synchronize do @totals[:codepoints_assigned] += 1 @totals[:codepoints_skipped] += 1 @by_block[codepoint.block_id][:skipped] += 1 @gaps << codepoint.cp end end |
#to_manifest ⇒ Ucode::Models::UniversalSetManifest
Returns immutable snapshot.
127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ucode/glyphs/universal_set/manifest_accumulator.rb', line 127 def to_manifest synchronize do Ucode::Models::UniversalSetManifest.new( unicode_version: @unicode_version, ucode_version: @ucode_version, generated_at: Time.now.utc.iso8601, source_config_sha256: @source_config_sha256, totals: Ucode::Models::UniversalSetManifest::Totals.new(@totals), by_tier: @by_tier.dup, entries: @entries.dup, ) end end |