source: trunk/lib/Stats.cc @ 77

Last change on this file since 77 was 77, checked in by Jari Häkkinen, 18 years ago

Fixed ticket:16, removal of multiple stringstreams in Stats::plot.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.6 KB
Line 
1//$Id: Stats.cc 77 2006-03-09 23:47:22Z jari $
2
3#include "Stats.h"
4#include "GnuplotFE.h"
5#include "utility.h"
6
7#include <algorithm>
8#include <cassert>
9#include <cstdlib>
10#include <fstream>
11#include <iostream>
12#include <map>
13#include <numeric>
14#include <sstream>
15#include <string>
16#include <unistd.h>
17#include <utility>
18#include <vector>
19
20
21namespace theplu{
22namespace svnstat{
23
24  u_int Stats::latest_revision_=0;
25
26  std::vector<u_int> 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<u_int> 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<u_int> Stats::accumulated(const std::string& user) const
41  {
42    if (!map_.count(user))
43      return std::vector<u_int>();
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<u_int> 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    GnuplotFE* gp=GnuplotFE::instance();
107    gp->command(cmd);
108    gp->command("set key default");
109    gp->command("set key left Left reverse");
110    gp->command("set multiplot");
111    std::vector<u_int> total=accumulated();   
112    double yrange_max=1.03*total.back()+1;
113    gp->yrange(yrange_max);
114    size_t plotno=1;
115    std::stringstream ss;
116    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
117      ss.str("");
118      ss << "set key height " << 2*plotno;
119      gp->command(ss.str());
120      std::vector<u_int> x=accumulated(i->first);
121      ss.str("");
122      ss << x.back() << " " << i->first;
123      gp->yrange(yrange_max);
124      gp->linetitle(ss.str());
125      ss.str("");
126      ss << "steps " << ++plotno;
127      gp->linestyle(ss.str());
128      gp->plot(x);
129    }
130    ss.str("");
131    ss << total.back() << " total";
132    gp->command("set key height 0");
133    gp->linetitle(ss.str());
134    gp->linestyle("steps 1");
135    gp->plot(total);
136
137    gp->command("unset multiplot");
138    gp->yrange();
139
140    return name;
141  }
142
143  Stats& Stats::operator+=(const Stats& other)
144  {
145    for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
146    {
147      std::pair<MapIter_,bool> result = map_.insert(*o_i);
148      if (!result.second)
149        map_[(*(result.first)).first] = 
150          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
151 
152    }
153    return *this;
154  }
155
156}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.