From 733588d948a46e75555457e80c1a17d3dbe84872 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Thu, 3 Apr 2014 19:18:15 +0200 Subject: [PATCH] RepoStatus: Hide implementation details. --- zypp/RepoManager.cc | 8 +-- zypp/RepoStatus.cc | 112 ++++++++++++++++++----------------------- zypp/RepoStatus.h | 125 ++++++++++++++++++---------------------------- zypp/target/TargetImpl.cc | 11 ++-- 4 files changed, 104 insertions(+), 152 deletions(-) diff --git a/zypp/RepoManager.cc b/zypp/RepoManager.cc index f22d5f9..4c64ee4 100644 --- a/zypp/RepoManager.cc +++ b/zypp/RepoManager.cc @@ -842,12 +842,8 @@ namespace zypp } // check status - // DBG << "oldstatus: " << (Date::ValueType)oldstatus.timestamp() << endl; - // DBG << " " << oldstatus.checksum() << endl; - // DBG << "newstatus: " << (Date::ValueType)newstatus.timestamp() << endl; - // DBG << " " << newstatus.checksum() << endl; bool refresh = false; - if ( oldstatus.checksum() == newstatus.checksum() ) + if ( oldstatus == newstatus ) { MIL << "repo has not changed" << endl; if ( policy == RefreshForced ) @@ -1058,7 +1054,7 @@ namespace zypp MIL << info.alias() << " is already cached." << endl; RepoStatus cache_status = cacheStatus(info); - if ( cache_status.checksum() == raw_metadata_status.checksum() ) + if ( cache_status == raw_metadata_status ) { MIL << info.alias() << " cache is up to date with metadata." << endl; if ( policy == BuildIfNeeded ) { diff --git a/zypp/RepoStatus.cc b/zypp/RepoStatus.cc index c8c3ceb..b51b25c 100644 --- a/zypp/RepoStatus.cc +++ b/zypp/RepoStatus.cc @@ -31,24 +31,24 @@ namespace zypp struct RepoStatus::Impl { public: - string checksum; - Date timestamp; + string _checksum; + Date _timestamp; /** Recursive computation of max dir timestamp. */ - static void recursive_timestamp( const Pathname & dir, time_t & max ) + static void recursive_timestamp( const Pathname & dir_r, time_t & max_r ) { std::list dircontent; - if ( filesystem::readdir( dircontent, dir, false/*no dots*/ ) != 0 ) + if ( filesystem::readdir( dircontent, dir_r, false/*no dots*/ ) != 0 ) return; // readdir logged the error for_( it, dircontent.begin(), dircontent.end() ) { - PathInfo pi( dir + *it, PathInfo::LSTAT ); + PathInfo pi( dir_r + *it, PathInfo::LSTAT ); if ( pi.isDir() ) { - recursive_timestamp( pi.path(), max ); - if ( pi.mtime() > max ) - max = pi.mtime(); + if ( pi.mtime() > max_r ) + max_r = pi.mtime(); + recursive_timestamp( pi.path(), max_r ); } } } @@ -63,9 +63,7 @@ namespace zypp /** \relates RepoStatus::Impl Stream output */ inline std::ostream & operator<<( std::ostream & str, const RepoStatus::Impl & obj ) - { - return str << obj.checksum << " " << (time_t)obj.timestamp; - } + { return str << obj._checksum << " " << (time_t)obj._timestamp; } /////////////////////////////////////////////////////////////////// // @@ -85,100 +83,88 @@ namespace zypp { if ( info.isFile() ) { - _pimpl->timestamp = Date( info.mtime() ); - _pimpl->checksum = filesystem::sha1sum( path_r ); + _pimpl->_timestamp = Date( info.mtime() ); + _pimpl->_checksum = filesystem::sha1sum( path_r ); } else if ( info.isDir() ) { time_t t = info.mtime(); Impl::recursive_timestamp( path_r, t ); - _pimpl->timestamp = Date(t); - _pimpl->checksum = CheckSum::sha1FromString( str::numstring( t ) ).checksum(); + _pimpl->_timestamp = Date(t); + _pimpl->_checksum = CheckSum::sha1FromString( str::numstring( t ) ).checksum(); } + + // NOTE: changing magic will once invalidate all solv file caches + // Helpfull if solv file content must be refreshed (e.g. due to different + // repo2* arguments) even if raw metadata are unchanged. + static const std::string magic( "42" ); + _pimpl->_checksum += magic; } } RepoStatus::~RepoStatus() {} - RepoStatus RepoStatus::fromCookieFile( const Pathname & cookiefile_r ) + RepoStatus RepoStatus::fromCookieFile( const Pathname & path_r ) { RepoStatus ret; - std::ifstream file( cookiefile_r.c_str() ); + std::ifstream file( path_r.c_str() ); if ( !file ) { - WAR << "No cookie file " << cookiefile_r << endl; + WAR << "No cookie file " << path_r << endl; } else { // line := "[checksum] time_t" std::string line( str::getline( file ) ); - ret.setTimestamp( Date( str::strtonum( str::stripLastWord( line ) ) ) ); - ret.setChecksum( line ); + ret._pimpl->_timestamp = Date( str::strtonum( str::stripLastWord( line ) ) ); + ret._pimpl->_checksum = line; } return ret; } - void RepoStatus::saveToCookieFile( const Pathname &cookiefile ) const + void RepoStatus::saveToCookieFile( const Pathname & path_r ) const { - std::ofstream file(cookiefile.c_str()); + std::ofstream file(path_r.c_str()); if (!file) { - ZYPP_THROW (Exception( "Can't open " + cookiefile.asString() ) ); + ZYPP_THROW (Exception( "Can't open " + path_r.asString() ) ); } - file << checksum() << " " << (time_t)timestamp() << endl; + file << _pimpl->_checksum << " " << (time_t)_pimpl->_timestamp << endl; file.close(); } bool RepoStatus::empty() const - { - return _pimpl->checksum.empty(); - } - - RepoStatus & RepoStatus::setChecksum( const string &checksum ) - { - _pimpl->checksum = checksum; - return *this; - } - - RepoStatus & RepoStatus::setTimestamp( const Date ×tamp ) - { - _pimpl->timestamp = timestamp; - return *this; - } - - string RepoStatus::checksum() const - { return _pimpl->checksum; } + { return _pimpl->_checksum.empty(); } Date RepoStatus::timestamp() const - { return _pimpl->timestamp; } + { return _pimpl->_timestamp; } + + std::ostream & operator<<( std::ostream & str, const RepoStatus & obj ) + { return str << *obj._pimpl; } RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs ) { - if ( lhs.empty() ) - return rhs; - if ( rhs.empty() ) - return lhs; + RepoStatus result; - // order strings to assert && is kommutativ - std::string lchk( lhs.checksum() ); - std::string rchk( rhs.checksum() ); - stringstream ss( lchk < rchk ? lchk+rchk : rchk+lchk ); + if ( lhs.empty() ) + result = rhs; + else if ( rhs.empty() ) + result = lhs; + else + { + // order strings to assert && is kommutativ + std::string lchk( lhs._pimpl->_checksum ); + std::string rchk( rhs._pimpl->_checksum ); + stringstream ss( lchk < rchk ? lchk+rchk : rchk+lchk ); - RepoStatus result; - result.setChecksum( CheckSum::sha1(ss).checksum() ); - result.setTimestamp( lhs.timestamp() < rhs.timestamp() ? rhs.timestamp() : lhs.timestamp() ); + result._pimpl->_checksum = CheckSum::sha1(ss).checksum(); + result._pimpl->_timestamp = std::max( lhs._pimpl->_timestamp, rhs._pimpl->_timestamp ); + } return result; } - /****************************************************************** - ** - ** FUNCTION NAME : operator<< - ** FUNCTION TYPE : std::ostream & - */ - std::ostream & operator<<( std::ostream & str, const RepoStatus & obj ) - { - return str << *obj._pimpl; - } + bool operator==( const RepoStatus & lhs, const RepoStatus & rhs ) + { return lhs._pimpl->_checksum == rhs._pimpl->_checksum; } ///////////////////////////////////////////////////////////////// } // namespace zypp diff --git a/zypp/RepoStatus.h b/zypp/RepoStatus.h index fd3717a..587a507 100644 --- a/zypp/RepoStatus.h +++ b/zypp/RepoStatus.h @@ -22,108 +22,79 @@ namespace zypp { ///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// - // - // CLASS NAME : RepoStatus - // - /** - * \short Local facts about a repository - * This class represents the status of a - * repository on the system. - * - * Anything that is not provided on the metadata - * files, like the timestamp of the downloaded - * metadata, and its checksum. - */ + /// \class RepoStatus + /// \brief Track changing files or directories. + /// + /// Compute timestamp and checksum for individual files or + /// directories (recursively) to track changing content. + /// + /// The timestamp most probably denotes the time the data were + /// changed the last time, that's why it is exposed. + /// + /// The checksum however is an implementation detail and of no + /// use outside this class. \ref operator== tells if the checksums + /// of two rRepoStatus are the same. + /////////////////////////////////////////////////////////////////// class RepoStatus { friend std::ostream & operator<<( std::ostream & str, const RepoStatus & obj ); - - public: - - /** - * reads the status from a file which contains the - * checksum and timestamp in each line. - * - * \returns An empty \ref RepoStatus if the file does not - * exist or is not readable. - */ - static RepoStatus fromCookieFile( const Pathname &path ); - - /** - * save the status information to a cookie file - * \throws Exception if the file can't be saved - */ - void saveToCookieFile( const Pathname &path ) const; - - /** - * Checksum of the repository. - * Usually the checksum of the index, but any - * checksum that changes when the repository changes - * in any way is sufficient. - */ - std::string checksum() const; - - /** - * timestamp of the repository. If the repository - * changes, it has to be updated as well with the - * new timestamp. - */ - Date timestamp() const; - - /** - * \short Is the status empty? - * - * An empty status means that the status - * was not calculated. - */ - bool empty() const; - - /** - * set the repository checksum \see checksum - * \param checksum - */ - RepoStatus & setChecksum( const std::string &checksum ); - - /** - * set the repository timestamp \see timestamp - * \param timestamp - */ - RepoStatus & setTimestamp( const Date ×tamp ); - - /** Implementation */ - class Impl; + friend RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs ); + friend bool operator==( const RepoStatus & lhs, const RepoStatus & rhs ); public: /** Default ctor */ RepoStatus(); - /** - * \short Status of a single file or drectory (recursively) + /** Compute status for single file or directory (recursively) * * \note Construction from a non existing file will result * in an empty status. */ - RepoStatus( const Pathname & path_r ); + explicit RepoStatus( const Pathname & path_r ); /** Dtor */ ~RepoStatus(); public: + /** Reads the status from a cookie file + * \returns An empty \ref RepoStatus if the file does not + * exist or is not readable. + * \see \ref saveToCookieFile + */ + static RepoStatus fromCookieFile( const Pathname & path ); + /** Save the status information to a cookie file + * \throws Exception if the file can't be saved + * \see \ref fromCookieFile + */ + void saveToCookieFile( const Pathname & path_r ) const; + + public: + /** Whether the status is empty (default constucted) */ + bool empty() const; + + /** The time the data were changed the last time */ + Date timestamp() const; + + public: + class Impl; ///< Implementation private: - /** Pointer to implementation */ - RWCOW_pointer _pimpl; + RWCOW_pointer _pimpl; ///< Pointer to implementation }; /////////////////////////////////////////////////////////////////// /** \relates RepoStatus Stream output */ std::ostream & operator<<( std::ostream & str, const RepoStatus & obj ); - /** - * combines 2 repostatus with a checksum based on both - * checksums and the newest timestamp - */ - RepoStatus operator&&( const RepoStatus &lhs, const RepoStatus &rhs ); + /** \relates RepoStatus Combine two RepoStatus (combined checksum and newest timestamp) */ + RepoStatus operator&&( const RepoStatus & lhs, const RepoStatus & rhs ); + + /** \relates RepoStatus Whether 2 RepoStatus refer to the same content checksum */ + bool operator==( const RepoStatus & lhs, const RepoStatus & rhs ); + + /** \relates RepoStatus Whether 2 RepoStatus refer to different content checksums */ + inline bool operator!=( const RepoStatus & lhs, const RepoStatus & rhs ) + { return ! ( lhs == rhs ); } ///////////////////////////////////////////////////////////////// } // namespace zypp diff --git a/zypp/target/TargetImpl.cc b/zypp/target/TargetImpl.cc index 7fcbcf5..7473d2a 100644 --- a/zypp/target/TargetImpl.cc +++ b/zypp/target/TargetImpl.cc @@ -973,8 +973,7 @@ namespace zypp bool build_rpm_solv = true; // lets see if the rpm solv cache exists - RepoStatus rpmstatus( RepoStatus( _root/"/var/lib/rpm/Name" ) - && (_root/"/etc/products.d") ); + RepoStatus rpmstatus( RepoStatus(_root/"var/lib/rpm/Name") && RepoStatus(_root/"etc/products.d") ); bool solvexisted = PathInfo(rpmsolv).isExist(); if ( solvexisted ) @@ -986,10 +985,10 @@ namespace zypp { RepoStatus status = RepoStatus::fromCookieFile(rpmsolvcookie); // now compare it with the rpm database - if ( status.checksum() == rpmstatus.checksum() ) - build_rpm_solv = false; - MIL << "Read cookie: " << rpmsolvcookie << " says: " - << (build_rpm_solv ? "outdated" : "uptodate") << endl; + if ( status == rpmstatus ) + build_rpm_solv = false; + MIL << "Read cookie: " << rpmsolvcookie << " says: " + << (build_rpm_solv ? "outdated" : "uptodate") << endl; } } -- 2.7.4