[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