source: trunk/lib/Stats.cc @ 63

Last change on this file since 63 was 63, checked in by Peter Johansson, 16 years ago

Fixed problem with mapping revison to date. Removed mkstemps. name of
png files are now in line with their html file name. Binary works on
svnstat, but is asserted on c++_tools.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.7 KB
Line 
1//$Id: Stats.cc 63 2006-01-19 23:07:36Z peter $
2
3#include "Stats.h"
4#include "Gnuplot.h"
5#include "utility.h"
6
7#include <algorithm>
8#include <cstdlib>
9#include <iostream>
10#include <map>
11#include <numeric>
12#include <sstream>
13#include <string>
14#include <unistd.h>
15#include <utility>
16#include <vector>
17
18
19namespace theplu{
20namespace svnstat{
21
22  Gnuplot Stats::gnuplot_pipe_;
23  u_int Stats::latest_revision_=0;
24
25  std::vector<double> Stats::accumulated(void) const
26  {
27    // sum of all users
28    std::vector<u_int> sum(latest_revision_+1, 0);
29    sum=std::accumulate(map_.begin(), map_.end(), sum,
30                        PairValuePlus<std::string,u_int>());
31
32    // calculate accumulated sum
33    std::vector<double> accum(sum.size());
34    std::partial_sum(sum.begin(),sum.end(),accum.begin());
35    assert(sum.size()==accum.size());
36    return accum;
37  }
38
39  std::vector<double> Stats::accumulated(const std::string& user) const
40  {
41    if (!map_.count(user))
42      return std::vector<double>();
43    std::vector<u_int> vec=(map_.find(user))->second;
44 
45    if (vec.size() < latest_revision_+1)
46      vec.insert(vec.end(), latest_revision_+1-vec.size(), 0);
47
48    std::vector<double> accum(vec.size());
49    std::partial_sum(vec.begin(),vec.end(),accum.begin());
50    return accum;
51  }
52
53  void Stats::add(const std::string& user, const u_int& rev)
54  {
55    std::vector<u_int>* vec = &(map_[user]);
56    if (vec->size() < rev+1){
57      vec->reserve(rev+1);
58      vec->insert(vec->end(), rev - vec->size(),0);
59      vec->push_back(1);
60      latest_revision_ = std::max(latest_revision_,rev);
61    }
62    else
63      (*vec)[rev]++;
64  }
65
66
67  bool Stats::parse(const std::string& path, const bool binary)
68  {
69    if (binary){
70      std::map<std::string,std::string> svn_info = info(path);
71      std::stringstream ss(svn_info["Last Changed Rev"]);
72      u_int revision;
73      ss >> revision;
74      add(svn_info["Last Changed Author"],revision);
75      return true;
76    }
77
78    // Calling svn blame
79    if (blame(path))
80      return true;
81
82    // Check if file is binary
83    std::ifstream is("svnstat.tmp");
84    std::string line;
85    getline(is,line,' ');
86    if (line==std::string("Skipping")){
87      getline(is,line,' ');
88      if (line==std::string("binary")){
89        is.close();
90        return parse(path,true);
91      }
92    }
93    is.close();
94
95    is.open("svnstat.tmp");
96    while (getline(is,line, '\n')){
97      if (!line.size()) // skip empty line
98        continue;
99      std::stringstream ss(line);
100      u_int revision;
101      std::string user;
102      ss >> revision;
103      ss >> user;
104      add(user, revision);
105    }
106    is.close();
107    return false;
108  }
109
110
111  std::string Stats::plot(const std::string& name) const
112  {
113    std::string cmd=std::string("set term png; set output '")+name+"'";
114    gnuplot_pipe_.command(cmd);
115    gnuplot_pipe_.command("set key left Left reverse");
116    std::vector<double> x=accumulated();   
117    std::stringstream sa;
118    sa << x.back() << " total";
119    gnuplot_pipe_.linetitle(sa.str());
120    gnuplot_pipe_.date_plot(x);
121    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
122      x=accumulated(i->first);
123      std::stringstream s;
124      s << x.back() << " " << i->first;
125      gnuplot_pipe_.linetitle(s.str());
126      gnuplot_pipe_.date_replot(x);
127    }
128
129    // Jari, must rewrite output once since the replots above are not
130    // added to the plot. Rather, the plot only contains the result
131    // from the first 'plot' call.
132    gnuplot_pipe_.command(cmd);
133    gnuplot_pipe_.command("replot");
134    return name;
135  }
136
137  Stats& Stats::operator+=(const Stats& other)
138  {
139    for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
140    {
141      std::pair<MapIter_,bool> result = map_.insert(*o_i);
142      if (!result.second)
143        map_[(*(result.first)).first] = 
144          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
145 
146    }
147    return *this;
148  }
149
150}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.