[Aptitude-svn-commit] r4106 - in branches/aptitude-0.3/aptitude: src/generic tests

Daniel Burrows dburrows at costa.debian.org
Sun Sep 18 03:36:03 UTC 2005


Author: dburrows
Date: Sun Sep 18 03:36:03 2005
New Revision: 4106

Added:
   branches/aptitude-0.3/aptitude/tests/test_dense_setset.cc
Modified:
   branches/aptitude-0.3/aptitude/src/generic/dense_setset.h
   branches/aptitude-0.3/aptitude/tests/Makefile.am
Log:
Add my idea of a routine that finds a subset containing a particular element,
and add a test for the dense setset class.

Modified: branches/aptitude-0.3/aptitude/src/generic/dense_setset.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/dense_setset.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/dense_setset.h	Sun Sep 18 03:36:03 2005
@@ -304,6 +304,36 @@
   {
     return find_subset(s, universal_relation<Val>());
   }
+
+  /** Find an arbitrary element that is a subset of s and contains the
+   *  value v (or rather, contains an equivalent value v' for which
+   *  r(v', v) holds).  In the case where s is large, few elements
+   *  contain v, and the elements that do are small, this could be
+   *  substantially faster than find_subset.
+   */
+  template<typename R>
+  const_iterator find_subset_containing(const imm::set<Val, Compare> &s,
+					const Val &v,
+					const R &r) const
+  {
+    const std::vector<index_entry> &found = sets_by_key[extractid(v)];
+
+    for(typename std::vector<index_entry>::const_iterator
+	  i = found.begin(); i != found.end(); ++i)
+      {
+	if(r(i->second, v) &&
+	   s.contains(entries[i->first].s, r))
+	  return entries.begin() + i->first;
+      }
+
+    return entries.end();
+  }
+
+  const_iterator find_subset_containing(const imm::set<Val, Compare> &s,
+					const Val &v) const
+  {
+    return find_subset_containing(s, v, universal_relation<Val>());
+  }
 };
 
 template<typename Key, typename Val, typename IdFunc,
@@ -457,6 +487,25 @@
   {
     return const_iterator(S.find_subset(m.get_bindings(), r));
   }
+
+  template<typename R>
+  /** Search for a submap which contains a mapping corresponding to
+   *  the provided mapping; analogous to find_subset_containing.
+   */
+  const_iterator find_submap_containing(const imm::map<Key, Val, Compare> &m,
+					const std::pair<Key, Val> &mapping,
+					const R &r) const
+  {
+    return const_iterator(S.find_subset_containing(m.get_bindings(),
+						   mapping, r));
+  }
+
+  const_iterator find_submap_containing(const imm::map<Key, Val, Compare> &m,
+					const std::pair<Key, Val> &mapping) const
+  {
+    return const_iterator(S.find_subset_containing(m.get_bindings(),
+						   mapping));
+  }
 };
 
 #endif // DENSE_SETSET_H

Modified: branches/aptitude-0.3/aptitude/tests/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/tests/Makefile.am	(original)
+++ branches/aptitude-0.3/aptitude/tests/Makefile.am	Sun Sep 18 03:36:03 2005
@@ -18,6 +18,7 @@
 # way...
 test_SOURCES = \
 	main.cc \
+	test_dense_setset.cc \
 	test_misc.cc \
 	test_resolver.cc \
 	test_setset.cc \

