Changeset 1376 for trunk


Ignore:
Timestamp:
Jun 14, 2011, 2:02:11 AM (9 years ago)
Author:
Peter Johansson
Message:

closes #385. implementing cache for svncopyright

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/CopyrightStats.cc

    r1362 r1376  
    2525#include "SVNinfo.h"
    2626#include "SVNlog.h"
     27#include "utility.h"
     28
     29#include <yat/utility/utility.h>
    2730
    2831#include <subversion-1/svn_types.h>
    2932
    3033#include <cassert>
     34#include <fstream>
    3135#include <iostream>
    3236
     
    3539
    3640  CopyrightStats::CopyrightStats(const std::string& path, bool ignore_cache,
    37                                  std::map<std::string, Alias>& author2alias,
    3841                                 const std::map<int, svn_revnum_t>& year2rev)
    39     : author2alias_(author2alias), path_(path)
    40   {
     42    : path_(path)
     43  {
     44    cache_file_ = concatenate_path(concatenate_path(directory_name(path),
     45                                                    ".svndigest"),
     46                                   file_name(path)+".svncopyright-cache");
    4147    init(ignore_cache, year2rev);
    4248  }
     
    4854    svn_revnum_t cache_rev = 0;
    4955    if (!ignore_cache)
    50       cache_rev = load_cache("");
     56      cache_rev = load_cache();
    5157    SVNinfo info(path_);
    5258    if (cache_rev >= info.last_changed_rev())
     
    5864
    5965    parse(cache_rev+1, year2rev);
    60     write_cache("");
    61   }
    62 
    63 
    64   svn_revnum_t CopyrightStats::load_cache(const std::string& filename)
    65   {
    66     // FIXME
     66    write_cache();
     67  }
     68
     69
     70  svn_revnum_t CopyrightStats::load_cache(void)
     71  {
     72    std::ifstream is(cache_file_.c_str());
     73    assert(is.good());
     74
     75    std::string line;
     76    getline(is, line);
     77    if (line!="SVNCOPYRIGHT CACHE VERSION 1")
     78      return 0;
     79    getline(is, line);
     80    if (line!=config_) {
     81      std::cout << "cache file is for different configuration.\n"
     82                << "config code: '" << config_ << "'\n"
     83                << "config code in cache file: '" << line << "'\n"
     84                << "retrieving statistics from repository.\n";
     85      return 0;
     86    }
     87
     88    svn_revnum_t rev = 0;
     89    try {
     90      getline(is, line);
     91      size_t nof_years = yat::utility::convert<size_t>(line);
     92      for (size_t i=0; i<nof_years; ++i) {
     93        getline(is, line);
     94        int year = yat::utility::convert<size_t>(line);
     95        std::set<std::string>& users = year2user_[year];
     96        getline(is, line);
     97        size_t nof_users = yat::utility::convert<size_t>(line);
     98        for (size_t i=0; i<nof_users; ++i) {
     99          getline(is, line);
     100          users.insert(line);
     101        }
     102      }
     103      getline(is, line);
     104      rev = yat::utility::convert<svn_revnum_t>(line);
     105      getline(is, line);
     106      if (line!="SVNCOPYRIGHT CACHE")
     107        return 0;
     108      return rev;
     109    }
     110    catch (yat::utility::runtime_error e) {
     111      return 0;
     112    }
    67113    return 0;
    68114  }
    69115
    70116
    71   const std::map<int, std::set<Alias> > CopyrightStats::map(void) const
    72   {
    73     return year2alias_;
     117  const std::map<int, std::set<std::string> >& CopyrightStats::map(void) const
     118  {
     119    return year2user_;
    74120  }
    75121
     
    97143     
    98144      const std::string& name = commit->author();
    99       // find username in map of aliases
    100       std::map<std::string, Alias>::iterator alias =
    101         author2alias_.lower_bound(name);
    102      
    103       // if alias not found for author
    104       if (alias == author2alias_.end() || alias->first!=name) {
    105         std::cerr << "svncopyright: warning: no copyright alias found for `"
    106                   << name << "'\n";
    107         // insert alias to avoid multiple warnings.
    108         Alias a(name, author2alias_.size());
    109         // FIXME use insert with hint
    110         author2alias_[name] = a;
    111         alias = author2alias_.find(name);
    112       }
    113       assert(alias!=author2alias_.end());
    114      
    115145      // skip if alias already has copyright for this year.
    116       std::map<int, std::set<Alias> >::const_iterator year_aliases =
    117         year2alias_.find(yearrev->first);
    118       if (year_aliases!=year2alias_.end()
    119           && year_aliases->second.count(alias->second))
     146      std::map<int, std::set<std::string> >::const_iterator year_users =
     147        year2user_.find(yearrev->first);
     148      if (year_users!=year2user_.end()
     149          && year_users->second.count(name))
    120150        continue;
    121151     
     
    128158        if ((lt==LineTypeParser::code || lt==LineTypeParser::comment) &&
    129159            svn_blame.revision()==commit->revision()) {
    130           year2alias_[yearrev->first].insert(alias->second);
     160          year2user_[yearrev->first].insert(name);
    131161          break;
    132162        }
     
    139169  void CopyrightStats::reset(void)
    140170  {
    141     year2alias_.clear();
    142   }
    143 
    144 
    145   void CopyrightStats::write_cache(const std::string& filename)
    146   {
    147     // FIXME
     171    year2user_.clear();
     172  }
     173
     174
     175  void CopyrightStats::write_cache(void)
     176  {
     177    mkdir_p(directory_name(cache_file_));
     178    std::ofstream os(cache_file_.c_str());
     179    assert(os.good());
     180
     181    os << "SVNCOPYRIGHT CACHE VERSION 1\n";
     182    os << config_ << "\n";
     183    os << year2user_.size() << "\n";
     184    using std::map;
     185    using std::set;
     186    using std::string;
     187    for (map<int, set<string> >::const_iterator i=year2user_.begin();
     188         i!=year2user_.end(); ++i) {
     189      os << i->first << "\n";
     190      os << i->second.size() << "\n";
     191      for (set<string>::const_iterator j=i->second.begin();
     192           j!=i->second.end(); ++j) {
     193        os << *j << "\n";
     194      }
     195    }
     196
     197    SVNinfo info(path_);
     198    os << info.last_changed_rev() << "\n";
     199    os << "SVNCOPYRIGHT CACHE\n";
     200    os.close();
    148201  }
    149202
  • trunk/lib/CopyrightStats.h

    r1358 r1376  
    4343     */
    4444    CopyrightStats(const std::string& path, bool ignore_cache,
    45                    std::map<std::string, Alias>& author2alias,
    4645                   const std::map<int, svn_revnum_t>& year2rev);
    4746
    48     const std::map<int, std::set<Alias> > map(void) const;
     47    const std::map<int, std::set<std::string> >& map(void) const;
    4948  private:
    5049    /**
     
    5554
    5655    /// return 0 if load failed; otherwise return rev cache represents
    57     svn_revnum_t load_cache(const std::string& filename);
     56    svn_revnum_t load_cache(void);
    5857
    5958    void parse(svn_revnum_t rev, const std::map<int, svn_revnum_t>& year2rev);
    6059    void reset(void);
    61     void write_cache(const std::string& filename);
     60    void write_cache(void);
    6261
    63     std::map<std::string, Alias>& author2alias_;
     62    std::string cache_file_;
     63    std::string config_;
    6464    std::string path_;
    65     std::map<int, std::set<Alias> > year2alias_;
     65    std::map<int, std::set<std::string> > year2user_;
    6666  };
    6767}} // end of namespace svndigest and namespace theplu
  • trunk/lib/CopyrightVisitor.cc

    r1358 r1376  
    7575    }
    7676    return ss.str();
    77   }
    78 
    79 
    80   void CopyrightVisitor::create_year2alias(std::map<int, std::set<Alias> >& m,
    81                                            const File& file)
    82   {
    83     using namespace std;
    84     const Stats& stats = file.stats()["add"];
    85 
    86     // loop over all years
    87     for (std::map<int, svn_revnum_t>::const_iterator rev_iter=year2rev_.begin();
    88          rev_iter!=year2rev_.end(); ++rev_iter) {
    89 
    90       svn_revnum_t last_rev_this_year = rev_iter->second;
    91       svn_revnum_t last_rev_last_year = 0;
    92       if (rev_iter != year2rev_.begin()) {
    93         last_rev_last_year = (--rev_iter)->second;
    94         ++rev_iter;
    95       }
    96       // do not go beyond BASE rev of file
    97       last_rev_this_year = std::min(last_rev_this_year,file.last_changed_rev());
    98       last_rev_last_year = std::min(last_rev_last_year,file.last_changed_rev());
    99       // loop over authors
    100       for (std::set<std::string>::const_iterator a_iter=stats.authors().begin();
    101            a_iter!=stats.authors().end(); ++a_iter) {
    102 
    103         // check if anything has been added since last year
    104         if ( (stats(LineTypeParser::code, *a_iter, last_rev_this_year) >
    105               stats(LineTypeParser::code, *a_iter, last_rev_last_year)) ||
    106              (stats(LineTypeParser::comment, *a_iter, last_rev_this_year) >
    107               stats(LineTypeParser::comment, *a_iter, last_rev_last_year)) ) {
    108        
    109        
    110           // find username in map of aliases
    111           std::map<string,Alias>::iterator name(alias_.lower_bound(*a_iter));
    112          
    113           // if alias exist insert alias
    114           if (name != alias_.end() && name->first==*a_iter)
    115             m[rev_iter->first].insert(name->second);
    116           else {
    117             // else insert user name
    118             Alias a(*a_iter,alias_.size());
    119             m[rev_iter->first].insert(a);
    120             std::cerr << "svncopyright: warning: no copyright alias found for `"
    121                       << *a_iter << "'\n";
    122             // insert alias to avoid multiple warnings.
    123             alias_.insert(name, std::make_pair(*a_iter, a));
    124           }
    125         }
    126       }
    127     }
    12877  }
    12978
     
    178127    if (verbose_)
    179128      std::cout << "Parsing '" << file.path() << "'\n";
    180     CopyrightStats stats(file.path(), ignore_cache_, alias_, year2rev_);
    181     const std::map<int, std::set<Alias> >& map = stats.map();
    182     assert(!map.empty());
    183     std::string new_block = copyright_block(map, prefix);
     129    CopyrightStats stats(file.path(), ignore_cache_, year2rev_);
     130    const std::map<int, std::set<std::string> >& year2users = stats.map();
     131    assert(!year2users.empty());
     132    std::map<int, std::set<Alias> > year2alias;
     133    translate(year2users, year2alias);
     134    std::string new_block = copyright_block(year2alias, prefix);
    184135    if (old_block==new_block)
    185136      return;
     
    231182  }
    232183
     184
    233185  void CopyrightVisitor::visit(File& file)
    234186  {
     
    242194  }
    243195
     196
     197  void CopyrightVisitor::translate(const std::set<std::string>& users,
     198                                   std::set<Alias>& aliases)
     199  {
     200    for (std::set<std::string>::const_iterator user=users.begin();
     201         user!=users.end(); ++user) {
     202      std::map<std::string, Alias>::const_iterator i = alias_.find(*user);
     203      // if alias not found for author
     204      if (i==alias_.end()) {
     205        std::cerr << "svncopyright: warning: no copyright alias found for `"
     206                  << *user << "'\n";
     207        // insert alias to avoid multiple warnings.
     208        Alias a(*user, alias_.size());
     209        alias_[*user] = a;
     210      }
     211      else {
     212        // FIXME: perhaps use hint
     213        aliases.insert(i->second);
     214      }
     215    }
     216  }
     217
     218
     219  void
     220  CopyrightVisitor::translate(const std::map<int, std::set<std::string> >& y2u,
     221                              std::map<int, std::set<Alias> >& y2a)
     222  {
     223    using std::map;
     224    using std::set;
     225    using std::string;
     226    for (map<int, set<string> >::const_iterator yu=y2u.begin();
     227         yu!=y2u.end();++yu) {
     228      set<Alias>& alias = y2a[yu->first];
     229      translate(yu->second, alias);
     230    }
     231  }
     232     
    244233}} // end of namespace svndigest and namespace theplu
  • trunk/lib/CopyrightVisitor.h

    r1239 r1376  
    3131#include <set>
    3232#include <string>
     33#include <vector>
    3334
    3435namespace theplu{
     
    7879                                const std::string& prefix) const;
    7980
    80     /**
    81        Create a map from year to set of authors.
    82      */
    83     void create_year2alias(std::map<int, std::set<Alias> >&, const File& file);
    8481
    8582    /**
    86        Look from copyright block in file \a path.
     83       Look for copyright block in file \a path.
    8784
    8885       \param path file to look for copyright
     
    113110    void update_copyright(const std::string& path, const std::string& block,
    114111                          size_t start_at_line, size_t end_at_line) const;
     112
     113
     114    /**
     115       Translating a set of users to a set of aliases using mapping in alias_
     116    */
     117    void translate(const std::set<std::string>&, std::set<Alias>&);
     118
     119    /**
     120       Translating each year
     121     */
     122    void translate(const std::map<int, std::set<std::string> >& year2user,
     123                   std::map<int, std::set<Alias> >& year2alias);
     124
     125
    115126  };
    116127}} // end of namespace svndigest and namespace theplu
  • trunk/test/Makefile.am

    r1373 r1376  
    5858
    5959# tests not yet passing are listed here
    60 XFAIL_TESTS = copyright_cache_test.sh
     60XFAIL_TESTS =
    6161
    6262noinst_HEADERS = Suite.h
  • trunk/test/copyright_cache_test.sh

    r1364 r1376  
    5656# modify the cache file to allow us to detect that it is used
    5757sed -i 's/peter/winston/' $cache_file
     58cat $cache_file
    5859# create a config reflecting this name change
    5960sed 's/peter/winston/' config > config2
     
    6667diff -u correct.txt copyright.txt || exit_fail
    6768
    68 diff -u cache.txt $cache_file || exit_fail
    69 
    7069exit_success;
  • trunk/yat/Makefile.am

    r1152 r1376  
    33## $Id$
    44
    5 # Copyright (C) 2009, 2010 Peter Johansson
     5# Copyright (C) 2009, 2010, 2011 Peter Johansson
    66#
    77# This file is part of svndigest, http://dev.thep.lu.se/svndigest
     
    4343libyat_a_SOURCES += ColumnStream.cc
    4444libyat_a_SOURCES += CommandLine.cc
     45libyat_a_SOURCES += dummie.cc
    4546libyat_a_SOURCES += Exception.cc
    4647libyat_a_SOURCES += Option.cc
Note: See TracChangeset for help on using the changeset viewer.