[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