source: trunk/lib/Stats.cc @ 74

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

Improved web presentation. Y axises normalized, ticket ticket:15 resolved.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.6 KB
Line 
1//$Id: Stats.cc 74 2006-03-07 15:46:59Z 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> x=accumulated();   
112    std::stringstream sa;
113    sa << x.back() << " total";
114    double yrange_max=1.03*x.back()+1;
115    gp->yrange(yrange_max);
116    gp->linetitle(sa.str());
117    gp->linestyle("steps 1");
118    gp->plot(x);
119    size_t plotno=1;
120    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
121      std::stringstream s0;
122      s0 << "set key height " << 2*plotno;
123      gp->command(s0.str());
124      x=accumulated(i->first);
125      std::stringstream s;
126      s << x.back() << " " << i->first;
127      gp->yrange(yrange_max);
128      gp->linetitle(s.str());
129      // Jari, reuse the stream above
130      std::stringstream s2;
131      s2 << "steps " << ++plotno;
132      gp->linestyle(s2.str());
133      gp->plot(x);
134    }
135    gp->command("unset multiplot");
136    gp->yrange();
137
138    return name;
139  }
140
141  Stats& Stats::operator+=(const Stats& other)
142  {
143    for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
144    {
145      std::pair<MapIter_,bool> result = map_.insert(*o_i);
146      if (!result.second)
147        map_[(*(result.first)).first] = 
148          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
149 
150    }
151    return *this;
152  }
153
154}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.