source: trunk/lib/Stats.h @ 1194

Last change on this file since 1194 was 1194, checked in by Peter Johansson, 11 years ago

refs #475. First version using Sparse Vector class. This change is obviously quite invasive and thus the size of this commit is larger than what is preferred. I've tried to limit as much as possible and left optimization and style issues behind with a note 'FIXME'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.2 KB
Line 
1#ifndef _theplu_svndigest_stats_
2#define _theplu_svndigest_stats_
3
4// $Id: Stats.h 1194 2010-10-03 23:39:12Z peter $
5
6/*
7  Copyright (C) 2005 Peter Johansson
8  Copyright (C) 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
9  Copyright (C) 2010 Peter Johansson
10
11  This file is part of svndigest, http://dev.thep.lu.se/svndigest
12
13  svndigest is free software; you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation; either version 3 of the License, or
16  (at your option) any later version.
17
18  svndigest is distributed in the hope that it will be useful, but
19  WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  General Public License for more details.
22
23  You should have received a copy of the GNU General Public License
24  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
25*/
26
27#include "LineTypeParser.h"
28#include "Vector.h"
29
30#include <subversion-1/svn_types.h>
31
32#include <map>
33#include <istream>
34#include <set>
35#include <string>
36#include <vector>
37
38namespace theplu{
39namespace svndigest{
40
41  ///
42  /// Class taking care of statistics from svn.
43  ///
44  class Stats
45  {
46  public:
47    ///
48    /// @brief Default Constructor
49    ///
50    explicit Stats(const std::string& path);
51
52    /**
53       \brief Destructor
54    */
55    virtual ~Stats(void);
56
57    ///
58    /// @brief adding \a n line(s) to \a user from \a revision to the stats
59    ///
60    //    void add(const std::string& user, svn_revnum_t revision,
61    //       LineTypeParser::line_type, unsigned int n=1);
62
63    ///
64    /// @return set of authors
65    ///
66    const std::set<std::string>& authors(void) const;
67
68    ///
69    /// \return number of code lines for \a user for latest revision.
70    ///
71    unsigned int code(const std::string& user="all") const; 
72
73
74    ///
75    /// \return number of comments lines for \a user for latest revision.
76    ///
77    unsigned int comments(const std::string& user="all") const; 
78
79    ///
80    /// \return number of empty lines for \a user for latest revision.
81    ///
82    unsigned int empty(const std::string& user="all") const; 
83
84    ///
85    /// \return revison node was modified
86    ///
87    svn_revnum_t last_changed_rev(void) const;
88
89    ///
90    /// \return number of lines for \a user for latest revision
91    ///
92    unsigned int lines(const std::string& user="all") const; 
93
94    /**
95       Load object from a stream.
96
97       \a latest_ver is set to true if cache_file is latest version;
98       otherwise it is set to false.
99
100       \return revision the cache represents - 0 if failed
101     */
102    svn_revnum_t load_cache(std::istream&, bool& latest_ver);
103
104    /**
105       Do the parsing for \a path. Revisions from \a rev will be parsed.
106    */
107    void parse(const std::string& path, svn_revnum_t rev=0);
108
109    ///
110    /// Create statistics graph.
111    ///
112    std::string plot(const std::string&, const std::string&) const;
113
114    ///
115    /// Plotting code, comment, other, and total in same plot (for
116    /// 'all' not individual authors).
117    ///
118    void plot_summary(const std::string& output) const;
119
120    /**
121       Send Stats to a stream.
122     */
123    void print(std::ostream&) const;
124
125    ///
126    /// @brief Clear all statistics
127    ///
128    void reset(void); 
129
130    /**
131       set vectors in stats_ to size \a rev
132    */
133    void resize(svn_revnum_t rev);
134
135    ///
136    /// \return latest revision for whole project
137    ///
138    svn_revnum_t revision(void) const;
139
140    /**
141       \return resulting Stats
142    */
143    Stats& operator+=(const Stats&);
144
145    /**
146       \return number of lines for \a author and \a linetype from
147       revision \a rev.
148
149       \throw if \a author does not exist
150     */
151    size_t operator()(int linetype, std::string author, svn_revnum_t rev) const;
152
153  protected:
154    typedef std::map<std::string, SumVector> Author2Vector;
155    typedef Author2Vector::iterator A2VIter;
156    typedef Author2Vector::const_iterator A2VConstIter;
157
158    std::vector<Author2Vector> stats_; // from linetype to a2v
159
160    /**
161     */
162    void add(const std::vector<std::map<std::string, SparseVector> >& data);
163
164    /**
165       Calculate accumalated statistics for fundamental statistics,
166       i.e., code, comment, empty, and copyright for each author.
167       \see accumulate
168     */
169    //    void accumulate_stats(svn_revnum_t rev=1);
170    void add_author(std::string);
171    void add_authors(std::set<std::string>::const_iterator, 
172                     std::set<std::string>::const_iterator);
173
174    // references to data
175    inline Author2Vector& code_stats(void) 
176    { return stats_[LineTypeParser::code]; }
177    inline Author2Vector& comment_stats(void) 
178    { return stats_[LineTypeParser::comment]; }
179    inline Author2Vector& copyright_stats(void) 
180    { return stats_[LineTypeParser::copyright]; }
181    inline Author2Vector& other_stats(void) 
182    { return stats_[LineTypeParser::other]; }
183    inline Author2Vector& comment_or_copy_stats(void) 
184    { return stats_[LineTypeParser::comment_or_copy]; }
185    inline Author2Vector& total_stats(void) 
186    { return stats_[LineTypeParser::total]; }
187
188    // const references to data
189    inline const Author2Vector& code_stats(void) const
190    { return stats_[LineTypeParser::code]; }
191    inline const Author2Vector& comment_stats(void) const
192    { return stats_[LineTypeParser::comment]; }
193    inline const Author2Vector& copyright_stats(void) const
194    { return stats_[LineTypeParser::copyright]; }
195    inline const Author2Vector& other_stats(void) const
196    { return stats_[LineTypeParser::other]; }
197    inline const Author2Vector& comment_or_copy_stats(void) const
198    { return stats_[LineTypeParser::comment_or_copy]; }
199    inline const Author2Vector& total_stats(void) const
200    { return stats_[LineTypeParser::total]; }
201
202    /**
203       add range [\a first, \a last) to \a map
204     */
205    void map_add(Author2Vector::const_iterator first, 
206                 Author2Vector::const_iterator last,
207                 Author2Vector& map);
208
209    std::set<std::string> authors_;
210
211    const SumVector& get_vector(const Author2Vector&, 
212                                const std::string& user) const;
213  private:
214    /// one liner used in cache file to validate that cache file was
215    /// created current configuration
216    std::string config_code_;
217
218    void add(SumVector& vec, svn_revnum_t rev, unsigned int n);
219    /**
220       \a vec is resized to revision().
221       vec is accumulated such that
222       vec[rev] = vec[rev-1] + vec[rev]
223       vec[rev+1] = vec[rev] + vec[rev+1]
224       et cetera
225     */
226    //    void accumulate(std::vector<unsigned int>& vec,
227    //              svn_revnum_t rev=1) const;
228    //    void add(std::vector<unsigned int>& vec, unsigned int rev, bool x,
229    //       unsigned int n);
230
231    /**
232       Parse statistics for fundamental categories, i.e., code,
233       comment, empty, and copyright for each author. Ignore revisions
234       earlier than \a first_rev.
235     */
236    virtual void do_parse(const std::string&, svn_revnum_t first_rev)=0;
237   
238    /// load cache file version 7
239    svn_revnum_t load_cache7(std::istream&);
240    /// load cache file version 8
241    svn_revnum_t load_cache8(std::istream&);
242
243    /**
244       called from plot(2)
245     */
246    // FIXME: why should Stats know about plotting?
247    void plot(const std::string& basename, const std::string& linetype,
248              const std::string& format) const;
249
250    /**
251       called from plot_summary(1)
252     */
253    // FIXME: why should Stats know about plotting?
254    void plot_summary(const std::string& basename, 
255                      const std::string& format) const;
256
257    // Change this string if cache format is changed in such a way
258    // that all old cache files are obsolete.
259    inline std::string cache_check_str(void) const 
260    {return "CACHE FILE VERSION 7";} 
261
262    void calc_all(void);
263    void calc_comment_or_copy(void);
264    void calc_total(void);
265    unsigned int get_back(const Author2Vector&, std::string user) const;
266    void load(std::istream& is, Author2Vector& m);
267    /**
268       Finds the largets element by iterating through the entire
269       vector. Inherited classes should implement their own version
270       when it is possible to get the largest element in faster than
271       in linear time.
272
273       \return the largest largest element in \a v.
274    */
275    virtual unsigned int max_element(const SumVector& v) const; 
276
277    void print(std::ostream& os, const Author2Vector& m) const;
278
279    svn_revnum_t revision_; // Should be the latest revision for whole project
280    svn_revnum_t last_changed_rev_; // Should be the latest revision for file
281
282    // using compiler generated copy constructor
283    //Stats(const Stats&);
284    // no assignment
285    Stats& operator=(const Stats&);
286
287  };
288}} // end of namespace svndigest end of namespace theplu
289
290#endif
Note: See TracBrowser for help on using the repository browser.