source: trunk/lib/Stats.cc @ 41

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

inserted zeros in vectors returned from Stats::accumulated
so they are equally sized.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.1 KB
Line 
1//$Id: Stats.cc 41 2006-01-13 16:41:57Z peter $
2
3#include "Stats.h"
4#include "Gnuplot.h"
5#include "utility.h"
6
7#include <cstdio>
8#include <fstream>
9
10#include <algorithm>
11#include <map>
12#include <numeric>
13#include <sstream>
14#include <string>
15#include <utility>
16#include <vector>
17
18#include <iostream>
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    if (map_.empty())
29      return std::vector<double>();
30
31    // sum of all users
32    std::vector<u_int> sum(latest_revision_+1,0);
33    sum=std::accumulate(map_.begin(), map_.end(), sum,
34                        PairValuePlus<std::string,u_int>());
35
36    // calculate accumulated sum
37    std::vector<double> accum(sum.size());
38    std::partial_sum(sum.begin(),sum.end(),accum.begin());   
39    return accum;
40  }
41
42  std::vector<double> Stats::accumulated(const std::string& user) const
43  {
44    if (!map_.count(user))
45      return std::vector<double>();
46    std::vector<u_int> vec=(map_.find(user))->second;
47 
48    vec.reserve(latest_revision_+1);
49    if (vec.size() < latest_revision_+1)
50      vec.insert(vec.end(), latest_revision_+1-vec.size(), 0);
51
52    std::vector<double> accum(vec.size());
53    std::partial_sum(vec.begin(),vec.end(),accum.begin());
54    return accum;
55  }
56
57  void Stats::add(const std::string& user, const u_int& rev)
58  {
59    std::vector<u_int> vec = map_[user];
60    if (vec.size() < rev+1){
61      u_int i=vec.size();
62      vec.resize(rev+1);
63      for (; i<rev; i++)
64        vec[i]=0;
65      vec[rev]=1;
66      latest_revision_ = std::max(latest_revision_,rev);
67    }
68    else
69      vec[rev]++;
70    map_[user]=vec;
71  }
72
73  std::string Stats::plot(void) const
74  {
75    char name[]="svnstatXXXXXX";
76    if (!strlen(mktemp(name))) {
77      std::cerr << "Failed to get unique filename: " << name << std::endl;
78      exit(-1);
79    }
80    std::string cmd=std::string("set term png; set output '")+name+".png'";
81    gnuplot_pipe_.command(cmd);
82    gnuplot_pipe_.command("set key left Left reverse");
83    std::vector<double> x=accumulated();
84    std::stringstream sa;
85    sa << x.back() << " total";
86    gnuplot_pipe_.linetitle(sa.str());
87    gnuplot_pipe_.plot(x);
88    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
89      x=accumulated(i->first);
90      std::stringstream s;
91      s << x.back() << " " << i->first;
92      gnuplot_pipe_.linetitle(s.str());
93      gnuplot_pipe_.replot(x);
94    }
95
96    // Jari, must rewrite output once since the replots above are not
97    // added to the plot. Rather, the plot only contains the result
98    // from the first 'plot' call.
99    gnuplot_pipe_.command(cmd);
100    gnuplot_pipe_.command("replot");
101    return std::string(name)+".png";
102  }
103
104  void Stats::print(std::ostream& os) const
105  {
106    os << "<p><img src='" << plot() << "' alt='[svnstat plot]' border=0></p>\n";
107  }
108
109  Stats& Stats::operator+=(const Stats& other)
110  {
111    for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
112    {
113      std::pair<MapIter_,bool> result = map_.insert(*o_i);
114      if (!result.second)
115        map_[(*(result.first)).first] = 
116          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
117 
118    }
119    return *this;
120  }
121
122}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.