Added: branches/aptitude-0.3/aptitude/tests/test_dense_setset.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/tests/test_dense_setset.cc	Sun Sep 18 03:36:03 2005
@@ -0,0 +1,276 @@
+// test_dense_setset.cc
+//
+//   Copyright (C) 2005 Daniel Burrows
+//
+//   This program is free software; you can redistribute it and/or
+//   modify it under the terms of the GNU General Public License as
+//   published by the Free Software Foundation; either version 2 of
+//   the License, or (at your option) any later version.
+//
+//   This program 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; see the file COPYING.  If not, write to
+//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+//   Boston, MA 02111-1307, USA.
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <src/generic/dense_setset.h>
+
+#include <iostream>
+
+template<typename Key, typename Val, typename Compare>
+inline
+std::ostream &operator<<(std::ostream &out, const imm::map<Key, Val, Compare> &s)
+{
+  out << "{";
+
+  for(typename imm::map<Key, Val, Compare>::const_iterator i = s.begin(); i != s.end(); ++i)
+    {
+      if(i != s.begin())
+	out << ", ";
+      out << i->first << " => " << i->second;
+    }
+
+  out << "}";
+
+  return out;
+}
+
+template<typename T, typename Compare>
+inline
+std::ostream &operator<<(std::ostream &out, const imm::set<T, Compare> &s)
+{
+  out << "{";
+
+  for(typename imm::set<T, Compare>::const_iterator i = s.begin(); i != s.end(); ++i)
+    {
+      if(i != s.begin())
+	out << ", ";
+      out << *i;
+    }
+
+  out << "}";
+
+  return out;
+}
+
+class Dense_SetsetTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE(Dense_SetsetTest);
+
+  CPPUNIT_TEST(testSubsetSearch);
+  CPPUNIT_TEST(testSubsetPredicateSearch);
+
+  CPPUNIT_TEST(testSubmapSearch);
+
+  CPPUNIT_TEST_SUITE_END();
+
+  struct identity
+  {
+    int operator()(int a) const
+    {
+      return a;
+    }
+  };
+
+public:
+  // Test searching for subsets of a set.
+  void testSubsetSearch()
+  {
+    imm::set<int> s1, s2, s3;
+
+    s1.insert(1);
+    s1.insert(2);
+    s1.insert(5);
+
+    s2.insert(5);
+
+    s3.insert(4);
+    s3.insert(5);
+
+    dense_setset<int, identity> S(10);
+
+    S.insert(s1);
+    S.insert(s2);
+    S.insert(s3);
+
+    imm::set<int> t;
+
+    t.insert(1);
+
+    dense_setset<int, identity>::const_iterator found = S.find_subset(t);
+    CPPUNIT_ASSERT(found == S.end());
+
+    t.insert(5);
+
+    found = S.find_subset(t);
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(s2, *found);
+
+    t.insert(6);
+    t.insert(4);
+    t.insert(3);
+
+    CPPUNIT_ASSERT(S.find_subset(t) != S.end());
+  }
+
+  struct HalfCmp
+  {
+  public:
+    bool operator()(int a, int b) const
+    {
+      return a/2 < b/2;
+    }
+  };
+
+  struct HalfExtractId
+  {
+  public:
+    bool operator()(int a) const
+    {
+      return a/2;
+    }
+  };
+
+  // Test searching for subsets of a set using subsumption.
+  void testSubsetPredicateSearch()
+  {
+    imm::set<int, HalfCmp> s1, s2, s3;
+
+    dense_setset<int, HalfExtractId, HalfCmp> S(20);
+
+    s1.insert(5);
+    CPPUNIT_ASSERT(s1.contains(5));
+    CPPUNIT_ASSERT_EQUAL(1U, s1.size());
+    S.insert(s1);
+
+    s2.insert(6);
+    s2.insert(8);
+    CPPUNIT_ASSERT_EQUAL(2U, s2.size());
+    S.insert(s2);
+
+    s3.insert(9);
+    s3.insert(11);
+    CPPUNIT_ASSERT_EQUAL(2U, s3.size());
+    S.insert(s3);
+
+    imm::set<int, HalfCmp> t;
+
+    t.insert(5);
+
+    dense_setset<int, HalfExtractId, HalfCmp>::const_iterator found = S.find_subset(t);
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(s1, *found);
+
+    found = S.find_subset_containing(t, 4);
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(s1, *found);
+
+    found = S.find_subset_containing(t, 8);
+    CPPUNIT_ASSERT(found == S.end());
+
+    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(s1, *found);
+    
+    t.erase(5);
+
+    t.insert(4);
+    found = S.find_subset(t);
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(s1, *found);
+
+    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(s2, *found);
+
+    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(s3, *found);
+
+    found = S.find_subset_containing(t, 6);
+
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(s2, *found);
+
+    found = S.find_subset_containing(t, 11);
+
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(s3, *found);
+  }
+
+  void testSubmapSearch()
+  {
+    imm::map<int, int> m1, m2, m3;
+
+    m1.put(1, 2);
+    m1.put(5, 2);
+
+    m2.put(1, 5);
+
+    m3.put(5, 2);
+    m3.put(6, 2);
+
+    dense_mapset<int, int, identity> S(10);
+
+    S.insert(m1);
+    S.insert(m2);
+    S.insert(m3);
+
+    imm::map<int, int> t;
+
+    t.put(1, 2);
+    t.put(3, 2);
+
+    dense_mapset<int, int, identity>::const_iterator found = S.find_submap(t);
+
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(m2, *found);
+
+    found = S.find_submap(t, std::equal_to<std::pair<int, int> >());
+    CPPUNIT_ASSERT(found == S.end());
+
+    t.put(5, 2);
+    found = S.find_submap(t, std::equal_to<std::pair<int, int> >());
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(m1, *found);
+
+    t.put(1, 5);
+    found = S.find_submap(t, std::equal_to<std::pair<int, int> >());
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(m2, *found);
+
+    t.erase(1);
+    t.put(6, 2);
+    found = S.find_submap(t);
+    CPPUNIT_ASSERT(found != S.end());
+    CPPUNIT_ASSERT_EQUAL(m3, *found);
+  }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Dense_SetsetTest);



More information about the Aptitude-svn-commit mailing list