Class: Bootsnap::LoadPathCache::Cache
- Inherits:
-
Object
- Object
- Bootsnap::LoadPathCache::Cache
- Defined in:
- lib/bootsnap/load_path_cache/cache.rb
Constant Summary collapse
- AGE_THRESHOLD =
seconds
30
- BUILTIN_FEATURES =
{ ‘enumerator’ => nil, ‘enumerator.so’ => nil, … }
$LOADED_FEATURES.reduce({}) do |acc, feat| # Builtin features are of the form 'enumerator.so'. # All others include paths. next acc unless feat.size < 20 && !feat.include?('/') base = File.basename(feat, '.*') # enumerator.so -> enumerator ext = File.extname(feat) # .so acc[feat] = nil # enumerator.so acc[base] = nil # enumerator if [DOT_SO, *DL_EXTENSIONS].include?(ext) DL_EXTENSIONS.each do |dl_ext| acc["#{base}#{dl_ext}"] = nil # enumerator.bundle end end acc end.freeze
Instance Method Summary collapse
- #absolute_path?(path) ⇒ Boolean
- #each_requirable ⇒ Object
-
#find(feature) ⇒ Object
Try to resolve this feature to an absolute path without traversing the loadpath.
-
#has_dir?(dir) ⇒ Boolean
Does this directory exist as a child of one of the path items? e.g.
-
#initialize(store, path_obj, development_mode: false) ⇒ Cache
constructor
A new instance of Cache.
- #push_paths(sender, *paths) ⇒ Object
- #reinitialize(path_obj = @path_obj) ⇒ Object
- #unshift_paths(sender, *paths) ⇒ Object
Constructor Details
#initialize(store, path_obj, development_mode: false) ⇒ Cache
Returns a new instance of Cache.
8 9 10 11 12 13 14 15 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 8 def initialize(store, path_obj, development_mode: false) @development_mode = development_mode @store = store @mutex = defined?(::Mutex) ? ::Mutex.new : ::Thread::Mutex.new # TODO: Remove once Ruby 2.2 support is dropped. @path_obj = path_obj @has_relative_paths = nil reinitialize end |
Instance Method Details
#absolute_path?(path) ⇒ Boolean
89 90 91 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 89 def absolute_path?(path) path[1] == ':' end |
#each_requirable ⇒ Object
108 109 110 111 112 113 114 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 108 def each_requirable @mutex.synchronize do @index.each do |rel, entry| yield "#{entry}/#{rel}" end end end |
#find(feature) ⇒ Object
Try to resolve this feature to an absolute path without traversing the loadpath.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 48 def find(feature) reinitialize if (@has_relative_paths && dir_changed?) || stale? feature = feature.to_s return feature if absolute_path?(feature) return File.(feature) if feature.start_with?('./') @mutex.synchronize do x = search_index(feature) return x if x # Ruby has some built-in features that require lies about. # For example, 'enumerator' is built in. If you require it, ruby # returns false as if it were already loaded; however, there is no # file to find on disk. We've pre-built a list of these, and we # return false if any of them is loaded. raise LoadPathCache::ReturnFalse if BUILTIN_FEATURES.key?(feature) # The feature wasn't found on our preliminary search through the index. # We resolve this differently depending on what the extension was. case File.extname(feature) # If the extension was one of the ones we explicitly cache (.rb and the # native dynamic extension, e.g. .bundle or .so), we know it was a # failure and there's nothing more we can do to find the file. when '', *CACHED_EXTENSIONS # no extension, .rb, (.bundle or .so) nil # Ruby allows specifying native extensions as '.so' even when DLEXT # is '.bundle'. This is where we handle that case. when DOT_SO x = search_index(feature[0..-4] + DLEXT) return x if x if DLEXT2 search_index(feature[0..-4] + DLEXT2) end else # other, unknown extension. For example, `.rake`. Since we haven't # cached these, we legitimately need to run the load path search. raise LoadPathCache::FallbackScan end end end |
#has_dir?(dir) ⇒ Boolean
Does this directory exist as a child of one of the path items? e.g. given “/a/b/c/d” exists, and the path is [“/a/b”], has_dir?(“c/d”) is true.
20 21 22 23 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 20 def has_dir?(dir) reinitialize if stale? @mutex.synchronize { @dirs[dir] } end |
#push_paths(sender, *paths) ⇒ Object
103 104 105 106 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 103 def push_paths(sender, *paths) return unless sender == @path_obj @mutex.synchronize { push_paths_locked(*paths) } end |
#reinitialize(path_obj = @path_obj) ⇒ Object
116 117 118 119 120 121 122 123 124 125 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 116 def reinitialize(path_obj = @path_obj) @mutex.synchronize do @path_obj = path_obj ChangeObserver.register(self, @path_obj) @index = {} @dirs = Hash.new(false) @generated_at = now push_paths_locked(*@path_obj) end end |
#unshift_paths(sender, *paths) ⇒ Object
98 99 100 101 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 98 def unshift_paths(sender, *paths) return unless sender == @path_obj @mutex.synchronize { unshift_paths_locked(*paths) } end |