Commit d4059ac966e26c4f384c53ca14319c56619fef78

Authored by randx
1 parent 05c86fb0

Move graph_commit under gitlab module

app/controllers/projects_controller.rb
1 -require File.join(Rails.root, 'lib', 'graph_commit') 1 +require Rails.root.join('lib', 'gitlab', 'graph_commit')
2 2
3 class ProjectsController < ApplicationController 3 class ProjectsController < ApplicationController
4 before_filter :project, except: [:index, :new, :create] 4 before_filter :project, except: [:index, :new, :create]
@@ -78,7 +78,7 @@ class ProjectsController &lt; ApplicationController @@ -78,7 +78,7 @@ class ProjectsController &lt; ApplicationController
78 end 78 end
79 79
80 def graph 80 def graph
81 - @days_json, @commits_json = GraphCommit.to_graph(project) 81 + @days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
82 end 82 end
83 83
84 def destroy 84 def destroy
lib/gitlab/graph_commit.rb 0 → 100644
@@ -0,0 +1,183 @@ @@ -0,0 +1,183 @@
  1 +require "grit"
  2 +
  3 +module Gitlab
  4 + class GraphCommit
  5 + attr_accessor :time, :space
  6 + attr_accessor :refs
  7 +
  8 + def self.to_graph(project)
  9 + @repo = project.repo
  10 + commits = Grit::Commit.find_all(@repo, nil, {max_count: 650})
  11 +
  12 + ref_cache = {}
  13 +
  14 + commits.map! {|c| GraphCommit.new(Commit.new(c))}
  15 + commits.each { |commit| commit.add_refs(ref_cache, @repo) }
  16 +
  17 + days = GraphCommit.index_commits(commits)
  18 + @days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json
  19 + @commits_json = commits.map(&:to_graph_hash).to_json
  20 +
  21 + return @days_json, @commits_json
  22 + end
  23 +
  24 + # Method is adding time and space on the
  25 + # list of commits. As well as returns date list
  26 + # corelated with time set on commits.
  27 + #
  28 + # @param [Array<GraphCommit>] comits to index
  29 + #
  30 + # @return [Array<TimeDate>] list of commit dates corelated with time on commits
  31 + def self.index_commits(commits)
  32 + days, heads = [], []
  33 + map = {}
  34 +
  35 + commits.reverse.each_with_index do |c,i|
  36 + c.time = i
  37 + days[i] = c.committed_date
  38 + map[c.id] = c
  39 + heads += c.refs unless c.refs.nil?
  40 + end
  41 +
  42 + heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
  43 + # sort heads so the master is top and current branches are closer
  44 + heads.sort! do |a,b|
  45 + if a.name == "master"
  46 + -1
  47 + elsif b.name == "master"
  48 + 1
  49 + else
  50 + b.commit.committed_date <=> a.commit.committed_date
  51 + end
  52 + end
  53 +
  54 + @_reserved = {}
  55 + days.each_index do |i|
  56 + @_reserved[i] = []
  57 + end
  58 +
  59 + heads.each do |h|
  60 + if map.include? h.commit.id then
  61 + place_chain(map[h.commit.id], map)
  62 + end
  63 + end
  64 + days
  65 + end
  66 +
  67 + # Add space mark on commit and its parents
  68 + #
  69 + # @param [GraphCommit] the commit object.
  70 + # @param [Hash<String,GraphCommit>] map of commits
  71 + def self.place_chain(commit, map, parent_time = nil)
  72 + leaves = take_left_leaves(commit, map)
  73 + if leaves.empty? then
  74 + return
  75 + end
  76 + space = find_free_space(leaves.last.time..leaves.first.time)
  77 + leaves.each{|l| l.space = space}
  78 + # and mark it as reserved
  79 + min_time = leaves.last.time
  80 + parents = leaves.last.parents.collect
  81 + parents.each do |p|
  82 + if map.include? p.id then
  83 + parent = map[p.id]
  84 + if parent.time < min_time then
  85 + min_time = parent.time
  86 + end
  87 + end
  88 + end
  89 + if parent_time.nil? then
  90 + max_time = leaves.first.time
  91 + else
  92 + max_time = parent_time - 1
  93 + end
  94 + mark_reserved(min_time..max_time, space)
  95 + # Visit branching chains
  96 + leaves.each do |l|
  97 + parents = l.parents.collect
  98 + .select{|p| map.include? p.id and map[p.id].space == 0}
  99 + for p in parents
  100 + place_chain(map[p.id], map, l.time)
  101 + end
  102 + end
  103 + end
  104 +
  105 + def self.mark_reserved(time_range, space)
  106 + for day in time_range
  107 + @_reserved[day].push(space)
  108 + end
  109 + end
  110 +
  111 + def self.find_free_space(time_range)
  112 + reserved = []
  113 + for day in time_range
  114 + reserved += @_reserved[day]
  115 + end
  116 + space = 1
  117 + while reserved.include? space do
  118 + space += 1
  119 + end
  120 + space
  121 + end
  122 +
  123 + # Takes most left subtree branch of commits
  124 + # which don't have space mark yet.
  125 + #
  126 + # @param [GraphCommit] the commit object.
  127 + # @param [Hash<String,GraphCommit>] map of commits
  128 + #
  129 + # @return [Array<GraphCommit>] list of branch commits
  130 + def self.take_left_leaves(commit, map)
  131 + leaves = []
  132 + leaves.push(commit) if commit.space == 0
  133 + while true
  134 + parent = commit.parents.collect
  135 + .select{|p| map.include? p.id and map[p.id].space == 0}
  136 + if parent.count == 0 then
  137 + return leaves
  138 + else
  139 + commit = map[parent.first.id]
  140 + leaves.push(commit)
  141 + end
  142 + end
  143 + end
  144 +
  145 +
  146 + def initialize(commit)
  147 + @_commit = commit
  148 + @time = -1
  149 + @space = 0
  150 + end
  151 +
  152 + def method_missing(m, *args, &block)
  153 + @_commit.send(m, *args, &block)
  154 + end
  155 +
  156 + def to_graph_hash
  157 + h = {}
  158 + h[:parents] = self.parents.collect do |p|
  159 + [p.id,0,0]
  160 + end
  161 + h[:author] = Gitlab::Encode.utf8(author.name)
  162 + h[:time] = time
  163 + h[:space] = space
  164 + h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
  165 + h[:id] = sha
  166 + h[:date] = date
  167 + h[:message] = Gitlab::Encode.utf8(message)
  168 + h[:login] = author.email
  169 + h
  170 + end
  171 +
  172 + def add_refs(ref_cache, repo)
  173 + if ref_cache.empty?
  174 + repo.refs.each do |ref|
  175 + ref_cache[ref.commit.id] ||= []
  176 + ref_cache[ref.commit.id] << ref
  177 + end
  178 + end
  179 + @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id)
  180 + @refs ||= []
  181 + end
  182 + end
  183 +end
