aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Piotr Jaroszyński <p.jaroszynski@gmail.com> 2009-04-04 23:22:34 +0200
committerAvatar Piotr Jaroszyński <p.jaroszynski@gmail.com> 2009-04-04 23:22:34 +0200
commitc4954637fe7bb34042f001755c2df4923633559f (patch)
tree77e4bb99b6a291a43aa36f599446802654ac20a2
parent731221582515aee50d7ea74ba1ee5a83345dc8a4 (diff)
downloadpaludis-c4954637fe7bb34042f001755c2df4923633559f.tar.gz
paludis-c4954637fe7bb34042f001755c2df4923633559f.tar.xz
Memoise file hashes.
-rw-r--r--paludis/repositories/e/Makefile.am2
-rw-r--r--paludis/repositories/e/check_fetched_files_visitor.cc37
-rw-r--r--paludis/repositories/e/e_repository.cc18
-rw-r--r--paludis/repositories/e/memoised_hashes.cc130
-rw-r--r--paludis/repositories/e/memoised_hashes.hh53
5 files changed, 210 insertions, 30 deletions
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index 703caae..a67332d 100644
--- a/paludis/repositories/e/Makefile.am
+++ b/paludis/repositories/e/Makefile.am
@@ -72,6 +72,7 @@ paludis_repositories_e_include_HEADERS = \
glsa.hh \
layout.hh \
manifest2_reader.hh \
+ memoised_hashes.hh \
metadata_xml.hh \
myoption.hh \
myoptions_requirements_verifier.hh \
@@ -129,6 +130,7 @@ libpaludiserepository_@PALUDIS_PC_SLOT@_la_SOURCES = \
glsa.cc \
layout.cc \
manifest2_reader.cc \
+ memoised_hashes.cc \
metadata_xml.cc \
myoption.cc \
myoptions_requirements_verifier.cc \
diff --git a/paludis/repositories/e/check_fetched_files_visitor.cc b/paludis/repositories/e/check_fetched_files_visitor.cc
index 48d57e1..11a2897 100644
--- a/paludis/repositories/e/check_fetched_files_visitor.cc
+++ b/paludis/repositories/e/check_fetched_files_visitor.cc
@@ -18,6 +18,7 @@
*/
#include <paludis/repositories/e/check_fetched_files_visitor.hh>
+#include <paludis/repositories/e/memoised_hashes.hh>
#include <paludis/repositories/e/source_uri_finder.hh>
#include <paludis/repositories/e/e_repository_id.hh>
#include <paludis/repositories/e/e_repository_params.hh>
@@ -241,10 +242,13 @@ CheckFetchedFilesVisitor::check_distfile_manifest(const FSEntry & distfile)
{
SafeIFStream file_stream(distfile);
+ MemoisedHashes * hashes = MemoisedHashes::get_instance();
+
if (! m->rmd160().empty())
{
- RMD160 rmd160sum(file_stream);
- if (rmd160sum.hexsum() != m->rmd160())
+ std::string rmd160hexsum(hashes->get<RMD160>(distfile, file_stream));
+
+ if (rmd160hexsum != m->rmd160())
{
Log::get_instance()->message("e.manifest.rmd160.failure", ll_debug, lc_context)
<< "Malformed Manifest: failed RMD160 checksum";
@@ -258,15 +262,14 @@ CheckFetchedFilesVisitor::check_distfile_manifest(const FSEntry & distfile)
return false;
}
Log::get_instance()->message("e.manifest.rmd160.result", ll_debug, lc_context)
- << "Actual RMD160 = " << rmd160sum.hexsum();
- file_stream.clear();
- file_stream.seekg(0, std::ios::beg);
+ << "Actual RMD160 = " << rmd160hexsum;
}
if (! m->sha1().empty())
{
- SHA1 sha1sum(file_stream);
- if (sha1sum.hexsum() != m->sha1())
+ std::string sha1hexsum(hashes->get<SHA1>(distfile, file_stream));
+
+ if (sha1hexsum != m->sha1())
{
Log::get_instance()->message("e.manifest.sha1.failure", ll_debug, lc_context)
<< "Malformed Manifest: failed SHA1 checksum";
@@ -280,15 +283,14 @@ CheckFetchedFilesVisitor::check_distfile_manifest(const FSEntry & distfile)
return false;
}
Log::get_instance()->message("e.manifest.sha1.result", ll_debug, lc_context)
- << "Actual SHA1 = " << sha1sum.hexsum();
- file_stream.clear();
- file_stream.seekg(0, std::ios::beg);
+ << "Actual SHA1 = " << sha1hexsum;
}
if (! m->sha256().empty())
{
- SHA256 sha256sum(file_stream);
- if (sha256sum.hexsum() != m->sha256())
+ std::string sha256hexsum(hashes->get<SHA256>(distfile, file_stream));
+
+ if (sha256hexsum != m->sha256())
{
Log::get_instance()->message("e.manifest.sha256.failure", ll_debug, lc_context)
<< "Malformed Manifest: failed SHA256 checksum";
@@ -302,15 +304,14 @@ CheckFetchedFilesVisitor::check_distfile_manifest(const FSEntry & distfile)
return false;
}
Log::get_instance()->message("e.manifest.sha256.result", ll_debug, lc_context)
- << "Actual SHA256 = " << sha256sum.hexsum();
- file_stream.clear();
- file_stream.seekg(0, std::ios::beg);
+ << "Actual SHA256 = " << sha256hexsum;
}
if (! m->md5().empty())
{
- MD5 md5sum(file_stream);
- if (md5sum.hexsum() != m->md5())
+ std::string md5hexsum(hashes->get<MD5>(distfile, file_stream));
+
+ if (md5hexsum != m->md5())
{
Log::get_instance()->message("e.manifest.md5.failure", ll_debug, lc_context)
<< "Malformed Manifest: failed MD5 checksum";
@@ -324,7 +325,7 @@ CheckFetchedFilesVisitor::check_distfile_manifest(const FSEntry & distfile)
return false;
}
Log::get_instance()->message("e.manifest.md5.result", ll_debug, lc_context)
- << "Actual MD5 = " << md5sum.hexsum();
+ << "Actual MD5 = " << md5hexsum;
}
}
catch (const SafeIFStreamError &)
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index 33796bf..60ed666 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -36,6 +36,7 @@
#include <paludis/repositories/e/layout.hh>
#include <paludis/repositories/e/info_metadata_key.hh>
#include <paludis/repositories/e/extra_distribution_data.hh>
+#include <paludis/repositories/e/memoised_hashes.hh>
#ifdef ENABLE_QA
# include <paludis/repositories/e/qa/qa_controller.hh>
@@ -1239,20 +1240,13 @@ ERepository::make_manifest(const QualifiedPackageName & qpn)
SafeIFStream file_stream(f);
- RMD160 rmd160sum(file_stream);
+ MemoisedHashes * hashes = MemoisedHashes::get_instance();
+
manifest << "DIST " << f.basename() << " "
<< f.file_size()
- << " RMD160 " << rmd160sum.hexsum();
-
- file_stream.clear();
- file_stream.seekg(0, std::ios::beg);
- SHA1 sha1sum(file_stream);
- manifest << " SHA1 " << sha1sum.hexsum();
-
- file_stream.clear();
- file_stream.seekg(0, std::ios::beg);
- SHA256 sha256sum(file_stream);
- manifest << " SHA256 " << sha256sum.hexsum()
+ << " RMD160 " << hashes->get<RMD160>(f, file_stream)
+ << " SHA1 " << hashes->get<SHA1>(f, file_stream)
+ << " SHA256 " << hashes->get<SHA256>(f, file_stream)
<< std::endl;
}
}
diff --git a/paludis/repositories/e/memoised_hashes.cc b/paludis/repositories/e/memoised_hashes.cc
new file mode 100644
index 0000000..328e6e6
--- /dev/null
+++ b/paludis/repositories/e/memoised_hashes.cc
@@ -0,0 +1,130 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Piotr Jaroszyński
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/repositories/e/memoised_hashes.hh>
+
+#include <paludis/util/mutex.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/instantiation_policy-impl.hh>
+#include <paludis/util/safe_ifstream.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/rmd160.hh>
+#include <paludis/util/sha1.hh>
+#include <paludis/util/sha256.hh>
+#include <paludis/util/md5.hh>
+
+#include <map>
+
+using namespace paludis;
+using namespace paludis::erepository;
+
+namespace paludis
+{
+ typedef std::map<std::pair<std::string, int>, std::pair<time_t, std::string> > HashesMap;
+
+ template <>
+ struct Implementation<MemoisedHashes>
+ {
+ mutable Mutex mutex;
+ mutable HashesMap hashes;
+
+ Implementation()
+ {
+ }
+ };
+}
+
+MemoisedHashes::MemoisedHashes() :
+ PrivateImplementationPattern<MemoisedHashes>(new Implementation<MemoisedHashes>)
+{
+}
+
+MemoisedHashes::~MemoisedHashes()
+{
+}
+
+namespace
+{
+ template <typename>
+ struct HashIDs;
+
+ template <>
+ struct HashIDs<RMD160>
+ {
+ static const int id;
+ };
+ const int HashIDs<RMD160>::id = 0;
+
+ template <>
+ struct HashIDs<SHA1>
+ {
+ static const int id;
+ };
+ const int HashIDs<SHA1>::id = 1;
+
+ template <>
+ struct HashIDs<SHA256>
+ {
+ static const int id;
+ };
+ const int HashIDs<SHA256>::id = 2;
+
+ template <>
+ struct HashIDs<MD5>
+ {
+ static const int id;
+ };
+ const int HashIDs<MD5>::id = 3;
+}
+
+template <typename H_>
+const std::string
+MemoisedHashes::get(const FSEntry & file, SafeIFStream & stream) const
+{
+ std::pair<std::string, int> key(stringify(file), HashIDs<H_>::id);
+ time_t mtime = file.mtime();
+
+ Lock l(_imp->mutex);
+
+ HashesMap::iterator i(_imp->hashes.find(key));
+
+ if (i == _imp->hashes.end() || i->second.first != mtime)
+ {
+ H_ hash(stream);
+ std::pair<time_t, std::string> value = std::make_pair(mtime, hash.hexsum());
+ stream.clear();
+ stream.seekg(0, std::ios::beg);
+
+ if (i != _imp->hashes.end())
+ i->second = value;
+ else
+ i = _imp->hashes.insert(std::make_pair(key, value)).first;
+ }
+
+ return i->second.second;
+}
+
+template const std::string MemoisedHashes::get<RMD160>(const FSEntry &, SafeIFStream &) const;
+template const std::string MemoisedHashes::get<SHA1>(const FSEntry &, SafeIFStream &) const;
+template const std::string MemoisedHashes::get<SHA256>(const FSEntry &, SafeIFStream &) const;
+template const std::string MemoisedHashes::get<MD5>(const FSEntry &, SafeIFStream &) const;
+
+template class PrivateImplementationPattern<MemoisedHashes>;
+template class InstantiationPolicy<MemoisedHashes, instantiation_method::SingletonTag>;
+
diff --git a/paludis/repositories/e/memoised_hashes.hh b/paludis/repositories/e/memoised_hashes.hh
new file mode 100644
index 0000000..7174316
--- /dev/null
+++ b/paludis/repositories/e/memoised_hashes.hh
@@ -0,0 +1,53 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2009 Piotr Jaroszyński
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_MEMOISED_HASHES_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_MEMOISED_HASHES_HH 1
+
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/fs_entry-fwd.hh>
+#include <paludis/util/safe_ifstream-fwd.hh>
+
+namespace paludis
+{
+ namespace erepository
+ {
+ class PALUDIS_VISIBLE MemoisedHashes :
+ public InstantiationPolicy<MemoisedHashes, instantiation_method::SingletonTag>,
+ private PrivateImplementationPattern<MemoisedHashes>
+ {
+ friend class InstantiationPolicy<MemoisedHashes, instantiation_method::SingletonTag>;
+
+ public:
+ template <typename H_>
+ const std::string get(const FSEntry & file, SafeIFStream & stream) const;
+
+ private:
+ MemoisedHashes();
+ ~MemoisedHashes();
+ };
+ }
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<erepository::MemoisedHashes>;
+ extern template class InstantiationPolicy<erepository::MemoisedHashes, instantiation_method::SingletonTag>;
+#endif
+}
+
+#endif