source: trunk/lib/Stats.cc @ 65

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

corrected includes

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