debian-mirror-gitlab/lib/gitlab/discussions_diff/file_collection.rb

80 lines
2.2 KiB
Ruby
Raw Normal View History

2019-02-15 15:39:39 +05:30
# frozen_string_literal: true
module Gitlab
module DiscussionsDiff
class FileCollection
include Gitlab::Utils::StrongMemoize
2019-12-04 20:38:33 +05:30
include Enumerable
2019-02-15 15:39:39 +05:30
def initialize(collection)
@collection = collection
end
2019-12-04 20:38:33 +05:30
def each(&block)
@collection.each(&block)
end
2019-02-15 15:39:39 +05:30
# Returns a Gitlab::Diff::File with the given ID (`unique_identifier` in
# Gitlab::Diff::File).
def find_by_id(id)
diff_files_indexed_by_id[id]
end
# Writes cache and preloads highlighted diff lines for
2019-12-04 20:38:33 +05:30
# highlightable object IDs, in @collection.
2019-02-15 15:39:39 +05:30
#
# - Highlight cache is written just for uncached diff files
# - The cache content is not updated (there's no need to do so)
2019-12-04 20:38:33 +05:30
def load_highlight
ids = highlightable_collection_ids
2019-12-21 20:55:43 +05:30
return if ids.empty?
2019-02-15 15:39:39 +05:30
cached_content = read_cache(ids)
uncached_ids = ids.select.each_with_index { |_, i| cached_content[i].nil? }
mapping = highlighted_lines_by_ids(uncached_ids)
2019-12-21 20:55:43 +05:30
HighlightCache.write_multiple(mapping) if mapping.any?
2019-02-15 15:39:39 +05:30
diffs = diff_files_indexed_by_id.values_at(*ids)
diffs.zip(cached_content).each do |diff, cached_lines|
next unless diff && cached_lines
diff.highlighted_diff_lines = cached_lines
end
end
2019-12-04 20:38:33 +05:30
private
def highlightable_collection_ids
each.with_object([]) { |file, memo| memo << file.id unless file.resolved_at }
end
2019-02-15 15:39:39 +05:30
def read_cache(ids)
HighlightCache.read_multiple(ids)
end
def diff_files_indexed_by_id
strong_memoize(:diff_files_indexed_by_id) do
diff_files.index_by(&:unique_identifier)
end
end
def diff_files
2019-12-04 20:38:33 +05:30
strong_memoize(:diff_files) { map(&:raw_diff_file) }
2019-02-15 15:39:39 +05:30
end
# Processes the diff lines highlighting for diff files matching the given
# IDs.
#
# Returns a Hash with { id => [Array of Gitlab::Diff::line], ...]
def highlighted_lines_by_ids(ids)
diff_files_indexed_by_id.slice(*ids).each_with_object({}) do |(id, file), hash|
hash[id] = file.highlighted_diff_lines.map(&:to_hash)
end
end
end
end
end