summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2016-08-30 23:02:39 +0800
committerLin Jen-Shin <godfat@godfat.org>2016-08-30 23:02:39 +0800
commitbd78e6af297c59d220090a037891003ec2571e22 (patch)
tree34f78854c29525bca16506ea4d9c76c0d03ce235
parent031b162392c074b0bff1a5d4239acd8026592fdd (diff)
downloadgitlab-ce-bd78e6af297c59d220090a037891003ec2571e22.tar.gz
Use algorithm from Kamil:
Excluding sorting, this is O(n) which should be much faster and much simpler and easier to understand.
-rw-r--r--lib/gitlab/ci/pipeline_duration.rb37
1 files changed, 9 insertions, 28 deletions
diff --git a/lib/gitlab/ci/pipeline_duration.rb b/lib/gitlab/ci/pipeline_duration.rb
index 03bf7fabc99..ff6dcdbfa31 100644
--- a/lib/gitlab/ci/pipeline_duration.rb
+++ b/lib/gitlab/ci/pipeline_duration.rb
@@ -37,41 +37,22 @@ module Gitlab
if segments.empty?
segments
else
- segments[1..-1].inject([segments.first]) do |current, target|
- left, result = insert_segment(current, target)
+ segments.drop(1).inject([segments.first]) do |result, current|
+ merged = try_merge_segment(result.last, current)
- if left # left is the latest one
- result << left
- else
+ if merged
+ result[-1] = merged
result
+ else
+ result << current
end
end
end
end
- def insert_segment(segments, init)
- segments.inject([init, []]) do |target_result, member|
- target, result = target_result
-
- if target.nil? # done
- result << member
- [nil, result]
- elsif merged = try_merge_segment(target, member) # overlapped
- [merged, result] # merge and keep finding the hole
- elsif target.last < member.first # found the hole
- result << target << member
- [nil, result]
- else
- result << member
- target_result
- end
- end
- end
-
- def try_merge_segment(target, member)
- if target.first <= member.last && target.last >= member.first
- Segment.new([target.first, member.first].min,
- [target.last, member.last].max)
+ def try_merge_segment(previous, current)
+ if current.first <= previous.last
+ Segment.new(previous.first, [previous.last, current.last].max)
end
end