Changeset 528


Ignore:
Timestamp:
Dec 25, 2007, 11:23:04 AM (13 years ago)
Author:
Peter Johansson
Message:

fixes #280 - keep on refactoring of Stats class

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/ClassicStats.cc

    r519 r528  
    5555  }
    5656
    57 
     57  ClassicStats::ClassicStats(const ClassicStats& other)
     58  : Stats(other)
     59  {
     60  }
     61
     62  /*
    5863  std::vector<u_int> ClassicStats::accumulated(const Map_& map) const
    5964  {
     
    8590    return accum;
    8691  }
     92  */
     93
    8794
    8895  void ClassicStats::add(const std::string& user, const u_int& rev,
     
    128135      ++(*comments)[rev];
    129136
    130     std::vector<u_int>* empty = &(empty_[user]);
    131     assert(empty);
    132     if (empty->size() < rev+1){
    133       empty->reserve(revision() + 1);
    134       empty->insert(empty->end(), rev - empty->size(), 0);
    135       if (lt == Parser::empty)
    136         empty->push_back(1);
     137    std::vector<u_int>* other = &(other_[user]);
     138    assert(other);
     139    if (other->size() < rev+1){
     140      other->reserve(revision() + 1);
     141      other->insert(other->end(), rev - other->size(), 0);
     142      if (lt == Parser::other)
     143        other->push_back(1);
    137144      else
    138         empty->push_back(0);
     145        other->push_back(0);
    139146    }
    140     else if (lt == Parser::empty)
    141       ++(*empty)[rev];
     147    else if (lt == Parser::other)
     148      ++(*other)[rev];
    142149  }
    143150
     
    172179    getline(is, str);
    173180    getline(is, str);
    174     if (str!=empty_cache()){
     181    if (str!=other_cache()){
    175182      return false;
    176183    }
    177     load(is, empty_);
     184    load(is, other_);
    178185    getline(is, str);
    179186    getline(is, str);
     
    188195
    189196
    190   void ClassicStats::load(std::istream& is, Map_& m)
     197  void ClassicStats::load(std::istream& is, Author2Vector& m)
    191198  {
    192199    while (m.size() < authors().size() && is.good()) {
     
    226233    plot_init(filename);
    227234    GnuplotFE* gp=GnuplotFE::instance();
    228     const Map_* stat=NULL;
     235    const Author2Vector* stat=NULL;
    229236    if (linetype=="total")
    230237      stat = &total_;
     
    234241      stat = &comments_;
    235242    else if (linetype=="empty")
    236       stat = &empty_;
     243      stat = &other_;
    237244    assert(stat);
    238     std::vector<u_int> total=accumulated(*stat);   
     245    assert(stat->size());
     246    std::vector<u_int> total=get_vector(*stat, "all");   
    239247    double yrange_max=1.03*total.back()+1;
    240248    gp->yrange(yrange_max);
     
    243251    vec_type author_cont;
    244252    author_cont.reserve(stat->size());
    245     for (MapConstIter_ i= stat->begin(); i != stat->end(); ++i) {
     253    for (A2VConstIter i= stat->begin(); i != stat->end(); ++i) {
    246254      author_cont.push_back(std::make_pair(i->first,
    247                                            accumulated(*stat,i->first)));
     255                                           get_vector(*stat,i->first)));
    248256    }
    249257
     
    294302    os << "\n" << comments_cache() << "\n";
    295303    do_print(os, comments_);
    296     os << "\n" << empty_cache() << "\n";
    297     do_print(os, empty_);
     304    os << "\n" << other_cache() << "\n";
     305    do_print(os, other_);
    298306    os << "\n" << total_cache() << "\n";
    299307    do_print(os, total_);
     
    302310
    303311
    304   void ClassicStats::do_print(std::ostream& os, const Map_& m) const
    305   {
    306     for (MapConstIter_ i(m.begin()); i!=m.end(); ++i){
     312  void ClassicStats::do_print(std::ostream& os, const Author2Vector& m) const
     313  {
     314    for (A2VConstIter i(m.begin()); i!=m.end(); ++i){
    307315      os << i->first << "\n";
    308316      os << i->second.size() << " ";
     
    313321
    314322 
    315   std::vector<u_int> ClassicStats::vector(std::string type,
    316                                           std::string user) const
    317   {
    318     const Map_* map = NULL;
    319     if (type=="code")
    320       map = &code_;
    321     else if (type=="comments")
    322       map = &comments_;
    323     else if (type=="other")
    324       map = &empty_;
    325     assert(map && "type is of invalid type");
    326     if (!map->count(user))
    327       return std::vector<u_int>(last_changed_rev(),0);
    328     const std::vector<u_int>& vec=(map->find(user))->second;
    329    
    330     std::vector<u_int> accum(vec.size());
    331     std::partial_sum(vec.begin(),vec.end(),accum.begin());
    332     // static_cast to remove annoying compiler warning
    333     if (accum.size() < static_cast<size_t>(revision()+1))
    334       accum.insert(accum.end(), revision()+1-vec.size(), accum.back());
    335     return accum;
    336 
    337   }
    338 
    339 
    340   ClassicStats& ClassicStats::operator+=(const ClassicStats& rhs)
    341   {
    342     base_add(rhs.code_.begin(), rhs.code_.end(), code_);
    343     base_add(rhs.comments_.begin(), rhs.comments_.end(), comments_);
    344     base_add(rhs.empty_.begin(), rhs.empty_.end(), empty_);
    345     base_add(rhs.total_.begin(), rhs.total_.end(), total_);
    346    
    347     base_add(rhs);
    348     return *this;
    349   }
    350 
    351323}} // end of namespace svndigest and namespace theplu
  • trunk/lib/ClassicStats.h

    r519 r528  
    4343    explicit ClassicStats(const std::string& path);
    4444
    45     ///
    46     ///
    47     ///
    48     inline u_int code(void) const { return accumulated(code_).back(); }
    49 
    50     ///
    51     ///
    52     ///
    53     inline u_int code(const std::string& user) const
    54     { return accumulated(code_, user).back(); }
    55 
    56     ///
    57     ///
    58     ///
    59     inline u_int comments(void) const { return accumulated(comments_).back(); }
    60 
    61     ///
    62     ///
    63     ///
    64     inline u_int comments(const std::string& user) const
    65     { return accumulated(comments_, user).back(); }
    66 
    67     ///
    68     ///
    69     ///
    70     inline u_int empty(void) const { return accumulated(empty_).back(); }
    71 
    72     ///
    73     ///
    74     ///
    75     inline u_int empty(const std::string& user) const
    76     { return accumulated(empty_, user).back(); }
    77 
    78     ///
    79     ///
    80     ///
    81     inline u_int lines(void) const { return accumulated(total_).back(); }
    82 
    83     ///
    84     ///
    85     ///
    86     inline u_int lines(const std::string& user) const
    87     { return accumulated(total_, user).back(); }
     45    ClassicStats(const ClassicStats& other);
    8846
    8947    ///
     
    9250    void plot_summary(const std::string& output) const;
    9351
    94     ///
    95     ///
    96     ///
    97     inline std::vector<u_int> total(const std::string& user) const
    98     { return accumulated(total_, user); }
    99 
    100     ///
    101     /// @return resulting Stats
    102     ///
    103     ClassicStats& operator+=(const ClassicStats&);
    104 
    10552  private:
    106     // Peter, if the vector is sparse make it a map
    107     typedef std::map<std::string, std::vector<u_int> > Map_;
    108     typedef Map_::iterator MapIter_;
    109     typedef Map_::const_iterator MapConstIter_;
    110 
    11153    /// using compiler generated copy
    112     //ClassicStats(const ClassicStats& other);
    113 
    114     ///
    115     /// @return accumulated vector of total
    116     ///
    117     std::vector<u_int> accumulated(const Map_&) const;
    118 
    119     ///
    120     /// @return accumulated vector of stats_[user]
    121     ///
    122     std::vector<u_int> accumulated(const Map_&,
    123                                    const std::string& user) const;
    12454
    12555    ///
     
    14777    void do_print(std::ostream&) const;
    14878
    149     ///
    150     /// @brief Clear all statistics
    151     ///
    152     inline void do_reset(void)
    153     {
    154       code_.clear(); comments_.clear(); empty_.clear(); total_.clear();
    155     }
    156 
    15779    // Change this string if cache format is changed in such a way
    15880    // that all old cache files are obsolete.
     
    16587       Load map from stream
    16688     */
    167     void load(std::istream&, Map_&);
     89    void load(std::istream&, Author2Vector&);
    16890
    169     void do_print(std::ostream& os, const Map_& map) const;
     91    void do_print(std::ostream& os, const Author2Vector& map) const;
    17092
    171     Map_ code_;
    172     Map_ comments_;
    173     Map_ empty_;
    174     Map_ total_;
    17593  };
    17694}} // end of namespace svndigest end of namespace theplu
  • trunk/lib/File.cc

    r519 r528  
    263263      os << "</td>\n<td class=\"";
    264264      assert(line_type!=parser.type().end());
    265       if (*line_type==Parser::empty)
     265      if (*line_type==Parser::other)
    266266        os << "line-other";
    267267      else if (*line_type==Parser::comment)
  • trunk/lib/Parser.cc

    r519 r528  
    6363    std::string str;
    6464    while(getline(is,str)) {
    65       line_type lt=empty;
     65      line_type lt=other;
    6666      for (std::string::iterator iter=str.begin(); iter!=str.end(); ++iter){
    6767        for (size_t i=mode; i<codon.size(); ++i) {
     
    103103    std::string str;
    104104    while(getline(is,str)) {
    105       line_type lt=empty;
     105      line_type lt=other;
    106106      for (std::string::iterator iter=str.begin(); iter!=str.end(); ++iter){
    107         if (lt==empty && isalnum(*iter))
     107        if (lt==other && isalnum(*iter))
    108108          lt = comment;
    109109      }
  • trunk/lib/Parser.h

    r519 r528  
    4848    ///
    4949    enum line_type {
    50       empty,
     50      other,
    5151      comment,
    5252      code
  • trunk/lib/Stats.cc

    r527 r528  
    5656    revision_=svn_info.rev();
    5757    last_changed_rev_=svn_info.last_changed_rev();
     58    std::vector<u_int> vec(last_changed_rev_+1, 0);
     59    code_["all"] = vec;
     60    comments_["all"] = vec;
     61    other_["all"] = vec;
     62    total_["all"] = vec;
    5863  }
    5964
     
    6469
    6570
    66   void Stats::base_add(v_map::const_iterator first1,
    67                        v_map::const_iterator last1, v_map& map)
    68   {
    69     v_map::iterator first2(map.begin());
    70     v_map::key_compare compare;
    71     while ( first1 != last1) {
    72       // key of first1 less than key of first2
    73       if (first2==map.end() || compare(first1->first,first2->first)) {
    74         first2 = map.insert(first2, *first1);
    75         ++first1;
    76       }
    77       // key of first2 less than key of first1
    78       else if ( compare(first2->first, first1->first)) {
    79         ++first2;
    80       }
    81       // keys are equivalent
    82       else {
    83         VectorPlus<v_map::mapped_type::value_type> vp;
    84         first2->second = vp(first1->second, first2->second);
    85         ++first1;
    86         ++first2;
    87       }
    88     }
     71  void Stats::accumulate(std::vector<u_int>& vec) const
     72  {
     73    if (vec.empty()){
     74      vec.resize(last_changed_rev(),0);
     75      return;
     76    }
     77    std::partial_sum(vec.begin(),vec.end(),vec.begin());
     78    // static_cast to remove annoying compiler warning
     79    if (vec.size() < static_cast<size_t>(revision()+1))
     80      vec.insert(vec.end(), revision()+1-vec.size(), vec.back());
     81  }
     82
     83
     84  void Stats::accumulate_stats(void)
     85  {
     86    for (std::set<std::string>::const_iterator iter(authors().begin());
     87         iter!=authors().end(); ++iter) {
     88      std::vector<u_int>& code = code_[*iter];
     89      accumulate(code);
     90      std::vector<u_int>& comments = comments_[*iter];
     91      accumulate(comments);
     92      std::vector<u_int>& other = other_[*iter];
     93      accumulate(other);
     94
     95      VectorPlus<u_int> vp;
     96      total_[*iter] = vp(vp(code, comments),other);
     97    }
     98    std::vector<u_int> init(revision()+1);
     99    code_["all"]=std::accumulate(code_.begin(), code_.end(), init,
     100                                 PairValuePlus<std::string,u_int>());
     101    comments_["all"]=std::accumulate(comments_.begin(), comments_.end(), init,
     102                                     PairValuePlus<std::string,u_int>());
     103    other_["all"]=std::accumulate(other_.begin(), other_.end(), init,
     104                                  PairValuePlus<std::string,u_int>());
     105    VectorPlus<u_int> vp;
     106    total_["all"] = vp(vp(code_["all"], comments_["all"]), other_["all"]);
    89107  }
    90108
     
    109127
    110128
    111   void Stats::base_add(const Stats& rhs)
    112   {
    113     revision_ = std::max(revision_, rhs.revision_);
    114     last_changed_rev_ = std::max(last_changed_rev_, rhs.last_changed_rev_);
    115     add_authors(rhs.authors().begin(), rhs.authors().end());
    116     base_add(rhs.code_.begin(), rhs.code_.end(), code_);
    117     base_add(rhs.comments_.begin(), rhs.comments_.end(), comments_);
    118     base_add(rhs.other_.begin(), rhs.other_.end(), other_);
    119     base_add(rhs.total_.begin(), rhs.total_.end(), total_);
    120   }
    121 
    122 
    123129  u_int Stats::code(const std::string& user) const
    124130  {
    125     return get_vector(code_, "all").back();
     131    return get_back(code_, user);
    126132  }
    127133
     
    129135  u_int Stats::comments(const std::string& user) const
    130136  {
    131     return get_vector(comments_, "all").back();
     137    return get_back(comments_, user);
    132138  }
    133139
     
    135141  u_int Stats::empty(const std::string& user) const
    136142  {
    137     return get_vector(other_, "all").back();
    138   }
    139 
    140 
    141   const std::vector<u_int>& Stats::get_vector(const v_map& m,
     143    return get_back(other_, user);
     144  }
     145
     146
     147  u_int Stats::get_back(const Author2Vector& m, std::string user) const
     148  {
     149    A2VConstIter iter(m.find(std::string(user)));
     150    if (iter==m.end() || iter->second.empty())
     151      return 0;
     152    return iter->second.back();
     153  }
     154
     155
     156  const std::vector<u_int>& Stats::get_vector(const Author2Vector& m,
    142157                                              std::string user) const
    143158  {
    144     v_map::const_iterator iter(m.find(std::string(user)));
     159    A2VConstIter iter(m.find(std::string(user)));
    145160    if (iter==m.end())
    146161      throw std::runtime_error(user+std::string(" not found i Stats"));
    147162    return iter->second;
    148163  }
     164
    149165
    150166  bool Stats::load_cache(std::istream& is)
     
    178194  u_int Stats::lines(const std::string& user) const
    179195  {
    180     return get_vector(total_, "all").back();
     196    return get_back(total_, user);
     197  }
     198
     199
     200  void Stats::map_add(A2VConstIter first1, A2VConstIter last1,
     201                      Author2Vector& map)
     202  {
     203    A2VIter first2(map.begin());
     204    Author2Vector::key_compare compare;
     205    while ( first1 != last1) {
     206      // key of first1 less than key of first2
     207      if (first2==map.end() || compare(first1->first,first2->first)) {
     208        first2 = map.insert(first2, *first1);
     209        ++first1;
     210      }
     211      // key of first2 less than key of first1
     212      else if ( compare(first2->first, first1->first)) {
     213        ++first2;
     214      }
     215      // keys are equivalent
     216      else {
     217        VectorPlus<Author2Vector::mapped_type::value_type> vp;
     218        first2->second = vp(first1->second, first2->second);
     219        ++first1;
     220        ++first2;
     221      }
     222    }
    181223  }
    182224
     
    184226  void Stats::parse(const std::string& path)
    185227  {
    186     // First we let inherited class do parsing
    187228    do_parse(path);
    188     // then we fill up with statistics
    189 
    190     update_stats();
     229    accumulate_stats();
    191230  }
    192231
     
    269308  void Stats::reset(void)
    270309  {
    271     do_reset();
    272   }
    273 
    274 
    275   void Stats::update_stats(void)
    276   {
    277     for (std::set<std::string>::const_iterator iter(authors_.begin());
    278          iter!=authors_.end(); ++iter) {
    279       std::vector<u_int> code(vector("code", *iter));
    280       code_[*iter] = code;
    281       std::vector<u_int> comments(vector("comments", *iter));
    282       comments_[*iter] = comments;
    283       std::vector<u_int> other(vector("other", *iter));
    284       other_[*iter] = other;
    285       VectorPlus<u_int> vp;
    286       total_[*iter] = vp(vp(code, comments),other);
    287     }
    288     std::vector<u_int> init(revision()+1);
    289     code_["all"]=std::accumulate(code_.begin(), code_.end(), init,
    290                                  PairValuePlus<std::string,u_int>());
    291     comments_["all"]=std::accumulate(comments_.begin(), comments_.end(), init,
    292                                      PairValuePlus<std::string,u_int>());
    293     other_["all"]=std::accumulate(other_.begin(), other_.end(), init,
    294                                   PairValuePlus<std::string,u_int>());
    295     VectorPlus<u_int> vp;
    296     total_["all"] = vp(vp(code_["all"], comments_["all"]), other_["all"]);
    297   }
     310    assert("implement me");
     311  }
     312
     313
     314  Stats& Stats::operator+=(const Stats& rhs)
     315  {
     316    revision_ = std::max(revision_, rhs.revision_);
     317    last_changed_rev_ = std::max(last_changed_rev_, rhs.last_changed_rev_);
     318    add_authors(rhs.authors().begin(), rhs.authors().end());
     319    map_add(rhs.code_.begin(), rhs.code_.end(), code_);
     320    map_add(rhs.comments_.begin(), rhs.comments_.end(), comments_);
     321    map_add(rhs.other_.begin(), rhs.other_.end(), other_);
     322    map_add(rhs.total_.begin(), rhs.total_.end(), total_);
     323    assert(rhs.other_.size());
     324    assert(other_.size());
     325   
     326    return *this;
     327  }
    298328
    299329
  • trunk/lib/Stats.h

    r527 r528  
    125125    svn_revnum_t revision(void) const { return revision_; }
    126126
     127    /**
     128       \return resulting Stats
     129    */
     130    Stats& operator+=(const Stats&);
     131
     132
     133
    127134  protected:
    128135    inline std::string code_cache(void) const {return "CACHE CODE";}
    129136    inline std::string comments_cache(void) const {return "CACHE COMMENTS";}
    130     inline std::string empty_cache(void) const {return "CACHE EMPTY";}
     137    inline std::string other_cache(void) const {return "CACHE EMPTY";}
    131138    inline std::string total_cache(void) const {return "CACHE TOTAL";}
    132139
    133     typedef std::map<std::string, std::vector<u_int> > v_map;
     140    typedef std::map<std::string, std::vector<u_int> > Author2Vector;
     141    typedef Author2Vector::iterator A2VIter;
     142    typedef Author2Vector::const_iterator A2VConstIter;
    134143
    135144    void add_author(std::string);
     
    138147
    139148    /**
    140        Function to be called from children's operator+=
    141      */
    142     void base_add(const Stats&);
    143 
    144     /**
    145149       add range [\a first, \a last) to \a map
    146150     */
    147     void base_add(v_map::const_iterator first, v_map::const_iterator last,
    148                   v_map& map);
     151    void map_add(Author2Vector::const_iterator first,
     152                 Author2Vector::const_iterator last,
     153                 Author2Vector& map);
    149154
    150155    ///
     
    153158    void plot_init(const std::string& output) const;
    154159
     160    Author2Vector total_;
     161    Author2Vector code_;
     162    Author2Vector comments_;
     163    Author2Vector other_;
     164    std::set<std::string> authors_;
     165
     166    const std::vector<u_int>& get_vector(const Author2Vector&,
     167                                         std::string user) const;
    155168  private:
     169    void accumulate(std::vector<u_int>& vec) const;
     170    void accumulate_stats(void);
    156171    virtual bool do_load_cache(std::istream&)=0;
    157172    virtual void do_parse(const std::string&)=0;
    158173    virtual std::string do_plot(const std::string&, const std::string&) const=0;
    159174    virtual void do_print(std::ostream& ) const=0;
    160     virtual void do_reset(void)=0;
    161175   
    162     const std::vector<u_int>& get_vector(const v_map&, std::string user) const;
    163     virtual std::vector<u_int> vector(std::string type,
    164                                       std::string user) const=0;
    165     void update_stats(void);
    166 
    167     v_map total_;
    168     v_map code_;
    169     v_map comments_;
    170     v_map other_;
     176    u_int get_back(const Author2Vector&, std::string user) const;
    171177
    172178    svn_revnum_t revision_; // Should be the latest revision for whole project
    173179    svn_revnum_t last_changed_rev_; // Should be the latest revision for file
    174180
    175     std::set<std::string> authors_;
     181
     182    // using compiler generated copy constructor
     183    //Stats(const Stats&);
     184    // no assignment
     185    Stats& operator=(const Stats&);
     186
    176187  };
    177188}} // end of namespace svndigest end of namespace theplu
  • trunk/test/parser.cc

    r519 r528  
    4747  std::ifstream is(file.c_str());
    4848  for (size_t i=0; i<parser.type().size(); ++i){
    49     if (parser.type()[i]==Parser::empty)
    50       os << "empty:   ";
     49    if (parser.type()[i]==Parser::other)
     50      os << "other:   ";
    5151    else if (parser.type()[i]==Parser::comment)
    5252      os << "comment: ";
Note: See TracChangeset for help on using the changeset viewer.