[Debtags-commits] [svn] r1975 - in tagcoll/2.0: . bench tagcoll tagcoll/coll tagcoll/tests tools

Enrico Zini enrico at costa.debian.org
Sat Sep 30 13:34:16 UTC 2006


Author: enrico
Date: Sat Sep 30 13:34:13 2006
New Revision: 1975

Modified:
   tagcoll/2.0/   (props changed)
   tagcoll/2.0/bench/collection.cc
   tagcoll/2.0/tagcoll/TextFormat.cc
   tagcoll/2.0/tagcoll/coll/patched.h
   tagcoll/2.0/tagcoll/coll/patched.tcc
   tagcoll/2.0/tagcoll/patch.h
   tagcoll/2.0/tagcoll/patch.tcc
   tagcoll/2.0/tagcoll/tests/test-utils.tcc
   tagcoll/2.0/tools/tagcoll.cc
Log:
 r3455 at viaza:  enrico | 2006-09-30 15:34:05 +0200
 Considerable speedup in coll::patched obtained by also maintaining the inverted patch list


Modified: tagcoll/2.0/bench/collection.cc
==============================================================================
--- tagcoll/2.0/bench/collection.cc	(original)
+++ tagcoll/2.0/bench/collection.cc	Sat Sep 30 13:34:13 2006
@@ -413,6 +413,5 @@
 #include <tagcoll/coll/simple.tcc>
 #include <tagcoll/coll/fast.tcc>
 #include <tagcoll/coll/patched.tcc>
-#include <tagcoll/Patches.tcc>
 
 /* vim:set ts=4 sw=4: */

Modified: tagcoll/2.0/tagcoll/TextFormat.cc
==============================================================================
--- tagcoll/2.0/tagcoll/TextFormat.cc	(original)
+++ tagcoll/2.0/tagcoll/TextFormat.cc	Sat Sep 30 13:34:13 2006
@@ -205,7 +205,6 @@
 }
 }
 
-#include <tagcoll/patch.tcc>
 #include <tagcoll/TextFormat.tcc>
 
 // vim:set ts=4 sw=4:

