Class: Banzai::Filter::References::ReferenceCache
- Inherits:
-
Object
- Object
- Banzai::Filter::References::ReferenceCache
show all
- Includes:
- RequestStoreReferenceCache, Gitlab::Utils::StrongMemoize
- Defined in:
- lib/banzai/filter/references/reference_cache.rb
Instance Method Summary
collapse
#cached_call, #get_or_set_cache
Constructor Details
#initialize(filter, context, result) ⇒ ReferenceCache
Returns a new instance of ReferenceCache.
10
11
12
13
14
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 10
def initialize(filter, context, result)
@filter = filter
@context = context
@result = result || {}
end
|
Instance Method Details
#cache_loaded? ⇒ Boolean
170
171
172
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 170
def cache_loaded?
!!@cache_loaded
end
|
#current_parent_path ⇒ Object
145
146
147
148
149
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 145
def current_parent_path
strong_memoize(:current_parent_path) do
parent&.full_path
end
end
|
#current_project_namespace_path ⇒ Object
151
152
153
154
155
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 151
def current_project_namespace_path
strong_memoize(:current_project_namespace_path) do
project&.namespace&.full_path
end
end
|
#find_for_paths(paths) ⇒ Object
Returns projects for the given paths.
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 118
def find_for_paths(paths)
if Gitlab::SafeRequestStore.active?
cache = refs_cache
to_query = paths - cache.keys
unless to_query.empty?
records = objects_for_paths(to_query)
found = []
records.each do |record|
ref = record.full_path
get_or_set_cache(cache, ref) { record }
found << ref
end
not_found = to_query - found
not_found.each do |ref|
get_or_set_cache(cache, ref) { nil }
end
end
cache.slice(*paths).values.compact
else
objects_for_paths(paths)
end
end
|
#full_group_path(group_ref) ⇒ Object
164
165
166
167
168
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 164
def full_group_path(group_ref)
return current_parent_path unless group_ref
group_ref
end
|
#full_project_path(namespace, project_ref) ⇒ Object
157
158
159
160
161
162
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 157
def full_project_path(namespace, project_ref)
return current_parent_path unless project_ref
namespace_ref = namespace || current_project_namespace_path
"#{namespace_ref}/#{project_ref}"
end
|
#load_parent_per_reference ⇒ Object
Returns a Hash containing referenced projects grouped per their full path.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 57
def load_parent_per_reference
@per_reference ||= {}
@per_reference[parent_type] ||= begin
refs = references_per_parent.keys
parent_ref = {}
refs.each do |ref|
next unless ref
if context[:project]&.full_path == ref
parent_ref[ref] = context[:project]
elsif context[:group]&.full_path == ref
parent_ref[ref] = context[:group]
end
refs -= [ref] if parent_ref[ref]
end
find_for_paths(refs).index_by(&:full_path).merge(parent_ref)
end
end
|
#load_records_per_parent ⇒ Object
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 85
def load_records_per_parent
@_records_per_project ||= {}
@_records_per_project[filter.object_class.to_s.underscore] ||= begin
hash = Hash.new { |h, k| h[k] = {} }
parent_per_reference.each do |path, parent|
record_ids = references_per_parent[path]
filter.parent_records(parent, record_ids).each do |record|
hash[parent][filter.record_identifier(record)] = record
end
end
hash
end
end
|
#load_reference_cache(nodes) ⇒ Object
16
17
18
19
20
21
22
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 16
def load_reference_cache(nodes)
load_references_per_parent(nodes)
load_parent_per_reference
load_records_per_parent
@cache_loaded = true
end
|
#load_references_per_parent(nodes) ⇒ Object
Loads all object references (e.g. issue IDs) per project/group they belong to.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 26
def load_references_per_parent(nodes)
@references_per_parent ||= {}
@references_per_parent[parent_type] ||= begin
refs = Hash.new { |hash, key| hash[key] = Set.new }
[filter.object_class.link_reference_pattern, filter.object_class.reference_pattern].each do |pattern|
next unless pattern
prepare_doc_for_scan.to_enum(:scan, pattern).each do
parent_path = if parent_type == :project
full_project_path($~[:namespace], $~[:project])
else
full_group_path($~[:group])
end
ident = filter.identifier($~)
refs[parent_path] << ident if ident
end
end
refs
end
end
|
#objects_for_paths(paths) ⇒ Object
107
108
109
110
111
112
113
114
115
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 107
def objects_for_paths(paths)
klass = parent_type.to_s.camelize.constantize
result = klass.where_full_path_in(paths)
return result if parent_type == :group
return unless parent_type == :project
result.includes(namespace: :route)
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/420046")
end
|
#parent_per_reference ⇒ Object
81
82
83
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 81
def parent_per_reference
@per_reference[parent_type]
end
|
#records_per_parent ⇒ Object
103
104
105
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 103
def records_per_parent
@_records_per_project[filter.object_class.to_s.underscore]
end
|
#references_per_parent ⇒ Object
51
52
53
|
# File 'lib/banzai/filter/references/reference_cache.rb', line 51
def references_per_parent
@references_per_parent[parent_type]
end
|