[Aptitude-svn-commit] r3990 - in branches/aptitude-0.3/aptitude: .
src/generic tests
Daniel Burrows
dburrows at costa.debian.org
Tue Aug 30 05:48:12 UTC 2005
Author: dburrows
Date: Tue Aug 30 05:48:08 2005
New Revision: 3990
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/generic/setset.h
branches/aptitude-0.3/aptitude/tests/test_setset.cc
Log:
Support narrowing searches using an extra relation.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Tue Aug 30 05:48:08 2005
@@ -2,6 +2,12 @@
* src/generic/setset.h, tests/test_setset.cc:
+ Make the necessary modifications to the 'setset' object to allow
+ extra relations on sets to be calculated (mainly to support
+ the subsumption relation as used to find conflicts).
+
+ * src/generic/setset.h, tests/test_setset.cc:
+
Add a data structure that stores a set of sets, optimized for
searching for a superset or a subset of a given set without
using imm::set's slow operator++.
Modified: branches/aptitude-0.3/aptitude/src/generic/setset.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/setset.h (original)
+++ branches/aptitude-0.3/aptitude/src/generic/setset.h Tue Aug 30 05:48:08 2005
@@ -49,7 +49,9 @@
typedef std::vector<imm::set<Val, Compare> > entries_list;
- typedef std::map<Val, std::set<typename entries_list::size_type> > index_type;
+ typedef std::pair<typename entries_list::size_type, Val> index_entry;
+
+ typedef std::map<Val, std::set<index_entry>, Compare> index_type;
index_type sets_by_key;
@@ -71,20 +73,24 @@
void operator()(const Val &v) const
{
- sets_by_key[v].insert(index);
+ sets_by_key[v].insert(index_entry(index, v));
}
};
// Used by find_subset to tally up intersections.
+ template<typename R>
struct tally_intersections
{
std::map<typename entries_list::size_type, unsigned int> &counts;
const index_type &sets_by_key;
+
+ const R &r;
public:
tally_intersections(std::map<typename entries_list::size_type, unsigned int> &_counts,
- const index_type &_sets_by_key)
- :counts(_counts), sets_by_key(_sets_by_key)
+ const index_type &_sets_by_key,
+ const R &_r)
+ :counts(_counts), sets_by_key(_sets_by_key), r(_r)
{
}
@@ -96,23 +102,34 @@
if(found != sets_by_key.end())
{
- const std::set<typename entries_list::size_type> &vals = found->second;
+ const std::set<index_entry> &vals = found->second;
- for(typename std::set<typename entries_list::size_type>::const_iterator vi
+ for(typename std::set<index_entry>::const_iterator vi
= vals.begin(); vi != vals.end(); ++vi)
- {
- typename std::map<typename entries_list::size_type, unsigned int>::iterator found
- = counts.find(*vi);
-
- if(found == counts.end())
- counts[*vi] = 1;
- else
- ++found->second;
- }
+ if(r(vi->second, v))
+ {
+ typename std::map<typename entries_list::size_type, unsigned int>::iterator found
+ = counts.find(vi->first);
+
+ if(found == counts.end())
+ counts[vi->first] = 1;
+ else
+ ++found->second;
+ }
}
}
};
+ template<class T>
+ struct universal_relation
+ {
+ public:
+ bool operator()(const T &t1, const T &t2) const
+ {
+ return true;
+ }
+ };
+
public:
setset(const Compare &c = Compare())
:sets_by_key(c)
@@ -139,13 +156,15 @@
}
/** Find an arbitrary element that is a subset of s. */
- const_iterator find_subset(const imm::set<Val, Compare> &s) const
+ template<typename R>
+ const_iterator find_subset(const imm::set<Val, Compare> &s,
+ const R &r) const
{
// For each element that intersects s, count how many times it
// intersects. If every element of a set intersects s (i.e., the
// count is equal to the set's size) then it is a subset of s.
std::map<typename entries_list::size_type, unsigned int> counts;
- s.for_each(tally_intersections(counts, sets_by_key));
+ s.for_each(tally_intersections<R>(counts, sets_by_key, r));
for(typename std::map<typename entries_list::size_type, unsigned int>::const_iterator ci
= counts.begin(); ci != counts.end(); ++ci)
@@ -158,6 +177,11 @@
return end();
}
+
+ const_iterator find_subset(const imm::set<Val, Compare> &s) const
+ {
+ return find_subset(s, universal_relation<Val>());
+ }
};
#endif // SETSET_H
Modified: branches/aptitude-0.3/aptitude/tests/test_setset.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/tests/test_setset.cc (original)
+++ branches/aptitude-0.3/aptitude/tests/test_setset.cc Tue Aug 30 05:48:08 2005
@@ -21,13 +21,13 @@
#include <src/generic/setset.h>
-template<typename T>
+template<typename T, typename Compare>
inline
-std::ostream &operator<<(std::ostream &out, const imm::set<T> &s)
+std::ostream &operator<<(std::ostream &out, const imm::set<T, Compare> &s)
{
out << "{";
- for(typename imm::set<T>::const_iterator i = s.begin(); i != s.end(); ++i)
+ for(typename imm::set<T, Compare>::const_iterator i = s.begin(); i != s.end(); ++i)
{
if(i != s.begin())
out << ", ";
@@ -44,6 +44,7 @@
CPPUNIT_TEST_SUITE(SetSetTest);
CPPUNIT_TEST(testSubsetSearch);
+ CPPUNIT_TEST(testSubsetPredicateSearch);
CPPUNIT_TEST_SUITE_END();
@@ -87,6 +88,85 @@
CPPUNIT_ASSERT(S.find_subset(t) != S.end());
}
+
+ struct HalfCmp
+ {
+ public:
+ bool operator()(int a, int b) const
+ {
+ return a/2 < b/2;
+ }
+ };
+
+ // Test searching for subsets of a set using subsumption.
+ void testSubsetPredicateSearch()
+ {
+ imm::set<int, HalfCmp> s1, s2, s3;
+
+ setset<int, HalfCmp> S;
+
+ s1.insert(5);
+ CPPUNIT_ASSERT(s1.contains(5));
+ CPPUNIT_ASSERT_EQUAL(s1.size(), 1U);
+ S.insert(s1);
+
+ s2.insert(6);
+ s2.insert(8);
+ CPPUNIT_ASSERT_EQUAL(s2.size(), 2U);
+ S.insert(s2);
+
+ s3.insert(9);
+ s3.insert(11);
+ CPPUNIT_ASSERT_EQUAL(s3.size(), 2U);
+ S.insert(s3);
+
+ imm::set<int, HalfCmp> t;
+
+ t.insert(5);
+
+ setset<int, HalfCmp>::const_iterator found = S.find_subset(t);
+ CPPUNIT_ASSERT(found != S.end());
+ CPPUNIT_ASSERT_EQUAL(*found, s1);
+
+ t.insert(10);
+ t.insert(11);
+ t.insert(15);
+ t.insert(17);
+
+ found = S.find_subset(t);
+ CPPUNIT_ASSERT(found != S.end());
+ CPPUNIT_ASSERT_EQUAL(*found, s1);
+
+ t.erase(5);
+
+ t.insert(4);
+ found = S.find_subset(t);
+ CPPUNIT_ASSERT(found != S.end());
+ CPPUNIT_ASSERT_EQUAL(*found, s1);
+
+ t.erase(4);
+ t.insert(7);
+ t.insert(8);
+ t.insertUpdate(11);
+
+ found = S.find_subset(t);
+ CPPUNIT_ASSERT(found != S.end());
+ CPPUNIT_ASSERT_EQUAL(*found, s2);
+
+ found = S.find_subset(t, std::greater<int>());
+
+ // Shouldn't show up since t contains 6 and 7, and the set is 6
+ // and 8.
+ CPPUNIT_ASSERT(found == S.end());
+
+ t.insertUpdate(10);
+ t.insertUpdate(8);
+
+ found = S.find_subset(t, std::greater<int>());
+
+ CPPUNIT_ASSERT(found != S.end());
+ CPPUNIT_ASSERT_EQUAL(*found, s3);
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(SetSetTest);
More information about the Aptitude-svn-commit
mailing list