Modified: tagcoll/2.0/tagcoll/coll/patched.h
==============================================================================
--- tagcoll/2.0/tagcoll/coll/patched.h	(original)
+++ tagcoll/2.0/tagcoll/coll/patched.h	Sat Sep 30 13:34:13 2006
@@ -50,12 +50,18 @@
 class Patched : public coll::Collection< Patched<ROCOLL> >
 {
 public:
-	typedef Patch<
+	typedef tagcoll::Patch<
 		typename coll_traits<ROCOLL>::item_type,
 		typename coll_traits<ROCOLL>::tag_type> Patch;
-	typedef PatchList<
+	typedef tagcoll::PatchList<
 		typename coll_traits<ROCOLL>::item_type,
 		typename coll_traits<ROCOLL>::tag_type> Patches;
+	typedef tagcoll::Patch<
+		typename coll_traits<ROCOLL>::tag_type,
+		typename coll_traits<ROCOLL>::item_type> RPatch;
+	typedef tagcoll::PatchList<
+		typename coll_traits<ROCOLL>::tag_type,
+		typename coll_traits<ROCOLL>::item_type> RPatches;
 
 protected:
 	typedef typename coll_traits<ROCOLL>::item_type Item;
@@ -65,6 +71,7 @@
 
 	const ROCOLL& coll;
 	Patches m_changes;
+	RPatches m_rchanges;
 
 #if 0
 	virtual void consumeItem(const ITEM& item, const std::set<TAG>& tags);
@@ -160,12 +167,7 @@
 	Patched(const ROCOLL& coll) : coll(coll) {}
 
 	template<typename ITEMS, typename TAGS>
-	void insert(const ITEMS& items, const TAGS& tags)
-	{
-		for (typename ITEMS::const_iterator i = items.begin();
-				i != items.end(); ++i)
-			m_changes.addPatch(Patch(*i, tags, TagSet()));
-	}
+	void insert(const ITEMS& items, const TAGS& tags);
 
 	template<typename ITEMS>
 	void insert(const ITEMS& items, const wibble::Empty<Tag>& tags)
@@ -186,7 +188,7 @@
 	/**
 	 * Throw away all changes previously applied to this collection
 	 */
-	void resetChanges() { m_changes.clear(); }
+	void resetChanges() { m_changes.clear(); m_rchanges.clear(); }
 
 	/**
 	 * Set the changes list to a specific patch list
@@ -204,7 +206,10 @@
 	{
 		return m_changes.patch(item, coll.getTagsOfItem(item));
 	}
-	ItemSet getItemsHavingTag(const typename coll_traits<ROCOLL>::tag_type& tag) const;
+	ItemSet getItemsHavingTag(const typename coll_traits<ROCOLL>::tag_type& tag) const
+	{
+		return m_rchanges.patch(tag, coll.getItemsHavingTag(tag));
+	}
 
 	ItemSet getTaggedItems() const;
 	TagSet getAllTags() const;
@@ -213,7 +218,7 @@
 
 	unsigned int getCardinality(const Tag& tag) const;
 
-	void applyChange(const Patches& change);
+	void applyChange(const Patches& change) { this->addChanges(change); }
 
 #if 0
 	template<typename OUT>

Modified: tagcoll/2.0/tagcoll/coll/patched.tcc
==============================================================================
--- tagcoll/2.0/tagcoll/coll/patched.tcc	(original)
+++ tagcoll/2.0/tagcoll/coll/patched.tcc	Sat Sep 30 13:34:13 2006
@@ -32,89 +32,81 @@
 namespace tagcoll {
 namespace coll {
 
+template<typename ROCOLL> template<typename ITEMS, typename TAGS>
+void Patched<ROCOLL>::insert(const ITEMS& items, const TAGS& tags)
+{
+	Patches changes;
+	for (typename ITEMS::const_iterator i = items.begin();
+			i != items.end(); ++i)
+		changes.addPatch(Patch(*i, tags, TagSet()));
+	addChanges(changes);
+}
+
+
 template<typename ROCOLL>
 void Patched<ROCOLL>::clear()
 {
 	// Remove all patches
 	m_changes.clear();
+	m_rchanges.clear();
 
 	// Add all tagsets of the underlying collection as removed tags in the patch
 	for (typename ROCOLL::const_iterator i = coll.begin();
 			i != coll.end(); ++i)
-		m_changes.addPatch(Patch(i->first, std::set< typename coll_traits<ROCOLL>::tag_type >(), i->second));
-}
-
-template<typename ROCOLL>
-typename coll_traits<ROCOLL>::itemset_type Patched<ROCOLL>::getItemsHavingTag(const Tag& tag) const
-{
-	ItemSet items(coll.getItemsHavingTag(tag));
-	ItemSet res;
-
-	// Check items in coll first
-	for (typename ItemSet::const_iterator i = items.begin(); i != items.end(); ++i)
-		// If they are unmodified, then we can trust coll.getItems
-		if (m_changes.find(*i) == m_changes.end())
-			res |= *i;
-
-	// Then check items in the patch
-	for (typename Patches::const_iterator i = m_changes.begin();
-			i != m_changes.end(); i++)
-		if (utils::set_contains(m_changes.patch(i->first, coll.getTagsOfItem(i->first)), tag))
-			res |= i->first;
+	{
+		m_changes.addPatch(Patch(i->first, std::set<Tag>(), i->second));
 
-	return res;
+		for (typename TagSet::const_iterator j = i->second.begin();
+				j != i->second.end(); ++j)
+			m_rchanges.addPatch(Patch(*j, wibble::Empty<Tag>(), wibble::singleton(i->first)));
+	}
 }
 
 template<typename ROCOLL>
 void Patched<ROCOLL>::setChanges(const Patches& changes)
 {
 	this->m_changes.clear();
+	this->m_rchanges.clear();
 	
-	// Simplify the patch against the contents of `coll' before adding it.
-	for (typename Patches::const_iterator i = changes.begin(); i != changes.end(); i++)
-		// Consider only valid items
-		if (i->first != Item())
-		{
-			Patch newChange(i->second);
-
-			TagSet tags(coll.getTagsOfItem(i->first));
-			newChange.removeRedundant(tags);
-
-			// Empty patches are filtered out by PatchList so we don't need to do
-			// it here
-			this->m_changes.addPatch(newChange);
-		}
+	addChanges(changes);
 }
 
 template<typename ROCOLL>
 void Patched<ROCOLL>::addChanges(const Patches& changes)
 {
-	Patches ch(m_changes);
-
-	ch.addPatch(changes);
+	// Simplify the patch against the contents of `coll' before adding it.
+	for (typename Patches::const_iterator i = changes.begin(); i != changes.end(); ++i)
+		// Consider only valid items
+		if (i->first != Item())
+		{
+			// Merge with existing patches
+			this->m_changes.addPatch(i->second);
+			// Simplify the result
+			this->m_changes.removeRedundant(i->first, coll.getTagsOfItem(i->first));
+		}
 
-	setChanges(ch);
+	RPatches rchanges;
+	rchanges.addPatchInverted(changes);
+	for (typename RPatches::const_iterator i = rchanges.begin(); i != rchanges.end(); ++i)
+		// Consider only valid tags
+		if (i->first != Tag())
+		{
+			// Merge with existing patches
+			this->m_rchanges.addPatch(i->second);
+			// Simplify the result
+			this->m_rchanges.removeRedundant(i->first, coll.getItemsHavingTag(i->first));
+		}
 }
 
 template<typename ROCOLL>
 bool Patched<ROCOLL>::hasTag(const Tag& tag) const
 {
-	ItemSet items(coll.getItemsHavingTag(tag));
-
-	// Check items in coll first
-	for (typename ItemSet::const_iterator i = items.begin();
-			i != items.end(); i++)
-		// If they are unmodified, then we can trust coll.getItems
-		if (m_changes.find(*i) == m_changes.end())
-			return true;
-
-	// Then check items in the patch
-	for (typename Patches::const_iterator i = m_changes.begin();
-			i != m_changes.end(); i++)
-		if (utils::set_contains(i->second.added, tag))
-			return true;
-
-	return false;
+	typename RPatches::const_iterator i = m_rchanges.find(tag);
+	if (i == m_rchanges.end())
+		return coll.hasTag(tag);
+	if (! i->second.added.empty())
+		return true;
+	return !this->getItemsHavingTag(tag).empty();
 }
 
 template<typename ROCOLL>
@@ -122,18 +114,28 @@
 {
 	ItemSet res(coll.getTaggedItems());
 	for (typename Patches::const_iterator i = m_changes.begin();
-			i != m_changes.end(); i++)
-		res |= i->first;
+			i != m_changes.end(); ++i)
+		if (!i->second.added.empty())
+			// Add packages for which tags are added
+			res |= i->first;
+		else if (getTagsOfItem(i->first).empty())
+			// Remove the packages to which the patch removes all tags
+			res -= i->first;
 	return res;
 }
 
 template<typename ROCOLL>
 typename coll_traits<ROCOLL>::tagset_type Patched<ROCOLL>::getAllTags() const
 {
-	TagSet res;
-	for (typename Patched<ROCOLL>::const_iterator i = begin();
-			i != end(); ++i)
-		res |= i->second;
+	TagSet res(coll.getAllTags());
+	for (typename RPatches::const_iterator i = m_rchanges.begin();
+			i != m_rchanges.end(); ++i)
+		if (!i->second.added.empty())
+			// Add tags for which packages are added
+			res |= i->first;
+		else if (coll.getCardinality(i->first) - i->second.removed.size() <= 0)
+			// Remove the tags to which the patch removes all items
+			res -= i->first;
 	return res;
 }
 
@@ -185,38 +187,20 @@
 #endif
 
 template<typename ROCOLL>
-void Patched<ROCOLL>::applyChange(const Patches& change)
-{
-	for (typename Patches::const_iterator i = change.begin();
-			i != change.end(); i++)
-	{
-		Patch newChange(i->second);
-		newChange.removeRedundant(getTagsOfItem(i->first));
-		m_changes.addPatch(newChange);
-	}
-}
-
-template<typename ROCOLL>
 unsigned int Patched<ROCOLL>::getCardinality(const Tag& tag) const
 {
-	unsigned int card = coll.getCardinality(tag);
-
-	for (typename Patches::const_iterator i = m_changes.begin();
-			i != m_changes.end(); i++)
-	{
-		if (utils::set_contains(i->second.added, tag))
-			card++;
-		else if (utils::set_contains(i->second.removed, tag))
-			card--;
-	}
-
-	return card;
+	typename RPatches::const_iterator i = m_rchanges.find(tag);
+	if (i == m_rchanges.end())
+		return coll.getCardinality(tag);
+	else
+		return coll.getCardinality(tag) + i->second.added.size() - i->second.removed.size();
 }
 
 }
 }
 
 #include <tagcoll/coll/base.tcc>
+#include <tagcoll/patch.tcc>
 
 #endif
 

Modified: tagcoll/2.0/tagcoll/patch.h
==============================================================================
--- tagcoll/2.0/tagcoll/patch.h	(original)
+++ tagcoll/2.0/tagcoll/patch.h	Sat Sep 30 13:34:13 2006
@@ -158,6 +158,12 @@
 	void addPatchInverted(const PatchList<TAG, ITEM>& patches);
 
 	/**
+	 * If the PatchList contains the give item, invoke
+	 * Patch::removeRedundant(tags) on its patch
+	 */
+	void removeRedundant(const ITEM& item, const std::set<TAG>& tags);
+
+	/**
 	 * Patch a tagged item
 	 *
 	 * @return

Modified: tagcoll/2.0/tagcoll/patch.tcc
==============================================================================
--- tagcoll/2.0/tagcoll/patch.tcc	(original)
+++ tagcoll/2.0/tagcoll/patch.tcc	Sat Sep 30 13:34:13 2006
@@ -105,6 +105,14 @@
 }
 
 template <class ITEM, class TAG>
+void PatchList<ITEM, TAG>::removeRedundant(const ITEM& item, const std::set<TAG>& tags)
+{
+	iterator i = this->find(item);
+	if (i == this->end()) return;
+	i->second.removeRedundant(tags);
+}
+
+template <class ITEM, class TAG>
 std::set<TAG> PatchList<ITEM, TAG>::patch(const ITEM& item, const std::set<TAG>& tagset) const
 {
 	// Find the patch record for this item

Modified: tagcoll/2.0/tagcoll/tests/test-utils.tcc
==============================================================================
--- tagcoll/2.0/tagcoll/tests/test-utils.tcc	(original)
+++ tagcoll/2.0/tagcoll/tests/test-utils.tcc	Sat Sep 30 13:34:13 2006
@@ -367,7 +367,6 @@
 	// Test handling of changes
 	PatchList<string, string> change;
 	Patch<string, string> p("tagged");
-	tagset.clear();
 	p.remove("tag1");
 	p.remove("tag2");
 	change.addPatch(p);

Modified: tagcoll/2.0/tools/tagcoll.cc
==============================================================================
--- tagcoll/2.0/tools/tagcoll.cc	(original)
+++ tagcoll/2.0/tools/tagcoll.cc	Sat Sep 30 13:34:13 2006
@@ -49,7 +49,7 @@
 
 #include <tagcoll/coll/simple.h>
 #include <tagcoll/Implications.h>
-#include <tagcoll/Patches.h>
+#include <tagcoll/patch.h>
 #include <tagcoll/DerivedTags.h>
 #include <tagcoll/coll/fast.h>
 
@@ -831,7 +831,6 @@
 }
 
 #include <tagcoll/TextFormat.tcc>
-#include <tagcoll/Patches.tcc>
 #include <tagcoll/Implications.tcc>
 #include <tagcoll/SmartHierarchy.tcc>
 #include <tagcoll/stream/filters.tcc>



More information about the Debtags-commits mailing list