fontist 3.0.17 → 3.0.19

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: aa8aac3407b7b54563dc14319ade845a761256f0ce2d324ed9a7a1da7dfe9613
4
- data.tar.gz: 2ec396abab12f551459a0e7455355243c46e0f4359bf2de4f018ebcde46a30e0
3
+ metadata.gz: 2892a051558c7fca54573398a4d81a65b24365a3a42c2aaedac27f38ed85a70f
4
+ data.tar.gz: d24c202473b5a65e7c282d99802bf5f443d664ca5bceaa61349a912dea2c00bf
5
5
  SHA512:
6
- metadata.gz: dd1a4460fc10c117bb6d7fc3dcbced001f83c918c64e70621778575e7edce78544a94fbbbbe5e64f22294e5c0525af723043055feae62f3a21fe299020cdda71
7
- data.tar.gz: 33e5d409a00bd73c39e839a9a9acad2f31aa2dde95697f1ad08ebfc4f0d2aa980cfb8cac95524b8fdc310c1e880546dbf09bb15ebd3060d44a71948821f35db9
6
+ metadata.gz: e8833cb9fc107eaf9b3a3f8d470735d7c269c35a12ecaf69cba222553ec2bd2db20b19e8ee3d9482b0f92127dfbf11ff24808a81e942e471ad52b4e79dc4e032
7
+ data.tar.gz: d72ce09d1cb402e2c35b16116fec1a562e67fb020fd217ce1289ca9784305d15da7fb55fd0e58b90f290b1217fed442b5e7f7aaa060256067d952248eea2c714
data/.rubocop.yml CHANGED
@@ -3,7 +3,7 @@ inherit_from:
3
3
  - https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
4
4
 
5
5
  AllCops:
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.0
7
7
  SuggestExtensions: false
8
8
 
9
9
  plugins:
data/Gemfile CHANGED
@@ -18,6 +18,12 @@ gem "simplecov"
18
18
  gem "vcr"
19
19
  gem "webmock"
20
20
 
21
+ # Optional YAML engine (consumer-side dependency; needs Ruby >= 3.0,
22
+ # which is above fontist's gemspec floor, so it stays out of the
23
+ # gemspec). Activated with FONTIST_YAML=yeptris; off by default
24
+ # pending leptris/yeptris#863 (linux scalar-parity fix).
25
+ gem "yeptris", require: false
26
+
21
27
  # Profiling tools (development only)
22
28
  # gem "ruby-prof", "~> 1.7"
23
29
  # stackprof uses Unix-specific system calls and doesn't compile on Windows
data/fontist.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.post_install_message = "Please run `fontist update` to fetch formulas."
17
17
 
18
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
18
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
19
19
 
20
20
  spec.metadata["homepage_uri"] = spec.homepage
21
21
  spec.metadata["source_code_uri"] = "https://github.com/fontist/fontist"
@@ -559,19 +559,48 @@ stats:)
559
559
  verbose: verbose, stats: stats,
560
560
  num_workers: num_cores)
561
561
  else
562
- # Measured on 600 system fonts: single thread 2.3s, 8 threads
563
- # 3.3s (GVL-bound, mutex contention), 8 processes 0.6s. The
564
- # silent build path therefore forks instead of threading
565
- results = Parallel.map(sorted_paths, in_processes: num_cores) do |path|
566
- detect_font_with_cache(path, existing_fonts_by_path[path],
567
- stats: nil)
562
+ # Threads, not forked processes: a silent scan runs from inside
563
+ # long-lived host processes (e.g. metanorma, whose heap reaches
564
+ # hundreds of MB by the time fonts are looked up). Each fork
565
+ # inherits that heap, and its RSS is charged to the process group
566
+ # while it lives, so an 8-process scan transiently multiplies the
567
+ # host's footprint by up to 9x — measured 3.6GB against a 0.9GB
568
+ # parent during a metanorma compile (OOMs under cgroup caps).
569
+ # The ~1s-per-600-fonts scan penalty is bounded and paid only on
570
+ # cache-miss rebuilds. split_paths_by_reuse keeps cached entries
571
+ # in the parent: see its comment for the marshal constraint.
572
+ to_scan, cached_results = split_paths_by_reuse(
573
+ sorted_paths,
574
+ existing_fonts_by_path)
575
+
576
+ results = Parallel.map(to_scan, in_threads: num_cores) do |path|
577
+ detect_fonts(path, stats: nil)
568
578
  end.flatten.compact
569
579
 
570
- stats&.total_fonts = results.size
571
- results
580
+ stats&.total_fonts = cached_results.size + results.size
581
+ cached_results + results
572
582
  end
573
583
  end
574
584
 
