fontist 3.0.14 → 3.0.15

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: 06a9b4c9a5923cb458a0a5312fd4877c4615e6663dbd12dc292bed425c084ac4
4
- data.tar.gz: 5032ff75c1ac724280b7529b1c24b7975c092624d6aadd74358255242cb950c9
3
+ metadata.gz: e34cf04876b1c50b7ada12a6d8c23a1954baaecc499433d25844f2c0df899c97
4
+ data.tar.gz: 3728d8848dd1eb1d92ef0f7b28d251e1f9ef3a9d5d3ec7592f39607f05d9b3d0
5
5
  SHA512:
6
- metadata.gz: '093f4d9ea5fcaefd488ebe05b2fa90f9179fe997cf78d54ecf06b36f8cf4d05487dcd557ef6162a61844919b2f80b6bbf7ecf190afcfc7b68426b81cb0989742'
7
- data.tar.gz: aa94716daea9eec2786bde7875eb036ed43afe20abc8e78c8aecd03ef65189cc8c79c2a1fb5b1f4e0e30ec628a7ea0f5c66448d5a09aa3018636be8b89f581c0
6
+ metadata.gz: 415419b02587672d1e4676365a2658f0d126f1860a2b67f22aef5509dcb14268deab6db07847b655151612247b94d029bfb9cea65352b8d80a41b017f6c97b76
7
+ data.tar.gz: 6cab85a340fb53f66d2ba771de09aa6d13a882a98aeb60ffd806da24207a669b61e8d9e57f59821107f6231f5b1070f18a107fde561289d787a32fb2afd3ca09
@@ -181,9 +181,15 @@ module Fontist
181
181
 
182
182
  content = File.read(path)
183
183
 
184
- from_yaml(content).tap do |formula|
185
- formula.path = path
186
- formula.name = titleize(formula.key_from_path) if formula.name.nil?
184
+ # Parsing a formula costs ~10-20ms and the same formula is
185
+ # re-read on every lookup, so the parsed instance is memoized
186
+ # (mtime-validated) and shared between callers; treat as
187
+ # read-only
188
+ formula = Fontist::FromFileCache.memoize(path) { from_yaml(content) }
189
+
190
+ formula.tap do |f|
191
+ f.path = path
192
+ f.name = titleize(f.key_from_path) if f.name.nil?
187
193
  end
188
194
  rescue Lutaml::Model::Error, TypeError, ArgumentError,
189
195
  Psych::BadAlias, Psych::SyntaxError => e
@@ -0,0 +1,34 @@
1
+ module Fontist
2
+ # Thread-safe, mtime-validated memoization for parsed YAML artifacts
3
+ # (formula index, formula files), which cost hundreds of milliseconds to
4
+ # parse and are re-read on every font lookup.
5
+ #
6
+ # Returned instances are shared between all callers and must be treated
7
+ # as read-only. Entries re-resolve automatically when the file's mtime
8
+ # changes (e.g. after `fontist update` rewrites the formulas repo).
9
+ module FromFileCache
10
+ def self.memoize(path)
11
+ mutex.synchronize do
12
+ mtime = File.mtime(path)
13
+ entry = cache[path]
14
+ if entry.nil? || entry[:mtime] != mtime
15
+ entry = { mtime: mtime, value: yield }
16
+ cache[path] = entry
17
+ end
18
+ entry[:value]
19
+ end
20
+ end
21
+
22
+ def self.clear
23
+ mutex.synchronize { cache.clear }
24
+ end
25
+
26
+ def self.mutex
27
+ @mutex ||= Mutex.new
28
+ end
29
+
30
+ def self.cache
31
+ @cache ||= {}
32
+ end
33
+ end
34
+ end
@@ -132,6 +132,10 @@ module Fontist
132
132
  # @param verbose [Boolean] Show detailed progress information
133
133
  # @return [void]
134
134
  def rebuild(verbose: false)
135
+ # A rebuild is an explicit request for a fresh scan, so any
136
+ # memoized font_paths must be dropped first
137
+ reset_scan_cache
138
+
135
139
  collection.rebuild(verbose: verbose)
136
140
  end
137
141
 
@@ -37,10 +37,17 @@ module Fontist
37
37
  # Uses case-insensitive glob patterns that work on all platforms,
38
38
  # including Linux where File::FNM_CASEFOLD is ignored
39
39
  #
40
+ # Delegates to the memoized fontist-repo scan on SystemFont; the
41
+ # memo is invalidated through reset_scan_cache when fonts are
42
+ # installed or removed mid-process
43
+ #
40
44
  # @return [Array<String>] Array of font file paths
41
45
  def font_paths
42
- patterns = Fontist::Utils.font_file_patterns(Fontist.fonts_path.join("**").to_s)
43
- patterns.flat_map { |pattern| Dir.glob(pattern) }
46
+ SystemFont.fontist_font_paths
47
+ end
48
+
49
+ def reset_scan_cache
50
+ SystemFont.reset_fontist_font_paths_cache
44
51
  end
45
52
  end
46
53
  end
@@ -49,12 +49,13 @@ module Fontist
49
49
 
50
50
  file_content = File.read(file_path).strip
51
51
 
52
- if file_content.empty? || file_content == "---"
53
- # Return empty collection for empty index files
54
- return new
55
- end
52
+ # Return empty collection for empty index files
53
+ return new if file_content.empty? || file_content == "---"
56
54
 
57
- from_yaml(file_content)
55
+ # Parsing the index YAML costs hundreds of milliseconds and
56
+ # happens on every font lookup, so the parsed instance is
57
+ # memoized (mtime-validated) and shared between callers
58
+ Fontist::FromFileCache.memoize(file_path) { from_yaml(file_content) }
58
59
  end
59
60
 
60
61
  def rebuild
@@ -67,6 +68,10 @@ module Fontist
67
68
  end
68
69
 
69
70
  def reset_cache
71
+ # Drop the memoized parsed instance along with the index file,
72
+ # to force a fresh parse on next access
73
+ Fontist::FromFileCache.clear
74
+
70
75
  # Delete the index file to force rebuild on next access
71
76
  # This is important for tests to ensure clean state
72
77
  FileUtils.rm_f(path)
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "3.0.14".freeze
2
+ VERSION = "3.0.15".freeze
3
3
  end
data/lib/fontist.rb CHANGED
@@ -7,6 +7,7 @@ require "lutaml/model"
7
7
  require_relative "fontist/errors"
8
8
  require_relative "fontist/version"
9
9
  require_relative "fontist/cache"
10
+ require_relative "fontist/from_file_cache"
10
11
  require_relative "fontist/memoizable"
11
12
  require_relative "fontist/path_scanning"
12
13
  require_relative "fontist/utils"
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.14
4
+ version: 3.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -375,6 +375,7 @@ files:
375
375
  - lib/fontist/formula.rb
376
376
  - lib/fontist/formula_picker.rb
377
377
  - lib/fontist/formula_suggestion.rb
378
+ - lib/fontist/from_file_cache.rb
378
379
  - lib/fontist/google_import_source.rb
379
380
  - lib/fontist/helpers.rb
380
381
  - lib/fontist/import.rb