84 |
13 Mar 06 |
jari |
// $Id$ |
14 |
30 Dec 05 |
peter |
2 |
|
84 |
13 Mar 06 |
jari |
3 |
/* |
84 |
13 Mar 06 |
jari |
Copyright (C) 2005 Peter Johansson |
978 |
12 Dec 09 |
peter |
Copyright (C) 2006, 2007, 2008, 2009 Jari Häkkinen, Peter Johansson |
1635 |
30 Mar 23 |
peter |
Copyright (C) 2010, 2011, 2012, 2023 Peter Johansson |
84 |
13 Mar 06 |
jari |
7 |
|
687 |
04 Aug 08 |
peter |
This file is part of svndigest, http://dev.thep.lu.se/svndigest |
84 |
13 Mar 06 |
jari |
9 |
|
149 |
12 Aug 06 |
jari |
svndigest is free software; you can redistribute it and/or modify it |
84 |
13 Mar 06 |
jari |
under the terms of the GNU General Public License as published by |
693 |
11 Sep 08 |
jari |
the Free Software Foundation; either version 3 of the License, or |
84 |
13 Mar 06 |
jari |
(at your option) any later version. |
84 |
13 Mar 06 |
jari |
14 |
|
149 |
12 Aug 06 |
jari |
svndigest is distributed in the hope that it will be useful, but |
84 |
13 Mar 06 |
jari |
WITHOUT ANY WARRANTY; without even the implied warranty of |
149 |
12 Aug 06 |
jari |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
84 |
13 Mar 06 |
jari |
General Public License for more details. |
84 |
13 Mar 06 |
jari |
19 |
|
84 |
13 Mar 06 |
jari |
You should have received a copy of the GNU General Public License |
693 |
11 Sep 08 |
jari |
along with svndigest. If not, see <http://www.gnu.org/licenses/>. |
84 |
13 Mar 06 |
jari |
22 |
*/ |
84 |
13 Mar 06 |
jari |
23 |
|
1619 |
12 Mar 23 |
peter |
24 |
#include <config.h> |
1619 |
12 Mar 23 |
peter |
25 |
|
14 |
30 Dec 05 |
peter |
26 |
#include "Stats.h" |
129 |
02 Aug 06 |
jari |
27 |
|
929 |
02 Dec 09 |
jari |
28 |
#include "Colors.h" |
1007 |
03 Jan 10 |
peter |
29 |
#include "Configuration.h" |
465 |
24 Aug 07 |
peter |
30 |
#include "Functor.h" |
138 |
03 Aug 06 |
jari |
31 |
#include "SVNblame.h" |
129 |
02 Aug 06 |
jari |
32 |
#include "SVNinfo.h" |
14 |
30 Dec 05 |
peter |
33 |
#include "utility.h" |
14 |
30 Dec 05 |
peter |
34 |
|
41 |
13 Jan 06 |
peter |
35 |
#include <algorithm> |
65 |
20 Jan 06 |
peter |
36 |
#include <cassert> |
63 |
19 Jan 06 |
peter |
37 |
#include <cstdlib> |
454 |
18 Aug 07 |
peter |
38 |
#include <fstream> |
1652 |
14 Jun 23 |
peter |
39 |
#include <initializer_list> |
1003 |
02 Jan 10 |
peter |
40 |
#include <iostream> |
454 |
18 Aug 07 |
peter |
41 |
#include <iterator> |
14 |
30 Dec 05 |
peter |
42 |
#include <map> |
14 |
30 Dec 05 |
peter |
43 |
#include <numeric> |
14 |
30 Dec 05 |
peter |
44 |
#include <string> |
138 |
03 Aug 06 |
jari |
45 |
#include <sstream> |
44 |
13 Jan 06 |
jari |
46 |
#include <unistd.h> |
23 |
02 Jan 06 |
peter |
47 |
#include <utility> |
14 |
30 Dec 05 |
peter |
48 |
#include <vector> |
14 |
30 Dec 05 |
peter |
49 |
|
14 |
30 Dec 05 |
peter |
50 |
namespace theplu{ |
149 |
12 Aug 06 |
jari |
51 |
namespace svndigest{ |
14 |
30 Dec 05 |
peter |
52 |
|
14 |
30 Dec 05 |
peter |
53 |
|
80 |
10 Mar 06 |
jari |
54 |
Stats::Stats(const std::string& path) |
1478 |
29 May 12 |
peter |
55 |
: stats_(std::vector<Author2Vector>(LineTypeParser::total+1)), |
1478 |
29 May 12 |
peter |
56 |
ignore_rev_(0) |
80 |
10 Mar 06 |
jari |
57 |
{ |
80 |
10 Mar 06 |
jari |
// Make sure latest revision is set properly |
129 |
02 Aug 06 |
jari |
59 |
SVNinfo svn_info(path); |
129 |
02 Aug 06 |
jari |
60 |
revision_=svn_info.rev(); |
129 |
02 Aug 06 |
jari |
61 |
last_changed_rev_=svn_info.last_changed_rev(); |
639 |
31 May 08 |
peter |
62 |
reset(); |
1378 |
14 Jun 11 |
peter |
63 |
config_code_ = Configuration::instance().code(path); |
80 |
10 Mar 06 |
jari |
64 |
} |
80 |
10 Mar 06 |
jari |
65 |
|
80 |
10 Mar 06 |
jari |
66 |
|
487 |
13 Oct 07 |
peter |
67 |
Stats::~Stats(void) |
487 |
13 Oct 07 |
peter |
68 |
{ |
487 |
13 Oct 07 |
peter |
69 |
} |
14 |
30 Dec 05 |
peter |
70 |
|
1478 |
29 May 12 |
peter |
71 |
|
1194 |
03 Oct 10 |
peter |
72 |
void Stats::add(const std::vector<std::map<std::string, SparseVector> >& data) |
1194 |
03 Oct 10 |
peter |
73 |
{ |
1194 |
03 Oct 10 |
peter |
// loop over line types |
1194 |
03 Oct 10 |
peter |
75 |
for (size_t lt = 0; lt<data.size(); ++lt) { |
1194 |
03 Oct 10 |
peter |
76 |
std::map<std::string, SparseVector>::const_iterator iter=data[lt].begin(); |
1194 |
03 Oct 10 |
peter |
77 |
std::map<std::string, SparseVector>::const_iterator last=data[lt].end(); |
1194 |
03 Oct 10 |
peter |
// loop over users |
1194 |
03 Oct 10 |
peter |
79 |
for ( ; iter!=last; ++iter) { |
1194 |
03 Oct 10 |
peter |
80 |
add_author(iter->first); |
1194 |
03 Oct 10 |
peter |
81 |
SumVector tmpvec; |
1194 |
03 Oct 10 |
peter |
82 |
accumulate(iter->second, tmpvec); |
1194 |
03 Oct 10 |
peter |
83 |
stats_[lt][iter->first] += tmpvec; |
1194 |
03 Oct 10 |
peter |
84 |
} |
1194 |
03 Oct 10 |
peter |
85 |
} |
1194 |
03 Oct 10 |
peter |
86 |
} |
14 |
30 Dec 05 |
peter |
87 |
|
1194 |
03 Oct 10 |
peter |
88 |
|
487 |
13 Oct 07 |
peter |
89 |
void Stats::add_author(std::string name) |
487 |
13 Oct 07 |
peter |
90 |
{ |
487 |
13 Oct 07 |
peter |
91 |
authors_.insert(name); |
487 |
13 Oct 07 |
peter |
92 |
} |
14 |
30 Dec 05 |
peter |
93 |
|
118 |
03 Jul 06 |
peter |
94 |
|
1478 |
29 May 12 |
peter |
95 |
void Stats::add_authors(std::set<std::string>::const_iterator first, |
487 |
13 Oct 07 |
peter |
96 |
std::set<std::string>::const_iterator last) |
487 |
13 Oct 07 |
peter |
97 |
{ |
487 |
13 Oct 07 |
peter |
98 |
authors_.insert(first, last); |
487 |
13 Oct 07 |
peter |
99 |
} |
118 |
03 Jul 06 |
peter |
100 |
|
118 |
03 Jul 06 |
peter |
101 |
|
487 |
13 Oct 07 |
peter |
102 |
const std::set<std::string>& Stats::authors(void) const |
487 |
13 Oct 07 |
peter |
103 |
{ |
487 |
13 Oct 07 |
peter |
104 |
return authors_; |
487 |
13 Oct 07 |
peter |
105 |
} |
202 |
10 Sep 06 |
peter |
106 |
|
14 |
30 Dec 05 |
peter |
107 |
|
537 |
27 Dec 07 |
peter |
108 |
void Stats::calc_all(void) |
537 |
27 Dec 07 |
peter |
109 |
{ |
1611 |
12 Feb 23 |
peter |
110 |
for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy, |
1611 |
12 Feb 23 |
peter |
111 |
LineTypeParser::other}) { |
803 |
10 Jul 09 |
peter |
112 |
stats_[lt]["all"].clear(); |
1199 |
04 Oct 10 |
peter |
113 |
for (std::map<std::string, SumVector>::iterator i = stats_[lt].begin(); |
1199 |
04 Oct 10 |
peter |
114 |
i!=stats_[lt].end(); ++i) { |
1199 |
04 Oct 10 |
peter |
115 |
stats_[lt]["all"] += i->second; |
1199 |
04 Oct 10 |
peter |
116 |
} |
803 |
10 Jul 09 |
peter |
117 |
} |
1194 |
03 Oct 10 |
peter |
118 |
|
1199 |
04 Oct 10 |
peter |
119 |
total_stats()["all"] = comment_or_copy_stats()["all"]; |
1199 |
04 Oct 10 |
peter |
120 |
total_stats()["all"] += code_stats()["all"]; |
1199 |
04 Oct 10 |
peter |
121 |
total_stats()["all"] += other_stats()["all"]; |
537 |
27 Dec 07 |
peter |
122 |
} |
537 |
27 Dec 07 |
peter |
123 |
|
537 |
27 Dec 07 |
peter |
124 |
|
537 |
27 Dec 07 |
peter |
125 |
void Stats::calc_total(void) |
537 |
27 Dec 07 |
peter |
126 |
{ |
537 |
27 Dec 07 |
peter |
127 |
for (std::set<std::string>::const_iterator iter(authors().begin()); |
537 |
27 Dec 07 |
peter |
128 |
iter!=authors().end(); ++iter) { |
1200 |
04 Oct 10 |
peter |
129 |
SumVector& total = total_stats()[*iter]; |
1200 |
04 Oct 10 |
peter |
130 |
total = code_stats()[*iter]; |
1611 |
12 Feb 23 |
peter |
131 |
total += comment_or_copy_stats()[*iter]; |
1200 |
04 Oct 10 |
peter |
132 |
total += other_stats()[*iter]; |
537 |
27 Dec 07 |
peter |
133 |
} |
537 |
27 Dec 07 |
peter |
134 |
} |
537 |
27 Dec 07 |
peter |
135 |
|
537 |
27 Dec 07 |
peter |
136 |
|
589 |
12 Apr 08 |
jari |
137 |
unsigned int Stats::code(const std::string& user) const |
487 |
13 Oct 07 |
peter |
138 |
{ |
552 |
08 Jan 08 |
peter |
139 |
return get_back(code_stats(), user); |
487 |
13 Oct 07 |
peter |
140 |
} |
60 |
16 Jan 06 |
peter |
141 |
|
487 |
13 Oct 07 |
peter |
142 |
|
589 |
12 Apr 08 |
jari |
143 |
unsigned int Stats::comments(const std::string& user) const |
487 |
13 Oct 07 |
peter |
144 |
{ |
552 |
08 Jan 08 |
peter |
145 |
return get_back(comment_or_copy_stats(), user); |
487 |
13 Oct 07 |
peter |
146 |
} |
487 |
13 Oct 07 |
peter |
147 |
|
487 |
13 Oct 07 |
peter |
148 |
|
1478 |
29 May 12 |
peter |
149 |
std::string Stats::config_code(void) const |
1478 |
29 May 12 |
peter |
150 |
{ |
1478 |
29 May 12 |
peter |
151 |
if (ignore_rev_==0) |
1478 |
29 May 12 |
peter |
152 |
return config_code_; |
1478 |
29 May 12 |
peter |
153 |
std::stringstream result(config_code_); |
1478 |
29 May 12 |
peter |
154 |
result << "ir" << ignore_rev_; |
1478 |
29 May 12 |
peter |
155 |
return result.str(); |
1478 |
29 May 12 |
peter |
156 |
} |
1478 |
29 May 12 |
peter |
157 |
|
1478 |
29 May 12 |
peter |
158 |
|
589 |
12 Apr 08 |
jari |
159 |
unsigned int Stats::empty(const std::string& user) const |
487 |
13 Oct 07 |
peter |
160 |
{ |
552 |
08 Jan 08 |
peter |
161 |
return get_back(other_stats(), user); |
487 |
13 Oct 07 |
peter |
162 |
} |
487 |
13 Oct 07 |
peter |
163 |
|
487 |
13 Oct 07 |
peter |
164 |
|
589 |
12 Apr 08 |
jari |
165 |
unsigned int Stats::get_back(const Author2Vector& m, std::string user) const |
487 |
13 Oct 07 |
peter |
166 |
{ |
528 |
25 Dec 07 |
peter |
167 |
A2VConstIter iter(m.find(std::string(user))); |
1478 |
29 May 12 |
peter |
168 |
if (iter==m.end() || iter->second.empty()) |
528 |
25 Dec 07 |
peter |
169 |
return 0; |
1495 |
27 Aug 12 |
peter |
170 |
assert(iter->second.size()); |
528 |
25 Dec 07 |
peter |
171 |
return iter->second.back(); |
487 |
13 Oct 07 |
peter |
172 |
} |
487 |
13 Oct 07 |
peter |
173 |
|
487 |
13 Oct 07 |
peter |
174 |
|
1478 |
29 May 12 |
peter |
175 |
const SumVector& Stats::get_vector(const Author2Vector& m, |
1194 |
03 Oct 10 |
peter |
176 |
const std::string& user) const |
487 |
13 Oct 07 |
peter |
177 |
{ |
528 |
25 Dec 07 |
peter |
178 |
A2VConstIter iter(m.find(std::string(user))); |
1478 |
29 May 12 |
peter |
179 |
if (iter==m.end()) |
487 |
13 Oct 07 |
peter |
180 |
throw std::runtime_error(user+std::string(" not found i Stats")); |
487 |
13 Oct 07 |
peter |
181 |
return iter->second; |
487 |
13 Oct 07 |
peter |
182 |
} |
487 |
13 Oct 07 |
peter |
183 |
|
528 |
25 Dec 07 |
peter |
184 |
|
1478 |
29 May 12 |
peter |
185 |
void Stats::ignore_rev(svn_revnum_t rev) |
1478 |
29 May 12 |
peter |
186 |
{ |
1478 |
29 May 12 |
peter |
187 |
ignore_rev_ = rev; |
1478 |
29 May 12 |
peter |
188 |
} |
1478 |
29 May 12 |
peter |
189 |
|
1478 |
29 May 12 |
peter |
190 |
|
1478 |
29 May 12 |
peter |
191 |
const svn_revnum_t& Stats::ignore_rev(void) const |
1478 |
29 May 12 |
peter |
192 |
{ |
1478 |
29 May 12 |
peter |
193 |
return ignore_rev_; |
1478 |
29 May 12 |
peter |
194 |
} |
1478 |
29 May 12 |
peter |
195 |
|
1478 |
29 May 12 |
peter |
196 |
|
529 |
25 Dec 07 |
peter |
197 |
svn_revnum_t Stats::last_changed_rev(void) const |
529 |
25 Dec 07 |
peter |
198 |
{ |
529 |
25 Dec 07 |
peter |
199 |
return last_changed_rev_; |
529 |
25 Dec 07 |
peter |
200 |
} |
529 |
25 Dec 07 |
peter |
201 |
|
529 |
25 Dec 07 |
peter |
202 |
|
589 |
12 Apr 08 |
jari |
203 |
unsigned int Stats::lines(const std::string& user) const |
529 |
25 Dec 07 |
peter |
204 |
{ |
552 |
08 Jan 08 |
peter |
205 |
return get_back(total_stats(), user); |
529 |
25 Dec 07 |
peter |
206 |
} |
529 |
25 Dec 07 |
peter |
207 |
|
529 |
25 Dec 07 |
peter |
208 |
|
529 |
25 Dec 07 |
peter |
209 |
void Stats::load(std::istream& is, Author2Vector& m) |
529 |
25 Dec 07 |
peter |
210 |
{ |
529 |
25 Dec 07 |
peter |
211 |
while (m.size() < authors().size()+1 && is.good()) { |
529 |
25 Dec 07 |
peter |
212 |
std::string name; |
529 |
25 Dec 07 |
peter |
213 |
std::getline(is, name); |
1194 |
03 Oct 10 |
peter |
214 |
SparseVector vec; |
636 |
24 May 08 |
peter |
215 |
std::string line; |
636 |
24 May 08 |
peter |
216 |
std::getline(is, line); |
636 |
24 May 08 |
peter |
217 |
std::stringstream ss(line); |
636 |
24 May 08 |
peter |
218 |
while (ss.good()) { |
636 |
24 May 08 |
peter |
219 |
svn_revnum_t rev=0; |
636 |
24 May 08 |
peter |
220 |
unsigned int count=0; |
636 |
24 May 08 |
peter |
221 |
ss >> rev; |
636 |
24 May 08 |
peter |
222 |
ss >> count; |
649 |
08 Jun 08 |
peter |
223 |
assert(rev<=revision_); |
636 |
24 May 08 |
peter |
224 |
if (!count) |
636 |
24 May 08 |
peter |
225 |
break; |
1194 |
03 Oct 10 |
peter |
226 |
vec.set(rev, count); |
529 |
25 Dec 07 |
peter |
227 |
} |
1194 |
03 Oct 10 |
peter |
228 |
SumVector& sumvec = m[name]; |
1194 |
03 Oct 10 |
peter |
229 |
accumulate(vec, sumvec); |
529 |
25 Dec 07 |
peter |
230 |
} |
529 |
25 Dec 07 |
peter |
231 |
} |
529 |
25 Dec 07 |
peter |
232 |
|
529 |
25 Dec 07 |
peter |
233 |
|
1124 |
07 Jul 10 |
peter |
234 |
svn_revnum_t Stats::load_cache(std::istream& is, bool& latest_ver) |
468 |
30 Aug 07 |
peter |
235 |
{ |
552 |
08 Jan 08 |
peter |
236 |
std::string str; |
552 |
08 Jan 08 |
peter |
237 |
getline(is, str); |
1611 |
12 Feb 23 |
peter |
238 |
if (str == "CACHE FILE VERSION 9") { |
1611 |
12 Feb 23 |
peter |
239 |
latest_ver = true; |
1611 |
12 Feb 23 |
peter |
240 |
return load_cache9(is); |
1611 |
12 Feb 23 |
peter |
241 |
} |
1124 |
07 Jul 10 |
peter |
242 |
if (str == "CACHE FILE VERSION 8") { |
1611 |
12 Feb 23 |
peter |
243 |
latest_ver = false; |
1122 |
07 Jul 10 |
peter |
244 |
return load_cache8(is); |
1124 |
07 Jul 10 |
peter |
245 |
} |
1124 |
07 Jul 10 |
peter |
246 |
latest_ver = false; |
1122 |
07 Jul 10 |
peter |
247 |
if (str == "CACHE FILE VERSION 7") |
1122 |
07 Jul 10 |
peter |
248 |
return load_cache7(is); |
1122 |
07 Jul 10 |
peter |
249 |
|
1122 |
07 Jul 10 |
peter |
250 |
if (str == "CACHE FILE VERSION 6") |
1122 |
07 Jul 10 |
peter |
251 |
std::cout << "cache file is obsolete; " |
1122 |
07 Jul 10 |
peter |
252 |
<< "retrieving statistics from repository.\n"; |
1122 |
07 Jul 10 |
peter |
253 |
return 0; |
1122 |
07 Jul 10 |
peter |
254 |
} |
1122 |
07 Jul 10 |
peter |
255 |
|
1122 |
07 Jul 10 |
peter |
256 |
|
1611 |
12 Feb 23 |
peter |
257 |
svn_revnum_t Stats::load_cache9(std::istream& is) |
1611 |
12 Feb 23 |
peter |
258 |
{ |
1611 |
12 Feb 23 |
peter |
259 |
std::string line; |
1611 |
12 Feb 23 |
peter |
260 |
getline(is, line); |
1611 |
12 Feb 23 |
peter |
261 |
if (line!=config_code()) { |
1611 |
12 Feb 23 |
peter |
262 |
std::cout << "cache file is for different configuration.\n" |
1611 |
12 Feb 23 |
peter |
263 |
<< "config code: '" << config_code() << "'\n" |
1611 |
12 Feb 23 |
peter |
264 |
<< "config code in cache file: '" << line << "'\n" |
1611 |
12 Feb 23 |
peter |
265 |
<< "retrieving statistics from repository.\n"; |
1611 |
12 Feb 23 |
peter |
266 |
return 0; |
1611 |
12 Feb 23 |
peter |
267 |
} |
1611 |
12 Feb 23 |
peter |
268 |
svn_revnum_t rev; |
1611 |
12 Feb 23 |
peter |
269 |
is >> rev; |
1611 |
12 Feb 23 |
peter |
270 |
reset(); |
1611 |
12 Feb 23 |
peter |
271 |
size_t a_size=0; |
1611 |
12 Feb 23 |
peter |
272 |
is >> a_size; |
1611 |
12 Feb 23 |
peter |
273 |
std::string str; |
1611 |
12 Feb 23 |
peter |
274 |
while (authors().size()<a_size && is.good()){ |
1611 |
12 Feb 23 |
peter |
275 |
getline(is, str); |
1611 |
12 Feb 23 |
peter |
276 |
if (str.size()) |
1611 |
12 Feb 23 |
peter |
277 |
add_author(str); |
1611 |
12 Feb 23 |
peter |
278 |
} |
1611 |
12 Feb 23 |
peter |
279 |
getline(is, str); |
1611 |
12 Feb 23 |
peter |
280 |
if (str!=cache_check_str()) { |
1611 |
12 Feb 23 |
peter |
281 |
return 0; |
1611 |
12 Feb 23 |
peter |
282 |
} |
1611 |
12 Feb 23 |
peter |
283 |
for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy, |
1611 |
12 Feb 23 |
peter |
284 |
LineTypeParser::other, LineTypeParser::total}) { |
1611 |
12 Feb 23 |
peter |
285 |
assert(static_cast<size_t>(lt) < stats_.size()); |
1611 |
12 Feb 23 |
peter |
286 |
load(is, stats_[lt]); |
1611 |
12 Feb 23 |
peter |
287 |
getline(is, str); |
1611 |
12 Feb 23 |
peter |
288 |
if (str!=cache_check_str()) { |
1611 |
12 Feb 23 |
peter |
289 |
return 0; |
1611 |
12 Feb 23 |
peter |
290 |
} |
1611 |
12 Feb 23 |
peter |
291 |
} |
1611 |
12 Feb 23 |
peter |
292 |
return rev; |
1611 |
12 Feb 23 |
peter |
293 |
} |
1611 |
12 Feb 23 |
peter |
294 |
|
1611 |
12 Feb 23 |
peter |
295 |
|
1122 |
07 Jul 10 |
peter |
296 |
svn_revnum_t Stats::load_cache8(std::istream& is) |
1122 |
07 Jul 10 |
peter |
297 |
{ |
1122 |
07 Jul 10 |
peter |
298 |
std::string line; |
1122 |
07 Jul 10 |
peter |
299 |
getline(is, line); |
1478 |
29 May 12 |
peter |
300 |
if (line!=config_code()) { |
1122 |
07 Jul 10 |
peter |
301 |
std::cout << "cache file is for different configuration.\n" |
1478 |
29 May 12 |
peter |
302 |
<< "config code: '" << config_code() << "'\n" |
1122 |
07 Jul 10 |
peter |
303 |
<< "config code in cache file: '" << line << "'\n" |
1122 |
07 Jul 10 |
peter |
304 |
<< "retrieving statistics from repository.\n"; |
664 |
13 Jun 08 |
peter |
305 |
return 0; |
1003 |
02 Jan 10 |
peter |
306 |
} |
1122 |
07 Jul 10 |
peter |
307 |
return load_cache7(is); |
1122 |
07 Jul 10 |
peter |
308 |
} |
1122 |
07 Jul 10 |
peter |
309 |
|
1122 |
07 Jul 10 |
peter |
310 |
|
1122 |
07 Jul 10 |
peter |
311 |
svn_revnum_t Stats::load_cache7(std::istream& is) |
1122 |
07 Jul 10 |
peter |
312 |
{ |
482 |
13 Oct 07 |
peter |
313 |
svn_revnum_t rev; |
482 |
13 Oct 07 |
peter |
314 |
is >> rev; |
529 |
25 Dec 07 |
peter |
315 |
reset(); |
468 |
30 Aug 07 |
peter |
316 |
size_t a_size=0; |
468 |
30 Aug 07 |
peter |
317 |
is >> a_size; |
1122 |
07 Jul 10 |
peter |
318 |
std::string str; |
529 |
25 Dec 07 |
peter |
319 |
while (authors().size()<a_size && is.good()){ |
468 |
30 Aug 07 |
peter |
320 |
getline(is, str); |
529 |
25 Dec 07 |
peter |
321 |
if (str.size()) |
529 |
25 Dec 07 |
peter |
322 |
add_author(str); |
468 |
30 Aug 07 |
peter |
323 |
} |
529 |
25 Dec 07 |
peter |
324 |
getline(is, str); |
1611 |
12 Feb 23 |
peter |
325 |
if (str!=cache_check_str7()) { |
664 |
13 Jun 08 |
peter |
326 |
return 0; |
649 |
08 Jun 08 |
peter |
327 |
} |
552 |
08 Jan 08 |
peter |
328 |
for (size_t i=0; i<stats_.size(); ++i){ |
552 |
08 Jan 08 |
peter |
329 |
load(is, stats_[i]); |
552 |
08 Jan 08 |
peter |
330 |
getline(is, str); |
1611 |
12 Feb 23 |
peter |
331 |
if (str!=cache_check_str7()) { |
664 |
13 Jun 08 |
peter |
332 |
return 0; |
649 |
08 Jun 08 |
peter |
333 |
} |
529 |
25 Dec 07 |
peter |
334 |
} |
664 |
13 Jun 08 |
peter |
335 |
return rev; |
468 |
30 Aug 07 |
peter |
336 |
} |
468 |
30 Aug 07 |
peter |
337 |
|
468 |
30 Aug 07 |
peter |
338 |
|
1478 |
29 May 12 |
peter |
339 |
void Stats::map_add(A2VConstIter first1, A2VConstIter last1, |
528 |
25 Dec 07 |
peter |
340 |
Author2Vector& map) |
528 |
25 Dec 07 |
peter |
341 |
{ |
528 |
25 Dec 07 |
peter |
342 |
A2VIter first2(map.begin()); |
528 |
25 Dec 07 |
peter |
343 |
Author2Vector::key_compare compare; |
1478 |
29 May 12 |
peter |
344 |
while ( first1 != last1) { |
528 |
25 Dec 07 |
peter |
// key of first1 less than key of first2 |
528 |
25 Dec 07 |
peter |
346 |
if (first2==map.end() || compare(first1->first,first2->first)) { |
528 |
25 Dec 07 |
peter |
347 |
first2 = map.insert(first2, *first1); |
528 |
25 Dec 07 |
peter |
348 |
++first1; |
528 |
25 Dec 07 |
peter |
349 |
} |
528 |
25 Dec 07 |
peter |
// key of first2 less than key of first1 |
528 |
25 Dec 07 |
peter |
351 |
else if ( compare(first2->first, first1->first)) { |
528 |
25 Dec 07 |
peter |
352 |
++first2; |
528 |
25 Dec 07 |
peter |
353 |
} |
528 |
25 Dec 07 |
peter |
// keys are equivalent |
528 |
25 Dec 07 |
peter |
355 |
else { |
1203 |
05 Oct 10 |
peter |
356 |
first2->second += first1->second; |
528 |
25 Dec 07 |
peter |
357 |
++first1; |
528 |
25 Dec 07 |
peter |
358 |
++first2; |
528 |
25 Dec 07 |
peter |
359 |
} |
528 |
25 Dec 07 |
peter |
360 |
} |
528 |
25 Dec 07 |
peter |
361 |
} |
528 |
25 Dec 07 |
peter |
362 |
|
528 |
25 Dec 07 |
peter |
363 |
|
1194 |
03 Oct 10 |
peter |
364 |
unsigned int Stats::max_element(const SumVector& vec) const |
1003 |
02 Jan 10 |
peter |
365 |
{ |
1478 |
29 May 12 |
peter |
366 |
return std::max_element(vec.begin(), vec.end(), |
1194 |
03 Oct 10 |
peter |
367 |
pair_value_compare<const svn_revnum_t, unsigned int>())->second; |
1003 |
02 Jan 10 |
peter |
368 |
} |
1003 |
02 Jan 10 |
peter |
369 |
|
1003 |
02 Jan 10 |
peter |
370 |
|
664 |
13 Jun 08 |
peter |
371 |
void Stats::parse(const std::string& path, svn_revnum_t rev) |
60 |
16 Jan 06 |
peter |
372 |
{ |
664 |
13 Jun 08 |
peter |
373 |
do_parse(path, rev); |
537 |
27 Dec 07 |
peter |
374 |
calc_total(); |
537 |
27 Dec 07 |
peter |
375 |
calc_all(); |
1478 |
29 May 12 |
peter |
376 |
|
639 |
31 May 08 |
peter |
377 |
assert(total_stats().size()); |
639 |
31 May 08 |
peter |
378 |
assert(code_stats().size()); |
639 |
31 May 08 |
peter |
379 |
assert(comment_or_copy_stats().size()); |
639 |
31 May 08 |
peter |
380 |
assert(other_stats().size()); |
60 |
16 Jan 06 |
peter |
381 |
} |
60 |
16 Jan 06 |
peter |
382 |
|
1026 |
11 Jan 10 |
peter |
383 |
|
454 |
18 Aug 07 |
peter |
384 |
void Stats::print(std::ostream& os) const |
454 |
18 Aug 07 |
peter |
385 |
{ |
1611 |
12 Feb 23 |
peter |
386 |
os << cache_check_str() << "\n"; |
1478 |
29 May 12 |
peter |
387 |
os << config_code() << "\n"; |
529 |
25 Dec 07 |
peter |
388 |
os << last_changed_rev() << " "; |
636 |
24 May 08 |
peter |
389 |
os << authors().size() << "\n"; |
482 |
13 Oct 07 |
peter |
390 |
|
1478 |
29 May 12 |
peter |
391 |
std::copy(authors().begin(), authors().end(), |
454 |
18 Aug 07 |
peter |
392 |
std::ostream_iterator<std::string>(os, "\n")); |
552 |
08 Jan 08 |
peter |
393 |
os << cache_check_str() << "\n"; |
1611 |
12 Feb 23 |
peter |
394 |
for (int lt : {LineTypeParser::code, LineTypeParser::comment_or_copy, |
1611 |
12 Feb 23 |
peter |
395 |
LineTypeParser::other, LineTypeParser::total}) { |
1611 |
12 Feb 23 |
peter |
396 |
assert(static_cast<size_t>(lt) < stats_.size()); |
1611 |
12 Feb 23 |
peter |
397 |
print(os, stats_[lt]); |
552 |
08 Jan 08 |
peter |
398 |
os << cache_check_str() << "\n"; |
552 |
08 Jan 08 |
peter |
399 |
} |
454 |
18 Aug 07 |
peter |
400 |
} |
454 |
18 Aug 07 |
peter |
401 |
|
454 |
18 Aug 07 |
peter |
402 |
|
529 |
25 Dec 07 |
peter |
403 |
void Stats::print(std::ostream& os, const Author2Vector& m) const |
529 |
25 Dec 07 |
peter |
404 |
{ |
529 |
25 Dec 07 |
peter |
405 |
for (A2VConstIter i(m.begin()); i!=m.end(); ++i){ |
529 |
25 Dec 07 |
peter |
406 |
os << i->first << "\n"; |
1208 |
07 Oct 10 |
peter |
407 |
const SumVector& vec = i->second; |
1208 |
07 Oct 10 |
peter |
408 |
if (vec.size()) { |
1208 |
07 Oct 10 |
peter |
409 |
SumVector::const_iterator v = vec.begin(); |
1208 |
07 Oct 10 |
peter |
410 |
if (v->second) |
1208 |
07 Oct 10 |
peter |
411 |
os << v->first << " " << v->second << " "; |
1208 |
07 Oct 10 |
peter |
412 |
++v; |
1208 |
07 Oct 10 |
peter |
413 |
SumVector::const_iterator prev = vec.begin(); |
1208 |
07 Oct 10 |
peter |
414 |
while (v != vec.end()) { |
1208 |
07 Oct 10 |
peter |
415 |
assert(vec[v->first - 1] == prev->second); |
1208 |
07 Oct 10 |
peter |
// FIXME: this if should not be needed if SumVector was |
1208 |
07 Oct 10 |
peter |
// truly sparse and collapsed when possible. |
1208 |
07 Oct 10 |
peter |
418 |
if (v->second != prev->second) |
1208 |
07 Oct 10 |
peter |
419 |
os << v->first << " " << v->second - prev->second << " "; |
1208 |
07 Oct 10 |
peter |
420 |
++v; |
1208 |
07 Oct 10 |
peter |
421 |
++prev; |
636 |
24 May 08 |
peter |
422 |
} |
636 |
24 May 08 |
peter |
423 |
} |
636 |
24 May 08 |
peter |
424 |
os << "\n"; |
529 |
25 Dec 07 |
peter |
425 |
} |
529 |
25 Dec 07 |
peter |
426 |
} |
529 |
25 Dec 07 |
peter |
427 |
|
487 |
13 Oct 07 |
peter |
428 |
void Stats::reset(void) |
454 |
18 Aug 07 |
peter |
429 |
{ |
552 |
08 Jan 08 |
peter |
430 |
for (size_t i=0; i<stats_.size(); ++i){ |
552 |
08 Jan 08 |
peter |
431 |
stats_[i].clear(); |
1194 |
03 Oct 10 |
peter |
432 |
stats_[i]["all"].resize(revision()+1); |
552 |
08 Jan 08 |
peter |
433 |
} |
529 |
25 Dec 07 |
peter |
434 |
authors_.clear(); |
487 |
13 Oct 07 |
peter |
435 |
} |
487 |
13 Oct 07 |
peter |
436 |
|
487 |
13 Oct 07 |
peter |
437 |
|
1194 |
03 Oct 10 |
peter |
438 |
void Stats::resize(svn_revnum_t rev) |
1194 |
03 Oct 10 |
peter |
439 |
{ |
1194 |
03 Oct 10 |
peter |
// set size on vectors |
1194 |
03 Oct 10 |
peter |
441 |
for (size_t i=0; i<stats_.size(); ++i) { |
1194 |
03 Oct 10 |
peter |
442 |
for (A2VIter iter=stats_[i].begin(); iter!=stats_[i].end(); ++iter) { |
1194 |
03 Oct 10 |
peter |
443 |
iter->second.resize(rev); |
1194 |
03 Oct 10 |
peter |
444 |
} |
1194 |
03 Oct 10 |
peter |
445 |
} |
1194 |
03 Oct 10 |
peter |
446 |
} |
1194 |
03 Oct 10 |
peter |
447 |
|
1194 |
03 Oct 10 |
peter |
448 |
|
1478 |
29 May 12 |
peter |
449 |
svn_revnum_t Stats::revision(void) const |
1478 |
29 May 12 |
peter |
450 |
{ |
1478 |
29 May 12 |
peter |
451 |
return revision_; |
1194 |
03 Oct 10 |
peter |
452 |
} |
1194 |
03 Oct 10 |
peter |
453 |
|
1194 |
03 Oct 10 |
peter |
454 |
|
528 |
25 Dec 07 |
peter |
455 |
Stats& Stats::operator+=(const Stats& rhs) |
528 |
25 Dec 07 |
peter |
456 |
{ |
528 |
25 Dec 07 |
peter |
457 |
revision_ = std::max(revision_, rhs.revision_); |
528 |
25 Dec 07 |
peter |
458 |
last_changed_rev_ = std::max(last_changed_rev_, rhs.last_changed_rev_); |
528 |
25 Dec 07 |
peter |
459 |
add_authors(rhs.authors().begin(), rhs.authors().end()); |
552 |
08 Jan 08 |
peter |
460 |
assert(stats_.size()==rhs.stats_.size()); |
552 |
08 Jan 08 |
peter |
461 |
for (size_t i=0; i<stats_.size(); ++i) |
552 |
08 Jan 08 |
peter |
462 |
map_add(rhs.stats_[i].begin(), rhs.stats_[i].end(), stats_[i]); |
1478 |
29 May 12 |
peter |
463 |
|
528 |
25 Dec 07 |
peter |
464 |
return *this; |
528 |
25 Dec 07 |
peter |
465 |
} |
454 |
18 Aug 07 |
peter |
466 |
|
1478 |
29 May 12 |
peter |
467 |
|
1478 |
29 May 12 |
peter |
468 |
size_t Stats::operator()(int linetype, std::string author, |
642 |
31 May 08 |
peter |
469 |
svn_revnum_t rev) const |
552 |
08 Jan 08 |
peter |
470 |
{ |
1611 |
12 Feb 23 |
peter |
471 |
assert(linetype == LineTypeParser::code || |
1611 |
12 Feb 23 |
peter |
472 |
linetype == LineTypeParser::comment_or_copy || |
1611 |
12 Feb 23 |
peter |
473 |
linetype == LineTypeParser::other || |
1611 |
12 Feb 23 |
peter |
474 |
linetype == LineTypeParser::total); |
1611 |
12 Feb 23 |
peter |
475 |
|
552 |
08 Jan 08 |
peter |
476 |
assert(linetype<=LineTypeParser::total); |
636 |
24 May 08 |
peter |
477 |
assert(static_cast<size_t>(linetype) < stats_.size()); |
642 |
31 May 08 |
peter |
478 |
assert(rev>=0); |
552 |
08 Jan 08 |
peter |
479 |
A2VConstIter i = stats_[linetype].find(author); |
637 |
24 May 08 |
peter |
480 |
if (i==stats_[linetype].end()){ |
637 |
24 May 08 |
peter |
481 |
std::stringstream msg; |
1478 |
29 May 12 |
peter |
482 |
msg << __FILE__ << ": author: " << author << " does not exist"; |
637 |
24 May 08 |
peter |
483 |
throw std::runtime_error(msg.str()); |
637 |
24 May 08 |
peter |
484 |
} |
1194 |
03 Oct 10 |
peter |
485 |
assert(rev <= revision()); |
1194 |
03 Oct 10 |
peter |
// assert(rev < static_cast<svn_revnum_t>(i->second.size())); |
552 |
08 Jan 08 |
peter |
487 |
return i->second[rev]; |
552 |
08 Jan 08 |
peter |
488 |
} |
454 |
18 Aug 07 |
peter |
489 |
|
149 |
12 Aug 06 |
jari |
490 |
}} // end of namespace svndigest and namespace theplu |