Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/ClassicStats.cc
r519 r528 55 55 } 56 56 57 57 ClassicStats::ClassicStats(const ClassicStats& other) 58 : Stats(other) 59 { 60 } 61 62 /* 58 63 std::vector<u_int> ClassicStats::accumulated(const Map_& map) const 59 64 { … … 85 90 return accum; 86 91 } 92 */ 93 87 94 88 95 void ClassicStats::add(const std::string& user, const u_int& rev, … … 128 135 ++(*comments)[rev]; 129 136 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); 137 144 else 138 empty->push_back(0);145 other->push_back(0); 139 146 } 140 else if (lt == Parser:: empty)141 ++(* empty)[rev];147 else if (lt == Parser::other) 148 ++(*other)[rev]; 142 149 } 143 150 … … 172 179 getline(is, str); 173 180 getline(is, str); 174 if (str!= empty_cache()){181 if (str!=other_cache()){ 175 182 return false; 176 183 } 177 load(is, empty_);184 load(is, other_); 178 185 getline(is, str); 179 186 getline(is, str); … … 188 195 189 196 190 void ClassicStats::load(std::istream& is, Map_& m)197 void ClassicStats::load(std::istream& is, Author2Vector& m) 191 198 { 192 199 while (m.size() < authors().size() && is.good()) { … … 226 233 plot_init(filename); 227 234 GnuplotFE* gp=GnuplotFE::instance(); 228 const Map_* stat=NULL;235 const Author2Vector* stat=NULL; 229 236 if (linetype=="total") 230 237 stat = &total_; … … 234 241 stat = &comments_; 235 242 else if (linetype=="empty") 236 stat = & empty_;243 stat = &other_; 237 244 assert(stat); 238 std::vector<u_int> total=accumulated(*stat); 245 assert(stat->size()); 246 std::vector<u_int> total=get_vector(*stat, "all"); 239 247 double yrange_max=1.03*total.back()+1; 240 248 gp->yrange(yrange_max); … … 243 251 vec_type author_cont; 244 252 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) { 246 254 author_cont.push_back(std::make_pair(i->first, 247 accumulated(*stat,i->first)));255 get_vector(*stat,i->first))); 248 256 } 249 257 … … 294 302 os << "\n" << comments_cache() << "\n"; 295 303 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_); 298 306 os << "\n" << total_cache() << "\n"; 299 307 do_print(os, total_); … … 302 310 303 311 304 void ClassicStats::do_print(std::ostream& os, const Map_& m) const305 { 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){ 307 315 os << i->first << "\n"; 308 316 os << i->second.size() << " "; … … 313 321 314 322 315 std::vector<u_int> ClassicStats::vector(std::string type,316 std::string user) const317 {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 warning333 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 351 323 }} // end of namespace svndigest and namespace theplu -
trunk/lib/ClassicStats.h
r519 r528 43 43 explicit ClassicStats(const std::string& path); 44 44 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); 88 46 89 47 /// … … 92 50 void plot_summary(const std::string& output) const; 93 51 94 ///95 ///96 ///97 inline std::vector<u_int> total(const std::string& user) const98 { return accumulated(total_, user); }99 100 ///101 /// @return resulting Stats102 ///103 ClassicStats& operator+=(const ClassicStats&);104 105 52 private: 106 // Peter, if the vector is sparse make it a map107 typedef std::map<std::string, std::vector<u_int> > Map_;108 typedef Map_::iterator MapIter_;109 typedef Map_::const_iterator MapConstIter_;110 111 53 /// using compiler generated copy 112 //ClassicStats(const ClassicStats& other);113 114 ///115 /// @return accumulated vector of total116 ///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;124 54 125 55 /// … … 147 77 void do_print(std::ostream&) const; 148 78 149 ///150 /// @brief Clear all statistics151 ///152 inline void do_reset(void)153 {154 code_.clear(); comments_.clear(); empty_.clear(); total_.clear();155 }156 157 79 // Change this string if cache format is changed in such a way 158 80 // that all old cache files are obsolete. … … 165 87 Load map from stream 166 88 */ 167 void load(std::istream&, Map_&);89 void load(std::istream&, Author2Vector&); 168 90 169 void do_print(std::ostream& os, const Map_& map) const;91 void do_print(std::ostream& os, const Author2Vector& map) const; 170 92 171 Map_ code_;172 Map_ comments_;173 Map_ empty_;174 Map_ total_;175 93 }; 176 94 }} // end of namespace svndigest end of namespace theplu -
trunk/lib/File.cc
r519 r528 263 263 os << "</td>\n<td class=\""; 264 264 assert(line_type!=parser.type().end()); 265 if (*line_type==Parser:: empty)265 if (*line_type==Parser::other) 266 266 os << "line-other"; 267 267 else if (*line_type==Parser::comment) -
trunk/lib/Parser.cc
r519 r528 63 63 std::string str; 64 64 while(getline(is,str)) { 65 line_type lt= empty;65 line_type lt=other; 66 66 for (std::string::iterator iter=str.begin(); iter!=str.end(); ++iter){ 67 67 for (size_t i=mode; i<codon.size(); ++i) { … … 103 103 std::string str; 104 104 while(getline(is,str)) { 105 line_type lt= empty;105 line_type lt=other; 106 106 for (std::string::iterator iter=str.begin(); iter!=str.end(); ++iter){ 107 if (lt== empty&& isalnum(*iter))107 if (lt==other && isalnum(*iter)) 108 108 lt = comment; 109 109 } -
trunk/lib/Parser.h
r519 r528 48 48 /// 49 49 enum line_type { 50 empty,50 other, 51 51 comment, 52 52 code -
trunk/lib/Stats.cc
r527 r528 56 56 revision_=svn_info.rev(); 57 57 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; 58 63 } 59 64 … … 64 69 65 70 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"]); 89 107 } 90 108 … … 109 127 110 128 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 123 129 u_int Stats::code(const std::string& user) const 124 130 { 125 return get_ vector(code_, "all").back();131 return get_back(code_, user); 126 132 } 127 133 … … 129 135 u_int Stats::comments(const std::string& user) const 130 136 { 131 return get_ vector(comments_, "all").back();137 return get_back(comments_, user); 132 138 } 133 139 … … 135 141 u_int Stats::empty(const std::string& user) const 136 142 { 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, 142 157 std::string user) const 143 158 { 144 v_map::const_iterator iter(m.find(std::string(user)));159 A2VConstIter iter(m.find(std::string(user))); 145 160 if (iter==m.end()) 146 161 throw std::runtime_error(user+std::string(" not found i Stats")); 147 162 return iter->second; 148 163 } 164 149 165 150 166 bool Stats::load_cache(std::istream& is) … … 178 194 u_int Stats::lines(const std::string& user) const 179 195 { 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 } 181 223 } 182 224 … … 184 226 void Stats::parse(const std::string& path) 185 227 { 186 // First we let inherited class do parsing187 228 do_parse(path); 188 // then we fill up with statistics 189 190 update_stats(); 229 accumulate_stats(); 191 230 } 192 231 … … 269 308 void Stats::reset(void) 270 309 { 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 } 298 328 299 329 -
trunk/lib/Stats.h
r527 r528 125 125 svn_revnum_t revision(void) const { return revision_; } 126 126 127 /** 128 \return resulting Stats 129 */ 130 Stats& operator+=(const Stats&); 131 132 133 127 134 protected: 128 135 inline std::string code_cache(void) const {return "CACHE CODE";} 129 136 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";} 131 138 inline std::string total_cache(void) const {return "CACHE TOTAL";} 132 139 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; 134 143 135 144 void add_author(std::string); … … 138 147 139 148 /** 140 Function to be called from children's operator+=141 */142 void base_add(const Stats&);143 144 /**145 149 add range [\a first, \a last) to \a map 146 150 */ 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); 149 154 150 155 /// … … 153 158 void plot_init(const std::string& output) const; 154 159 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; 155 168 private: 169 void accumulate(std::vector<u_int>& vec) const; 170 void accumulate_stats(void); 156 171 virtual bool do_load_cache(std::istream&)=0; 157 172 virtual void do_parse(const std::string&)=0; 158 173 virtual std::string do_plot(const std::string&, const std::string&) const=0; 159 174 virtual void do_print(std::ostream& ) const=0; 160 virtual void do_reset(void)=0;161 175 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; 171 177 172 178 svn_revnum_t revision_; // Should be the latest revision for whole project 173 179 svn_revnum_t last_changed_rev_; // Should be the latest revision for file 174 180 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 176 187 }; 177 188 }} // end of namespace svndigest end of namespace theplu
Note: See TracChangeset
for help on using the changeset viewer.