diff options
author | Oswaldo Ferreira <oswaldo@gitlab.com> | 2018-12-16 14:00:43 -0200 |
---|---|---|
committer | Oswaldo Ferreira <oswaldo@gitlab.com> | 2018-12-21 16:59:21 -0200 |
commit | 7cf4947792647fd985c38ebf37c27989fd5a1632 (patch) | |
tree | 46bef7a798e8749e815f594a918266c8d9f9dd61 /lib/gitlab/diff | |
parent | a9049532a271117983430d2d80b8ad61879ecf7a (diff) | |
download | gitlab-ce-7cf4947792647fd985c38ebf37c27989fd5a1632.tar.gz |
Cache diff highlight in discussions
This commit handles note diffs caching, which considerably improves
the performance on merge requests with lots of comments.
Important to note that the caching approach taken here is different
from `Gitlab::Diff::HighlightCache`. We do not reset the whole cache
when a new push is sent or anything else. That's because discussions
diffs are persisted and do not change.
Diffstat (limited to 'lib/gitlab/diff')
-rw-r--r-- | lib/gitlab/diff/file.rb | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index b5fc8d364c8..bcbded6be9a 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -3,7 +3,7 @@ module Gitlab module Diff class File - attr_reader :diff, :repository, :diff_refs, :fallback_diff_refs + attr_reader :diff, :repository, :diff_refs, :fallback_diff_refs, :unique_identifier delegate :new_file?, :deleted_file?, :renamed_file?, :old_path, :new_path, :a_mode, :b_mode, :mode_changed?, @@ -22,12 +22,20 @@ module Gitlab DiffViewer::Image ].sort_by { |v| v.binary? ? 0 : 1 }.freeze - def initialize(diff, repository:, diff_refs: nil, fallback_diff_refs: nil, stats: nil) + def initialize( + diff, + repository:, + diff_refs: nil, + fallback_diff_refs: nil, + stats: nil, + unique_identifier: nil) + @diff = diff @stats = stats @repository = repository @diff_refs = diff_refs @fallback_diff_refs = fallback_diff_refs + @unique_identifier = unique_identifier @unfolded = false # Ensure items are collected in the the batch @@ -67,7 +75,15 @@ module Gitlab def line_for_position(pos) return nil unless pos.position_type == 'text' - diff_lines.find { |line| line.old_line == pos.old_line && line.new_line == pos.new_line } + # This method is normally used to find which line the diff was + # commented on, and in this context, it's normally the raw diff persisted + # at `note_diff_files`, which is a fraction of the entire diff + # (it goes from the first line, to the commented line, or + # one line below). Therefore it's more performant to fetch + # from bottom to top instead of the other way around. + diff_lines + .reverse_each + .find { |line| line.old_line == pos.old_line && line.new_line == pos.new_line } end def position_for_line_code(code) @@ -166,6 +182,10 @@ module Gitlab @unfolded end + def highlight_loaded? + @highlighted_diff_lines.present? + end + def highlighted_diff_lines @highlighted_diff_lines ||= Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight |