source: trunk/lib/Stats.cc @ 101

Last change on this file since 101 was 101, checked in by Peter Johansson, 15 years ago

closes #28 #18 and added some lippstick to the node daughters table output

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.7 KB
Line 
1// $Id: Stats.cc 101 2006-06-22 09:00:06Z peter $
2
3/*
4  Copyright (C) 2005 Peter Johansson
5  Copyright (C) 2006 Jari Häkkinen, Peter Johansson
6
7  This file is part of svnstat, http://lev.thep.lu.se/trac/svnstat
8
9  svnstat is free software; you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13
14  svnstat is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22  02111-1307, USA.
23*/
24
25#include "Stats.h"
26#include "GnuplotFE.h"
27#include "utility.h"
28
29#include <algorithm>
30#include <cassert>
31#include <cstdlib>
32#include <fstream>
33#include <iostream>
34#include <map>
35#include <numeric>
36#include <sstream>
37#include <string>
38#include <unistd.h>
39#include <utility>
40#include <vector>
41
42
43namespace theplu{
44namespace svnstat{
45
46
47  Stats::Stats(const std::string& path)
48  {
49    // Make sure latest revision is set properly
50    std::map<std::string,std::string> svn_info = info(path);
51    std::stringstream ss;
52    ss << (svn_info.count("Revision") ? svn_info["Revision"] : "0");
53    ss >> latest_revision_;
54  }
55
56
57  std::vector<u_int> Stats::accumulated(void) const
58  {
59    // sum of all users
60    std::vector<u_int> sum(latest_revision_+1, 0);
61    sum=std::accumulate(map_.begin(), map_.end(), sum,
62                        PairValuePlus<std::string,u_int>());
63
64    // calculate accumulated sum
65    std::vector<u_int> accum(sum.size());
66    std::partial_sum(sum.begin(),sum.end(),accum.begin());
67    assert(sum.size()==accum.size());
68    return accum;
69  }
70
71  std::vector<u_int> Stats::accumulated(const std::string& user) const
72  {
73    if (!map_.count(user))
74      return std::vector<u_int>();
75    std::vector<u_int> vec=(map_.find(user))->second;
76 
77    if (vec.size() < latest_revision_+1)
78      vec.insert(vec.end(), latest_revision_+1-vec.size(), 0);
79
80    std::vector<u_int> accum(vec.size());
81    std::partial_sum(vec.begin(),vec.end(),accum.begin());
82    return accum;
83  }
84
85  void Stats::add(const std::string& user, const u_int& rev)
86  {
87    std::vector<u_int>* vec = &(map_[user]);
88    if (vec->size() < rev+1){
89      vec->reserve(latest_revision_ + 1);
90      vec->insert(vec->end(), rev - vec->size(),0);
91      vec->push_back(1);
92    }
93    else
94      (*vec)[rev]++;
95  }
96
97
98  bool Stats::parse(const std::string& path)
99  {
100    // Calling svn blame
101    if (blame(path))
102      return true;
103
104    // Check if file is binary
105    std::ifstream is("svnstat.tmp");
106    std::string line;
107    getline(is,line,' ');
108    if (line==std::string("Skipping")){
109      getline(is,line,' ');
110      if (line==std::string("binary")){
111        is.close();
112        return true;
113      }
114    }
115    is.close();
116
117    is.open("svnstat.tmp");
118    while (getline(is,line, '\n')){
119      if (!line.size()) // skip empty line
120        continue;
121      std::stringstream ss(line);
122      u_int revision;
123      std::string user;
124      ss >> revision;
125      ss >> user;
126      add(user, revision);
127    }
128    is.close();
129    return false;
130  }
131
132
133  std::string Stats::plot(const std::string& filename,
134                          const std::string& title) const
135  {
136    GnuplotFE* gp=GnuplotFE::instance();
137    gp->command(std::string("set term png; set output '")+filename+"'");
138    gp->command(std::string("set title '")+title+"'");
139    gp->command("set key default");
140    gp->command("set key left Left reverse");
141    gp->command("set multiplot");
142    std::vector<u_int> total=accumulated();   
143    double yrange_max=1.03*total.back()+1;
144    gp->yrange(yrange_max);
145    size_t plotno=1;
146    std::stringstream ss;
147    for (MapConstIter_ i= map_.begin(); i != map_.end(); i++) {
148      ss.str("");
149      ss << "set key height " << 2*plotno;
150      gp->command(ss.str());
151      std::vector<u_int> x=accumulated(i->first);
152      ss.str("");
153      ss << x.back() << " " << i->first;
154      gp->yrange(yrange_max);
155      gp->linetitle(ss.str());
156      ss.str("");
157      ss << "steps " << ++plotno;
158      gp->linestyle(ss.str());
159      gp->plot(x);
160    }
161    ss.str("");
162    ss << total.back() << " total";
163    gp->command("set key height 0");
164    gp->linetitle(ss.str());
165    gp->linestyle("steps 1");
166    gp->plot(total);
167
168    gp->command("unset multiplot");
169    gp->yrange();
170
171    return filename;
172  }
173
174  Stats& Stats::operator+=(const Stats& other)
175  {
176    for (MapConstIter_ o_i= other.map_.begin(); o_i != other.map_.end(); ++o_i)
177    {
178      std::pair<MapIter_,bool> result = map_.insert(*o_i);
179      if (!result.second)
180        map_[(*(result.first)).first] = 
181          VectorPlus<u_int>()( (*(result.first)).second, (*o_i).second );
182 
183    }
184    return *this;
185  }
186
187}} // end of namespace svnstat and namespace theplu
Note: See TracBrowser for help on using the repository browser.