585
+ # The stat-only reuse check runs in the parent: cached entries can
586
+ # carry backrefs to their SystemIndexFontCollection (whose
587
+ # paths_loader is a Proc), and worker results are Marshal.dump'ed
588
+ # back across the fork boundary — crossing it with cached
589
+ # collections raises "no _dump_data is defined for class Proc".
590
+ # Workers therefore receive only to-scan paths, and the block
591
+ # handed to Parallel closes over nothing but its argument.
592
+ def split_paths_by_reuse(sorted_paths, existing_fonts_by_path)
593
+ unchanged, to_scan = sorted_paths.partition do |path|
594
+ cached = existing_fonts_by_path[path]
595
+ cached&.any? && file_unchanged?(path, cached.first)
596
+ end
597
+ cached_results = unchanged.flat_map do |path|
598
+ existing_fonts_by_path[path].to_a
599
+ end
600
+
601
+ [to_scan, cached_results]
602
+ end
603
+
575
604
  def process_paths_in_threads(sorted_paths, existing_fonts_by_path,
576
605
  verbose:, stats:, num_workers:)
577
606
  progress = ScanProgress.new(sorted_paths.size, verbose: verbose) do |count, path|
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "3.0.17".freeze
2
+ VERSION = "3.0.19".freeze
3
3
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontist
4
+ module Yaml
5
+ # Model YAML parsing through yeptris's native loader. Measured 4x
6
+ # faster than Psych on formula and index documents (442KB index:
7
+ # 47ms vs 202ms), with parse results verified identical across the
8
+ # full formulas corpus. Dumping stays on the standard adapter.
9
+ class YeptrisAdapter < Lutaml::Yaml::Adapter::StandardAdapter
10
+ def self.parse(yaml, _options = {})
11
+ Yeptris::YAML.load(yaml)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module Fontist
2
+ module Yaml
3
+ autoload :YeptrisAdapter, "#{__dir__}/yaml/yeptris_adapter"
4
+ end
5
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fontist
4
+ # Model YAML engine selection.
5
+ #
6
+ # The yeptris engine (native loader, measured 4x faster than Psych on
7
+ # large documents) activates only when explicitly enabled with
8
+ # FONTIST_YAML=yeptris. It is off by default because the yeptris
9
+ # x86_64-linux and Windows builds currently mis-parse some plain
10
+ # scalars as single-element Arrays (leptris/yeptris#863); flip the
11
+ # default once that parity fix lands.
12
+ module YamlBackend
13
+ ENV_KEY = "FONTIST_YAML"
14
+ ENABLED_VALUE = "yeptris"
15
+
16
+ class << self
17
+ # Returns the activated adapter class, or nil when the standard
18
+ # engine stays in place (flag unset, or yeptris unavailable)
19
+ def activate!
20
+ return nil unless enabled?
21
+ return nil unless yeptris_available?
22
+
23
+ adapter = Yaml::YeptrisAdapter
24
+ Lutaml::Model::AdapterResolver.set_adapter_class(:yaml, adapter)
25
+
26
+ adapter
27
+ end
28
+
29
+ def enabled?
30
+ ENV[ENV_KEY] == ENABLED_VALUE
31
+ end
32
+
33
+ def yeptris_available?
34
+ require "yeptris"
35
+ true
36
+ rescue LoadError
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/fontist.rb CHANGED
@@ -11,6 +11,8 @@ require_relative "fontist/from_file_cache"
11
11
  require_relative "fontist/memoizable"
12
12
  require_relative "fontist/path_scanning"
13
13
  require_relative "fontist/utils"
14
+ require_relative "fontist/yaml"
15
+ require_relative "fontist/yaml_backend"
14
16
 
15
17
  module Fontist
16
18
  # Core classes
@@ -282,3 +284,5 @@ module Fontist
282
284
  true
283
285
  end
284
286
  end
287
+
288
+ Fontist::YamlBackend.activate!
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontist
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.17
4
+ version: 3.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -512,6 +512,9 @@ files:
512
512
  - lib/fontist/version.rb
513
513
  - lib/fontist/windows_fod_metadata.rb
514
514
  - lib/fontist/windows_import_source.rb
515
+ - lib/fontist/yaml.rb
516
+ - lib/fontist/yaml/yeptris_adapter.rb
517
+ - lib/fontist/yaml_backend.rb
515
518
  - lib/tasks/system_fonts.rake
516
519
  - script/capture_system_fonts
517
520
  - script/download_system_indexes
@@ -533,7 +536,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
533
536
  requirements:
534
537
  - - ">="
535
538
  - !ruby/object:Gem::Version
536
- version: 2.7.0
539
+ version: 3.0.0
537
540
  required_rubygems_version: !ruby/object:Gem::Requirement
538
541
  requirements:
539
542
  - - ">="