source: trunk/lib/Stats.cc @ 72

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

prefer stl algorithms...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.4 KB
Line 
1//$Id: Stats.cc 72 2006-03-02 22:16:24Z 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)
69  {
70    // Calling svn blame
71    if (blame(path))
72      return true;
73
74    // Check if file is binary
75    std::ifstream is("svnstat.tmp");
76    std::string line;
77    getline(is,line,' ');
78    if (line==std::string("Skipping")){
79      getline(is,line,' ');
80      if (line==std::string("binary")){
81        is.close();
82        return true;
83      }
84    }
85    is.close();
86
87    is.open("svnstat.tmp");
88    while (getline(is,line, '\n')){
89      if (!line.size()) // skip empty line
90        continue;
91      std::stringstream ss(line);
92      u_int revision;
93      std::string user;
94      ss >> revision;
95      ss >> user;
96      add(user, revision);
97    }
98    is.close();
99    return false;
100  }
101
102
103  std::string Stats::plot(const std::string& name) const
104  {
105    std::string cmd=std::string("set term png; set output '")+name+"'";
106    gnuplot_pipe_.command(cmd);
107    gnuplot_pipe_.command("set key left Left reverse");
108    std::vector<double> x=accumulated();   
109    std::stringstream sa;
110    sa << x.back() << " total";
111    gnuplot_pipe_.linetitle(sa.str());
112    gnuplot_pipe_.date_plot(x);
113    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
114      x=accumulated(i->first);
115      std::stringstream s;
116      s << x.back() << " " << i->first;
117      gnuplot_pipe_.linetitle(s.str());
118      gnuplot_pipe_.date_replot(x);
119    }
120
121    // Jari, must rewrite output once since the replots above are not
122    // added to the plot. Rather, the plot only contains the result
123    // from the first 'plot' call.
124    gnuplot_pipe_.command(cmd);
125    gnuplot_pipe_.command("replot");
126    return name;
127  }
128
129  Stats& Stats::operator+=(const Stats& other)
130  {
131    for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
132    {
133      std::pair<MapIter_,bool> result = map_.insert(*o_i);
134      if (!result.second)
135        map_[(*(result.first)).first] = 
136          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
137 
138    }
139    return *this;
140  }
141
142}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.