aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-26 16:17:10 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-01-26 16:17:10 +0000
commitcb85301bfab7628319692643e7372e7a2f88a6e5 (patch)
treecd7f20c82ec859f431b2a674c9c8eaaae16fc301
parentfb4ee1c716fbbbe39a0627cff0c464151f20368d (diff)
downloadpaludis-cb85301bfab7628319692643e7372e7a2f88a6e5.tar.gz
paludis-cb85301bfab7628319692643e7372e7a2f88a6e5.tar.xz
Use tr1:: or __gnu_cxx:: hashes (if available) for PortageRepository, since it's a bottleneck. Fix silly bug that occurs if || ( ) dependencies are specified on the commandline.
-rw-r--r--configure.ac40
-rw-r--r--paludis/dep_list.cc21
-rw-r--r--paludis/dep_list.hh4
-rw-r--r--paludis/match_package.cc2
-rw-r--r--paludis/portage_repository.cc222
-rw-r--r--paludis/version_spec.cc7
-rw-r--r--paludis/version_spec.hh7
-rw-r--r--src/install.cc11
8 files changed, 281 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac
index a1f4905..87e52b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,6 +101,46 @@ int main(int, char **)
])
dnl }}}
+dnl {{{ check for hashes
+have_tr1_hashes=0
+have_ext_hashes=0
+AC_MSG_CHECKING([for a usable std::tr1::unordered_map<>])
+AC_COMPILE_IFELSE([
+#include <tr1/unordered_map>
+int main(int, char **)
+{
+ std::tr1::unordered_map<int, int> m;
+ m.insert(std::make_pair(1, 2));
+}
+],
+ [
+ AC_MSG_RESULT([yes])
+ have_tr1_hashes=1
+ ],
+ [
+ AC_MSG_RESULT([no])
+ AC_MSG_CHECKING([for a usable __gnu_cxx::hash_map<>])
+ AC_COMPILE_IFELSE([
+#include <ext/hash_map>
+int main(int, char **)
+{
+ __gnu_cxx::hash_map<int, int> m;
+ m.insert(std::make_pair(1, 2));
+}
+],
+ [
+ AC_MSG_RESULT([yes])
+ have_ext_hashes=1
+ ],
+ [
+ AC_MSG_RESULT([no])
+ ]
+ ]))
+
+AC_DEFINE_UNQUOTED([HAVE_TR1_HASHES], $have_tr1_hashes, [Do we have std::tr1:: hashes?])
+AC_DEFINE_UNQUOTED([HAVE_EXT_HASHES], $have_ext_hashes, [Do we have __gnu_cxx hashes?])
+dnl }}}
+
dnl {{{ we need libebt.
dnl don't use AC_CHECK_HEADER, it does silly things
AC_MSG_CHECKING([for libebt])
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index a7f3a85..166eed1 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -44,7 +44,7 @@ std::ostream &
paludis::operator<< (std::ostream & s, const DepListEntry & e)
{
s << e.get<dle_name>() << "-" << e.get<dle_version>() << ":"
- << e.get<dle_slot>() << "::" << e.get<dle_repository>();
+ << e.get<dle_metadata>()->get(vmk_slot) << "::" << e.get<dle_repository>();
return s;
}
@@ -328,7 +328,7 @@ DepList::visit(const PackageDepAtom * const p)
std::list<DepListEntry>::iterator merge_entry(
_implementation->merge_list.insert(_implementation->merge_list_insert_pos,
DepListEntry(match->get<pde_name>(), match->get<pde_version>(),
- SlotName(metadata->get(vmk_slot)), match->get<pde_repository>(),
+ metadata, match->get<pde_repository>(),
false, false, false)));
Save<std::list<DepListEntry>::iterator> old_merge_list_insert_pos(
@@ -385,22 +385,25 @@ struct IsViable :
public std::unary_function<bool, DepAtom::ConstPointer>
{
const Implementation<DepList> & _impl;
+ CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag> e;
IsViable(const Implementation<DepList> & impl) :
- _impl(impl)
+ _impl(impl),
+ e(0)
{
+ if (_impl.current_package)
+ e = CountedPtr<PackageDatabaseEntry, count_policy::ExternalCountTag>(
+ new PackageDatabaseEntry(
+ _impl.current_package->get<dle_name>(),
+ _impl.current_package->get<dle_version>(),
+ _impl.current_package->get<dle_repository>()));
}
bool operator() (DepAtom::ConstPointer a)
{
- PackageDatabaseEntry e(
- _impl.current_package->get<dle_name>(),
- _impl.current_package->get<dle_version>(),
- _impl.current_package->get<dle_repository>());
-
const UseDepAtom * const u(a->as_use_dep_atom());
if (0 != u)
- return _impl.environment->query_use(u->flag(), &e) ^ u->inverse();
+ return _impl.environment->query_use(u->flag(), e.raw_pointer()) ^ u->inverse();
else
return true;
}
diff --git a/paludis/dep_list.hh b/paludis/dep_list.hh
index 4432baf..3f0f968 100644
--- a/paludis/dep_list.hh
+++ b/paludis/dep_list.hh
@@ -45,7 +45,7 @@ namespace paludis
{
dle_name, ///< Package name
dle_version, ///< Package version
- dle_slot, ///< Package SLOT
+ dle_metadata, ///< Package SLOT
dle_repository, ///< Repository name
dle_has_predeps, ///< DEPEND (and RDEPEND if not rdepend_post) done?
dle_has_trypredeps, ///< RDEPEND (if rdepend_post) done?
@@ -61,7 +61,7 @@ namespace paludis
SmartRecordKeys<DepListEntryKeys, last_dle>,
SmartRecordKey<dle_name, QualifiedPackageName>,
SmartRecordKey<dle_version, VersionSpec>,
- SmartRecordKey<dle_slot, SlotName>,
+ SmartRecordKey<dle_metadata, VersionMetadata::ConstPointer>,
SmartRecordKey<dle_repository, RepositoryName>,
SmartRecordKey<dle_has_predeps, bool>,
SmartRecordKey<dle_has_trypredeps, bool>,
diff --git a/paludis/match_package.cc b/paludis/match_package.cc
index d5ca191..6d345e5 100644
--- a/paludis/match_package.cc
+++ b/paludis/match_package.cc
@@ -42,7 +42,7 @@ match_package_internals::do_match(
(*atom->version_spec_ptr())))
return false;
- if (atom->slot_ptr() && (*atom->slot_ptr() != entry->get<dle_slot>()))
+ if (atom->slot_ptr() && (atom->slot_ptr()->data() != entry->get<dle_metadata>()->get(vmk_slot)))
return false;
return true;
diff --git a/paludis/portage_repository.cc b/paludis/portage_repository.cc
index 37e9e08..5891401 100644
--- a/paludis/portage_repository.cc
+++ b/paludis/portage_repository.cc
@@ -17,6 +17,8 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+
#include "dir_iterator.hh"
#include "filter_insert_iterator.hh"
#include "fs_entry.hh"
@@ -39,8 +41,198 @@
#include <vector>
#include <deque>
+#include <limits>
+
+#if HAVE_TR1_HASHES
+# include <tr1/unordered_set>
+# include <tr1/unordered_map>
+#elif HAVE_EXT_HASHES
+# include <ext/hash_set>
+# include <ext/hash_map>
+#else
+# include <set>
+# include <map>
+#endif
+
using namespace paludis;
+#if HAVE_TR1_HASHES || HAVE_EXT_HASHES
+
+template <typename T_>
+struct CRCHash;
+
+template <>
+class CRCHash<QualifiedPackageName> :
+ std::unary_function<QualifiedPackageName, std::size_t>
+{
+ private:
+ static const std::size_t h_shift = std::numeric_limits<std::size_t>::digits - 5;
+ static const std::size_t h_mask = 0x1f << h_shift;
+
+ public:
+ std::size_t operator() (const QualifiedPackageName & val) const
+ {
+ const std::string & s1(val.get<qpn_category>().data()), s2(val.get<qpn_package>().data());
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < s1.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s1[t];
+ }
+
+ for (std::string::size_type t(0) ; t < s2.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s2[t];
+ }
+
+ return h;
+ }
+};
+
+template <typename Validated_>
+class CRCHash<Validated<std::string, Validated_> > :
+ std::unary_function<Validated<std::string, Validated_>, std::size_t>
+{
+ private:
+ static const std::size_t h_shift = std::numeric_limits<std::size_t>::digits - 5;
+ static const std::size_t h_mask = 0x1f << h_shift;
+
+ public:
+ std::size_t operator() (const Validated<std::string, Validated_> & val) const
+ {
+ const std::string & s1(val.data());
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < s1.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s1[t];
+ }
+
+ return h;
+ }
+};
+
+template <>
+class CRCHash<std::pair<QualifiedPackageName, VersionSpec> > :
+ std::unary_function<std::pair<QualifiedPackageName, VersionSpec>, std::size_t>
+{
+ private:
+ static const std::size_t h_shift = std::numeric_limits<std::size_t>::digits - 5;
+ static const std::size_t h_mask = 0x1f << h_shift;
+
+ public:
+ std::size_t operator() (const std::pair<QualifiedPackageName, VersionSpec> & val) const
+ {
+ const std::string & s1(val.first.get<qpn_category>().data()),
+ s2(val.first.get<qpn_package>().data());
+
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < s1.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s1[t];
+ }
+
+ for (std::string::size_type t(0) ; t < s2.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s2[t];
+ }
+
+ h ^= val.second.hash_value();
+
+ return h;
+ }
+};
+
+#endif
+
+#if HAVE_TR1_HASHES
+
+typedef std::tr1::unordered_map<QualifiedPackageName, VersionSpecCollection::Pointer,
+ CRCHash<QualifiedPackageName> > VersionsMap;
+
+typedef std::tr1::unordered_map<QualifiedPackageName, PackageDepAtom::ConstPointer,
+ CRCHash<QualifiedPackageName> > VirtualsMap;
+
+typedef std::tr1::unordered_map<QualifiedPackageName, std::deque<PackageDepAtom::ConstPointer>,
+ CRCHash<QualifiedPackageName> > RepositoryMaskMap;
+
+typedef std::tr1::unordered_map<CategoryNamePart, bool,
+ CRCHash<CategoryNamePart> > CategoryMap;
+
+typedef std::tr1::unordered_map<QualifiedPackageName, bool,
+ CRCHash<QualifiedPackageName> > PackagesMap;
+
+typedef std::tr1::unordered_map<UseFlagName, UseFlagState,
+ CRCHash<UseFlagName> > UseMap;
+
+typedef std::tr1::unordered_set<UseFlagName,
+ CRCHash<UseFlagName> > UseMaskSet;
+
+typedef std::tr1::unordered_map<std::pair<QualifiedPackageName, VersionSpec>,
+ VersionMetadata::Pointer, CRCHash<std::pair<QualifiedPackageName, VersionSpec> > > MetadataMap;
+
+#elif HAVE_EXT_HASHES
+
+typedef __gnu_cxx::hash_map<QualifiedPackageName, VersionSpecCollection::Pointer,
+ CRCHash<QualifiedPackageName> > VersionsMap;
+
+typedef __gnu_cxx::hash_map<QualifiedPackageName, PackageDepAtom::ConstPointer,
+ CRCHash<QualifiedPackageName> > VirtualsMap;
+
+typedef __gnu_cxx::hash_map<QualifiedPackageName, std::deque<PackageDepAtom::ConstPointer>,
+ CRCHash<QualifiedPackageName> > RepositoryMaskMap;
+
+typedef __gnu_cxx::hash_map<CategoryNamePart, bool,
+ CRCHash<CategoryNamePart> > CategoryMap;
+
+typedef __gnu_cxx::hash_map<QualifiedPackageName, bool,
+ CRCHash<QualifiedPackageName> > PackagesMap;
+
+typedef __gnu_cxx::hash_map<UseFlagName, UseFlagState,
+ CRCHash<UseFlagName> > UseMap;
+
+typedef __gnu_cxx::hash_set<UseFlagName,
+ CRCHash<UseFlagName> > UseMaskSet;
+
+typedef __gnu_cxx::hash_map<std::pair<QualifiedPackageName, VersionSpec>,
+ VersionMetadata::Pointer, CRCHash<std::pair<QualifiedPackageName, VersionSpec> > > MetadataMap;
+
+#else
+
+typedef std::map<QualifiedPackageName, VersionSpecCollection::Pointer> VersionsMap;
+
+typedef std::map<QualifiedPackageName, PackageDepAtom::ConstPointer> VirtualsMap;
+
+typedef std::map<QualifiedPackageName, std::deque<PackageDepAtom::ConstPointer> > RepositoryMaskMap;
+
+typedef std::map<CategoryNamePart, bool> CategoryMap;
+
+typedef std::map<QualifiedPackageName, bool> PackagesMap;
+
+typedef std::map<UseFlagName, UseFlagState> UseMap;
+
+typedef std::set<UseFlagName> UseMaskSet;
+
+typedef std::map<std::pair<QualifiedPackageName, VersionSpec>, VersionMetadata::Pointer> MetadataMap;
+
+#endif
+
namespace paludis
{
/**
@@ -67,32 +259,32 @@ namespace paludis
/// Our category names, and whether we have a fully loaded list
/// of package names for that category.
- mutable std::map<CategoryNamePart, bool> category_names;
+ mutable CategoryMap category_names;
/// Our package names, and whether we have a fully loaded list of
/// version specs for that category.
- mutable std::map<QualifiedPackageName, bool> package_names;
+ mutable PackagesMap package_names;
/// Our version specs for each package.
- mutable std::map<QualifiedPackageName, VersionSpecCollection::Pointer> version_specs;
+ mutable VersionsMap version_specs;
/// Metadata cache.
- mutable std::map<std::pair<QualifiedPackageName, VersionSpec>, VersionMetadata::Pointer> metadata;
+ mutable MetadataMap metadata;
/// Repository mask.
- mutable std::map<QualifiedPackageName, std::deque<PackageDepAtom::ConstPointer> > repo_mask;
+ mutable RepositoryMaskMap repo_mask;
/// Have repository mask?
mutable bool has_repo_mask;
/// Use mask.
- mutable std::set<UseFlagName> use_mask;
+ mutable UseMaskSet use_mask;
/// Use.
- mutable std::map<UseFlagName, UseFlagState> use;
+ mutable UseMap use;
/// Old style virtuals name mapping.
- mutable std::map<QualifiedPackageName, PackageDepAtom::ConstPointer> virtuals_map;
+ mutable VirtualsMap virtuals_map;
/// Have we loaded our profile yet?
mutable bool has_profile;
@@ -233,7 +425,7 @@ PortageRepository::do_has_package_named(const CategoryNamePart & c,
need_category_names();
need_virtual_names();
- std::map<CategoryNamePart, bool>::const_iterator cat_iter(
+ CategoryMap::iterator cat_iter(
_implementation->category_names.find(c));
if (_implementation->category_names.end() == cat_iter)
@@ -268,7 +460,7 @@ PortageRepository::do_category_names() const
need_category_names();
CategoryNamePartCollection::Pointer result(new CategoryNamePartCollection);
- std::map<CategoryNamePart, bool>::const_iterator i(_implementation->category_names.begin()),
+ CategoryMap::const_iterator i(_implementation->category_names.begin()),
i_end(_implementation->category_names.end());
for ( ; i != i_end ; ++i)
result->insert(i->first);
@@ -357,7 +549,7 @@ PortageRepository::need_version_names(const QualifiedPackageName & n) const
stringify(n.get<qpn_package>()));
if (CategoryNamePart("virtual") == n.get<qpn_category>() && ! path.exists())
{
- std::map<QualifiedPackageName, PackageDepAtom::ConstPointer>::iterator i(
+ VirtualsMap::iterator i(
_implementation->virtuals_map.find(n));
need_version_names(i->second->package());
@@ -432,7 +624,7 @@ PortageRepository::do_version_metadata(
cache_file /= stringify(c);
cache_file /= stringify(p) + "-" + stringify(v);
- std::map<QualifiedPackageName, PackageDepAtom::ConstPointer>::iterator vi;
+ VirtualsMap::iterator vi(_implementation->virtuals_map.end());
if (cache_file.is_regular_file())
{
std::ifstream cache(std::string(cache_file).c_str());
@@ -496,7 +688,7 @@ PortageRepository::do_query_repository_masks(const CategoryNamePart & c,
_implementation->has_repo_mask = true;
}
- std::map<QualifiedPackageName, std::deque<PackageDepAtom::ConstPointer> >::const_iterator r(
+ RepositoryMaskMap::iterator r(
_implementation->repo_mask.find(QualifiedPackageName(c, p)));
if (_implementation->repo_mask.end() == r)
return false;
@@ -538,7 +730,7 @@ PortageRepository::do_query_use(const UseFlagName & f) const
_implementation->has_profile = true;
}
- std::map<UseFlagName, UseFlagState>::const_iterator p;
+ UseMap::iterator p(_implementation->use.end());
if (_implementation->use.end() == ((p = _implementation->use.find(f))))
return use_unspecified;
else
@@ -567,7 +759,7 @@ PortageRepository::need_virtual_names() const
_implementation->add_profile(_implementation->profile.realpath());
_implementation->has_profile = true;
- for (std::map<QualifiedPackageName, PackageDepAtom::ConstPointer>::const_iterator
+ for (VirtualsMap::const_iterator
v(_implementation->virtuals_map.begin()), v_end(_implementation->virtuals_map.end()) ;
v != v_end ; ++v)
_implementation->package_names.insert(
diff --git a/paludis/version_spec.cc b/paludis/version_spec.cc
index e4140ed..fd40eec 100644
--- a/paludis/version_spec.cc
+++ b/paludis/version_spec.cc
@@ -304,6 +304,13 @@ VersionSpec::equal_star_compare(const VersionSpec & other) const
return true;
}
+std::size_t
+VersionSpec::hash_value() const
+{
+ /// \todo Improve this;
+ return _implementation->version_parts[0];
+}
+
std::ostream &
paludis::operator<< (std::ostream & s, const VersionSpec & v)
{
diff --git a/paludis/version_spec.hh b/paludis/version_spec.hh
index 0a41714..c56dd8a 100644
--- a/paludis/version_spec.hh
+++ b/paludis/version_spec.hh
@@ -95,6 +95,13 @@ namespace paludis
* Comparison function for =* depend operator.
*/
bool equal_star_compare(const VersionSpec & other) const;
+
+ /**
+ * Fetch a hash value, used to avoid exposing our internals to
+ * CRCHash.
+ */
+ std::size_t hash_value() const;
+
};
/**
diff --git a/src/install.cc b/src/install.cc
index ecdc672..6593507 100644
--- a/src/install.cc
+++ b/src/install.cc
@@ -95,17 +95,16 @@ do_install()
cout << "::" << dep->get<p::dle_repository>();
/* display slot name, unless it's 0 */
- if (p::SlotName("0") != dep->get<p::dle_slot>())
- cout << colour(cl_slot, " {:" + stringify(dep->get<p::dle_slot>()) + "}");
+ if ("0" != dep->get<p::dle_metadata>()->get(p::vmk_slot))
+ cout << colour(cl_slot, " {:" + p::stringify(dep->get<p::dle_metadata>()->get(p::vmk_slot)) + "}");
- /* fetch metadata */
+ /* fetch db entry */
p::PackageDatabaseEntry p(p::PackageDatabaseEntry(dep->get<p::dle_name>(),
dep->get<p::dle_version>(), dep->get<p::dle_repository>()));
- p::VersionMetadata::ConstPointer metadata(env->package_database()->fetch_metadata(p));
/* display USE flags */
- for (p::VersionMetadata::IuseIterator i(metadata->begin_iuse()),
- i_end(metadata->end_iuse()) ; i != i_end ; ++i)
+ for (p::VersionMetadata::IuseIterator i(dep->get<p::dle_metadata>()->begin_iuse()),
+ i_end(dep->get<p::dle_metadata>()->end_iuse()) ; i != i_end ; ++i)
{
if (env->query_use(*i, &p))
cout << " " << colour(cl_flag_on, *i);