lib/graph_commit.rb
@@ -1,181 +0,0 @@ @@ -1,181 +0,0 @@
1 -require "grit"  
2 -  
3 -class GraphCommit  
4 - attr_accessor :time, :space  
5 - attr_accessor :refs  
6 -  
7 - def self.to_graph(project)  
8 - @repo = project.repo  
9 - commits = Grit::Commit.find_all(@repo, nil, {max_count: 650})  
10 -  
11 - ref_cache = {}  
12 -  
13 - commits.map! {|c| GraphCommit.new(Commit.new(c))}  
14 - commits.each { |commit| commit.add_refs(ref_cache, @repo) }  
15 -  
16 - days = GraphCommit.index_commits(commits)  
17 - @days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json  
18 - @commits_json = commits.map(&:to_graph_hash).to_json  
19 -  
20 - return @days_json, @commits_json  
21 - end  
22 -  
23 - # Method is adding time and space on the  
24 - # list of commits. As well as returns date list  
25 - # corelated with time set on commits.  
26 - #  
27 - # @param [Array<GraphCommit>] comits to index  
28 - #  
29 - # @return [Array<TimeDate>] list of commit dates corelated with time on commits  
30 - def self.index_commits(commits)  
31 - days, heads = [], []  
32 - map = {}  
33 -  
34 - commits.reverse.each_with_index do |c,i|  
35 - c.time = i  
36 - days[i] = c.committed_date  
37 - map[c.id] = c  
38 - heads += c.refs unless c.refs.nil?  
39 - end  
40 -  
41 - heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}  
42 - # sort heads so the master is top and current branches are closer  
43 - heads.sort! do |a,b|  
44 - if a.name == "master"  
45 - -1  
46 - elsif b.name == "master"  
47 - 1  
48 - else  
49 - b.commit.committed_date <=> a.commit.committed_date  
50 - end  
51 - end  
52 -  
53 - @_reserved = {}  
54 - days.each_index do |i|  
55 - @_reserved[i] = []  
56 - end  
57 -  
58 - heads.each do |h|  
59 - if map.include? h.commit.id then  
60 - place_chain(map[h.commit.id], map)  
61 - end  
62 - end  
63 - days  
64 - end  
65 -  
66 - # Add space mark on commit and its parents  
67 - #  
68 - # @param [GraphCommit] the commit object.  
69 - # @param [Hash<String,GraphCommit>] map of commits  
70 - def self.place_chain(commit, map, parent_time = nil)  
71 - leaves = take_left_leaves(commit, map)  
72 - if leaves.empty? then  
73 - return  
74 - end  
75 - space = find_free_space(leaves.last.time..leaves.first.time)  
76 - leaves.each{|l| l.space = space}  
77 - # and mark it as reserved  
78 - min_time = leaves.last.time  
79 - parents = leaves.last.parents.collect  
80 - parents.each do |p|  
81 - if map.include? p.id then  
82 - parent = map[p.id]  
83 - if parent.time < min_time then  
84 - min_time = parent.time  
85 - end  
86 - end  
87 - end  
88 - if parent_time.nil? then  
89 - max_time = leaves.first.time  
90 - else  
91 - max_time = parent_time - 1  
92 - end  
93 - mark_reserved(min_time..max_time, space)  
94 - # Visit branching chains  
95 - leaves.each do |l|  
96 - parents = l.parents.collect  
97 - .select{|p| map.include? p.id and map[p.id].space == 0}  
98 - for p in parents  
99 - place_chain(map[p.id], map, l.time)  
100 - end  
101 - end  
102 - end  
103 -  
104 - def self.mark_reserved(time_range, space)  
105 - for day in time_range  
106 - @_reserved[day].push(space)  
107 - end  
108 - end  
109 -  
110 - def self.find_free_space(time_range)  
111 - reserved = []  
112 - for day in time_range  
113 - reserved += @_reserved[day]  
114 - end  
115 - space = 1  
116 - while reserved.include? space do  
117 - space += 1  
118 - end  
119 - space  
120 - end  
121 -  
122 - # Takes most left subtree branch of commits  
123 - # which don't have space mark yet.  
124 - #  
125 - # @param [GraphCommit] the commit object.  
126 - # @param [Hash<String,GraphCommit>] map of commits  
127 - #  
128 - # @return [Array<GraphCommit>] list of branch commits  
129 - def self.take_left_leaves(commit, map)  
130 - leaves = []  
131 - leaves.push(commit) if commit.space == 0  
132 - while true  
133 - parent = commit.parents.collect  
134 - .select{|p| map.include? p.id and map[p.id].space == 0}  
135 - if parent.count == 0 then  
136 - return leaves  
137 - else  
138 - commit = map[parent.first.id]  
139 - leaves.push(commit)  
140 - end  
141 - end  
142 - end  
143 -  
144 -  
145 - def initialize(commit)  
146 - @_commit = commit  
147 - @time = -1  
148 - @space = 0  
149 - end  
150 -  
151 - def method_missing(m, *args, &block)  
152 - @_commit.send(m, *args, &block)  
153 - end  
154 -  
155 - def to_graph_hash  
156 - h = {}  
157 - h[:parents] = self.parents.collect do |p|  
158 - [p.id,0,0]  
159 - end  
160 - h[:author] = Gitlab::Encode.utf8(author.name)  
161 - h[:time] = time  
162 - h[:space] = space  
163 - h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?  
164 - h[:id] = sha  
165 - h[:date] = date  
166 - h[:message] = Gitlab::Encode.utf8(message)  
167 - h[:login] = author.email  
168 - h  
169 - end  
170 -  
171 - def add_refs(ref_cache, repo)  
172 - if ref_cache.empty?  
173 - repo.refs.each do |ref|  
174 - ref_cache[ref.commit.id] ||= []  
175 - ref_cache[ref.commit.id] << ref  
176 - end  
177 - end  
178 - @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id)  
179 - @refs ||= []  
180 - end  
181 -end