}
// 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 )
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 ) {
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<std::string> 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 );
}
}
}
/** \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; }
///////////////////////////////////////////////////////////////////
//
{
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<time_t>( str::stripLastWord( line ) ) ) );
- ret.setChecksum( line );
+ ret._pimpl->_timestamp = Date( str::strtonum<time_t>( 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
{ /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
- //
- // 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<Impl> _pimpl;
+ RWCOW_pointer<Impl> _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
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 )
{
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;
}
}