[Debtags-commits] [svn] r1749 - in tagcoll/2.0: . tagcoll
tagcoll/coll
Enrico Zini
enrico at costa.debian.org
Tue May 9 22:36:45 UTC 2006
Author: enrico
Date: Tue May 9 22:36:42 2006
New Revision: 1749
Added:
tagcoll/2.0/tagcoll/coll/fast.tcc
Modified:
tagcoll/2.0/ (props changed)
tagcoll/2.0/tagcoll/Makefile.am
tagcoll/2.0/tagcoll/SmartHierarchy.cc
tagcoll/2.0/tagcoll/SmartHierarchy.h
tagcoll/2.0/tagcoll/coll/base.h
tagcoll/2.0/tagcoll/coll/fast.cc
Log:
r2675 at viaza: enrico | 2006-05-09 17:18:35 -0500
Refactored SmartHierarchy to use Fast instead of CardinalityStore
Split fast in .cc and .tcc
Modified: tagcoll/2.0/tagcoll/Makefile.am
==============================================================================
--- tagcoll/2.0/tagcoll/Makefile.am (original)
+++ tagcoll/2.0/tagcoll/Makefile.am Tue May 9 22:36:42 2006
@@ -26,7 +26,7 @@
coll/simple.h \
coll/simple.cc \
coll/fast.h \
- coll/fast.cc \
+ coll/fast.tcc \
coll/patched.h \
coll/patched.cc \
\
@@ -54,10 +54,11 @@
\
CardinalityStore.h \
CardinalityStore.cc \
- SmartHierarchy.h \
- SmartHierarchy.cc \
experiments.h
+# SmartHierarchy.h \
+# SmartHierarchy.cc
+
lib_LTLIBRARIES = libtagcoll.la
libtagcoll_la_SOURCES = \
input/base.cc \
@@ -91,13 +92,14 @@
\
DerivedTags.cc \
\
+ SmartHierarchy.cc \
+ \
test-utils.cc
# IntDiskIndex.cc \
# BasicStringDiskIndex.cc \
# \
# CardinalityStore.cc \
-# SmartHierarchy.cc \
# \
# experiments.cc
Modified: tagcoll/2.0/tagcoll/SmartHierarchy.cc
==============================================================================
--- tagcoll/2.0/tagcoll/SmartHierarchy.cc (original)
+++ tagcoll/2.0/tagcoll/SmartHierarchy.cc Tue May 9 22:36:42 2006
@@ -47,18 +47,18 @@
//template class SmartHierarchyNode<Debtags::Package*>;
//template class CleanSmartHierarchyNode<Debtags::Package*>;
-template<class ITEM, class TAG>
-HierarchyNode<ITEM, TAG>::~HierarchyNode()
+template<typename COLL>
+HierarchyNode<COLL>::~HierarchyNode()
{
if (coll)
delete coll;
- for (typename vector<HierarchyNode<ITEM, TAG>*>::iterator i = children.begin();
+ for (typename vector<HierarchyNode<COLL>*>::iterator i = children.begin();
i != children.end(); i++)
delete *i;
}
-template<class ITEM, class TAG>
-void SmartHierarchyNode<ITEM, TAG>::expand()
+template<typename COLL>
+void SmartHierarchyNode<COLL>::expand()
{
/*
Define the "cardinality" of a tag as the number of items in the collection
@@ -81,7 +81,7 @@
fprintf(stderr, "%d tags, %d tagsets\n", coll->tagCount(), coll->tagsetCount());
#endif
- if (flattenThreshold > 0 && this->coll->itemCount() < flattenThreshold)
+ if (flattenThreshold > 0 && this->coll->itemCount() < (unsigned)flattenThreshold)
{
this->items = unexpandedItems | this->coll->getTaggedItems();
#ifdef VERB_FLATTEN
@@ -92,21 +92,18 @@
{
this->items = unexpandedItems;
- std::set<TAG> processed;
- CardinalityStore<ITEM, TAG> workcoll = *this->coll;
+ COLL workcoll = *this->coll;
while (1)
{
// Choose the tag T with the highest cardinality
- int card;
- TAG tag = workcoll.findTagWithMaxCardinalityNotIn(processed, &card);
+ size_t card;
+ TAG tag = workcoll.findTagWithMaxCardinality(card);
// Stop condition: there are no more tags left
if (card == 0)
break;
- processed.insert(tag);
-
#ifdef VERB1
//print_spaces(nest);
fprintf(stderr, " Processed: ");
@@ -122,10 +119,17 @@
#endif
// Append the child node
- this->children.push_back(new SmartHierarchyNode(this, tag, workcoll, flattenThreshold));
+ this->children.push_back(smartHierarchyNode(
+ this, tag, workcoll.getChildCollection(tag), flattenThreshold));
- // Remove all tags already fully implied by the chosen one
- workcoll = workcoll.getCollectionWithoutTags(processed);
+ // Remove the tag we chosen
+ workcoll.removeTag(tag);
+
+ // Also remove tags already fully implied by the chosen one
+ std::set<TAG> impls = workcoll.getTagsImplying(tag);
+ for (typename std::set<TAG>::const_iterator i = impls.begin();
+ i != impls.end(); ++i)
+ workcoll.removeTag(*i);
}
}
@@ -133,8 +137,8 @@
this->coll = 0;
}
-template<class ITEM, class TAG>
-void CleanSmartHierarchyNode<ITEM, TAG>::expand()
+template<typename COLL>
+void CleanSmartHierarchyNode<COLL>::expand()
{
/* Same as SmartHierarchyNode, except it create CleanSmartHierarchyNode
* children and performs merging of equivalent tags*/
@@ -142,35 +146,39 @@
// FIXME: another way is to use a virtual HiearchyNode* createChildNode(parms) method
//fprintf(stderr, "CSHN::expand\n");
- this->coll->mergeEquivalentTags();
+ //this->coll->mergeEquivalentTags();
//fprintf(stderr, "CSHN::merged\n");
- if (this->flattenThreshold > 0 && this->coll->itemCount() < this->flattenThreshold)
+ if (this->flattenThreshold > 0 && this->coll->itemCount() < (unsigned)this->flattenThreshold)
this->items = this->unexpandedItems | this->coll->getTaggedItems();
else
{
this->items = this->unexpandedItems;
- std::set<TAG> processed;
- CardinalityStore<ITEM, TAG> workcoll = *this->coll;
+ COLL workcoll = *this->coll;
while (1)
{
// Choose the tag T with the highest cardinality
- int card;
- TAG tag = workcoll.findTagWithMaxCardinalityNotIn(processed, &card);
+ size_t card;
+ TAG tag = workcoll.findTagWithMaxCardinality(card);
// Stop condition: there are no more tags left
if (card == 0)
break;
- processed.insert(tag);
-
// Append the child node
- this->children.push_back(new CleanSmartHierarchyNode(this, tag, workcoll, this->flattenThreshold));
+ this->children.push_back(cleanSmartHierarchyNode(
+ this, tag, workcoll.getChildCollection(tag), this->flattenThreshold));
+
+ // Remove the tag we chosen
+ workcoll.removeTag(tag);
// Remove all tags already fully implied by the chosen one
- workcoll = workcoll.getCollectionWithoutTags(processed);
+ std::set<TAG> impls = workcoll.getTagsImplying(tag);
+ for (typename std::set<TAG>::const_iterator i = impls.begin();
+ i != impls.end(); ++i)
+ workcoll.removeTag(*i);
}
}
@@ -202,26 +210,18 @@
this->coll = 0;
}
-#ifndef INSTANTIATING_TEMPLATES
-#include <string>
-
-namespace tagcoll {
- template class HierarchyNode<std::string, std::string>;
- template class SmartHierarchyNode<std::string, std::string>;
- template class CleanSmartHierarchyNode<std::string, std::string>;
-}
-#endif
-
#ifdef COMPILE_TESTSUITE
#include <tests/test-utils.h>
#include <tagcoll/TextFormat.h>
-#include <tagcoll/StringParserInput.h>
+#include <tagcoll/input/string.h>
+#include <tagcoll/coll/fast.h>
namespace wibble {
namespace tut {
+using namespace tagcoll;
using namespace tagcoll::tests;
struct tagcoll_smarthierarchy_shar {
@@ -231,18 +231,30 @@
template<> template<>
void to::test<1>()
{
- StringParserInput input_coll(
+ std::string input_coll(
"a: b, c\n"
"b:\n"
"c: \n"
"d: c::D, e::F, f::g\n"
);
+ coll::Fast<string, string> coll;
+ parseCollection(input_coll, inserter(coll));
+
+ HierarchyNode< coll::Fast<string, string> >* root = smartHierarchyNode("_top", coll, 2);
+ delete root;
+
+ root = cleanSmartHierarchyNode("_top", coll, 2);
+ delete root;
+
//ensure(false);
}
}
}
+#include <tagcoll/coll/fast.tcc>
+#include <tagcoll/TextFormat.tcc>
+
#endif
// vim:set ts=4 sw=4:
Modified: tagcoll/2.0/tagcoll/SmartHierarchy.h
==============================================================================
--- tagcoll/2.0/tagcoll/SmartHierarchy.h (original)
+++ tagcoll/2.0/tagcoll/SmartHierarchy.h Tue May 9 22:36:42 2006
@@ -23,32 +23,37 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <tagcoll/CardinalityStore.h>
+#include <tagcoll/coll/base.h>
#include <vector>
namespace tagcoll
{
// Base class for the auto-expanding tree nodes
-template<class ITEM, class TAG>
+template<typename COLL>
class HierarchyNode
{
protected:
+ typedef typename coll::coll_traits<COLL>::item_type ITEM;
+ typedef typename coll::coll_traits<COLL>::tag_type TAG;
+ typedef typename coll::coll_traits<COLL>::itemset_type ITEMSET;
+ typedef typename coll::coll_traits<COLL>::tagset_type TAGSET;
+
// Tag name
TAG _tag;
- CardinalityStore<ITEM, TAG>* coll;
- std::vector<HierarchyNode<ITEM, TAG>*> children;
+ COLL* coll;
+ std::vector<HierarchyNode<COLL>*> children;
std::set<ITEM> items;
- HierarchyNode<ITEM, TAG>* _parent;
+ HierarchyNode<COLL>* _parent;
public:
- HierarchyNode(const TAG& tag, const CardinalityStore<ITEM, TAG>& coll)
- : _tag(tag), coll(new CardinalityStore<ITEM, TAG>(coll)), _parent(0) {}
- HierarchyNode(HierarchyNode<ITEM, TAG>* parent, const TAG& tag, const CardinalityStore<ITEM, TAG>& coll)
- : _tag(tag), coll(new CardinalityStore<ITEM, TAG>(coll)), _parent(parent) {}
+ HierarchyNode(const TAG& tag, const COLL& coll)
+ : _tag(tag), coll(new COLL(coll)), _parent(0) {}
+ HierarchyNode(HierarchyNode<COLL>* parent, const TAG& tag, const COLL& coll)
+ : _tag(tag), coll(new COLL(coll)), _parent(parent) {}
virtual ~HierarchyNode();
- typedef typename std::vector<HierarchyNode<ITEM, TAG>*>::iterator iterator;
+ typedef typename std::vector<HierarchyNode<COLL>*>::iterator iterator;
// Get the node tag (const version)
const TAG& tag() const { return _tag; }
@@ -57,7 +62,7 @@
TAG tag() { return _tag; }
// Get the parent of this node (0 if it is the root node)
- HierarchyNode<ITEM, TAG>* parent() const { return _parent; }
+ HierarchyNode<COLL>* parent() const { return _parent; }
// Expand the collection in the children of this node
virtual void expand() = 0;
@@ -85,7 +90,7 @@
}
// Get a child node by index
- HierarchyNode<ITEM, TAG>* operator[](int idx)
+ HierarchyNode<COLL>* operator[](int idx)
{
if (coll)
expand();
@@ -103,10 +108,15 @@
// Hierarchy of items where information is replicated to acheive intuitive
// navigability of the resulting structure
-template<class ITEM, class TAG>
-class SmartHierarchyNode : public HierarchyNode<ITEM, TAG>
+template<typename COLL>
+class SmartHierarchyNode : public HierarchyNode<COLL>
{
protected:
+ typedef typename HierarchyNode<COLL>::ITEM ITEM;
+ typedef typename HierarchyNode<COLL>::TAG TAG;
+ typedef typename HierarchyNode<COLL>::ITEMSET ITEMSET;
+ typedef typename HierarchyNode<COLL>::TAGSET TAGSET;
+
std::set<ITEM> unexpandedItems;
// Threshold of child items below which the child hierarchy is flattened
@@ -117,18 +127,18 @@
virtual void expand();
public:
- SmartHierarchyNode(const TAG& tag, const CardinalityStore<ITEM, TAG>& coll, int flattenThreshold = 0)
+ SmartHierarchyNode(const TAG& tag, const COLL& coll, int flattenThreshold = 0)
throw () :
- HierarchyNode<ITEM, TAG>(tag, coll),
+ HierarchyNode<COLL>(tag, coll),
flattenThreshold(flattenThreshold) {}
SmartHierarchyNode(
- HierarchyNode<ITEM, TAG>* parent,
+ HierarchyNode<COLL>* parent,
const TAG& tag,
- const CardinalityStore<ITEM, TAG>& coll,
+ const COLL& coll,
int flattenThreshold = 0)
throw () :
- HierarchyNode<ITEM, TAG>(parent, tag, coll.getChildCollection(tag)),
+ HierarchyNode<COLL>(parent, tag, coll),
flattenThreshold(flattenThreshold)
{
std::set<TAG> tags; tags.insert(tag);
@@ -138,27 +148,54 @@
virtual ~SmartHierarchyNode() {}
};
+template<typename COLL>
+inline HierarchyNode<COLL>* smartHierarchyNode(const typename coll::coll_traits<COLL>::tag_type& tag, const COLL& coll, int flattenThreshold)
+{
+ return new SmartHierarchyNode<COLL>(tag, coll, flattenThreshold);
+}
+template<typename COLL>
+inline HierarchyNode<COLL>* smartHierarchyNode(HierarchyNode<COLL>* parent, const typename coll::coll_traits<COLL>::tag_type& tag, const COLL& coll, int flattenThreshold)
+{
+ return new SmartHierarchyNode<COLL>(parent, tag, coll, flattenThreshold);
+}
+
// SmartHierarchyNode which also does merging of equivalent tags
-template<class ITEM, class TAG>
-class CleanSmartHierarchyNode : public SmartHierarchyNode<ITEM, TAG>
+template<typename COLL>
+class CleanSmartHierarchyNode : public SmartHierarchyNode<COLL>
{
protected:
+ typedef typename SmartHierarchyNode<COLL>::ITEM ITEM;
+ typedef typename SmartHierarchyNode<COLL>::TAG TAG;
+ typedef typename SmartHierarchyNode<COLL>::ITEMSET ITEMSET;
+ typedef typename SmartHierarchyNode<COLL>::TAGSET TAGSET;
+
// Expand the collection in the children of this node
virtual void expand();
TAG setTag(const TAG& tag) { return this->_tag = tag; }
- HierarchyNode<ITEM, TAG>* setParent(HierarchyNode<ITEM, TAG>* parent) { return this->_parent = parent; }
+ HierarchyNode<COLL>* setParent(HierarchyNode<COLL>* parent) { return this->_parent = parent; }
public:
- CleanSmartHierarchyNode(const TAG& tag, const CardinalityStore<ITEM, TAG>& coll, int flattenThreshold = 0)
- : SmartHierarchyNode<ITEM, TAG>(tag, coll, flattenThreshold) {}
- CleanSmartHierarchyNode(HierarchyNode<ITEM, TAG>* parent, const TAG& tag, const CardinalityStore<ITEM, TAG>& coll, int flattenThreshold = 0)
- : SmartHierarchyNode<ITEM, TAG>(parent, tag, coll, flattenThreshold) {}
+ CleanSmartHierarchyNode(const TAG& tag, const COLL& coll, int flattenThreshold = 0)
+ : SmartHierarchyNode<COLL>(tag, coll, flattenThreshold) {}
+ CleanSmartHierarchyNode(HierarchyNode<COLL>* parent, const TAG& tag, const COLL& coll, int flattenThreshold = 0)
+ : SmartHierarchyNode<COLL>(parent, tag, coll, flattenThreshold) {}
virtual ~CleanSmartHierarchyNode() {}
};
-};
+template<typename COLL>
+inline HierarchyNode<COLL>* cleanSmartHierarchyNode(const typename coll::coll_traits<COLL>::tag_type& tag, const COLL& coll, int flattenThreshold)
+{
+ return new CleanSmartHierarchyNode<COLL>(tag, coll, flattenThreshold);
+}
+template<typename COLL>
+inline HierarchyNode<COLL>* cleanSmartHierarchyNode(HierarchyNode<COLL>* parent, const typename coll::coll_traits<COLL>::tag_type& tag, const COLL& coll, int flattenThreshold)
+{
+ return new CleanSmartHierarchyNode<COLL>(parent, tag, coll, flattenThreshold);
+}
+
+}
// vim:set ts=4 sw=4:
#endif
Modified: tagcoll/2.0/tagcoll/coll/base.h
==============================================================================
--- tagcoll/2.0/tagcoll/coll/base.h (original)
+++ tagcoll/2.0/tagcoll/coll/base.h Tue May 9 22:36:42 2006
@@ -283,7 +283,7 @@
{
typename coll_traits<Self>::itemset_type items = getItemsHavingTags(tags);
for (typename coll_traits<Self>::itemset_type::const_iterator i = items.begin();
- i != items.end(); i++)
+ i != items.end(); ++i)
{
*out = std::make_pair(*i, getTagsOfItem(*i));
++out;
Modified: tagcoll/2.0/tagcoll/coll/fast.cc
==============================================================================
--- tagcoll/2.0/tagcoll/coll/fast.cc (original)
+++ tagcoll/2.0/tagcoll/coll/fast.cc Tue May 9 22:36:42 2006
@@ -18,182 +18,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <tagcoll/coll/fast.h>
-#include <tagcoll/Patches.h>
-
-#include <wibble/operators.h>
-
-using namespace std;
-using namespace wibble::operators;
-
-namespace tagcoll {
-namespace coll {
-
-template<class ITEM, class TAG>
-std::set<ITEM> Fast<ITEM, TAG>::getItems(const TAG& tag) const
-{
- typename map<TAG, std::set<ITEM> >::const_iterator i = tags.find(tag);
- if (i != tags.end())
- return i->second;
- else
- return std::set<ITEM>();
-}
-
-template<class ITEM, class TAG>
-std::set<TAG> Fast<ITEM, TAG>::getTags(const ITEM& item) const
-{
- typename map<ITEM, std::set<TAG> >::const_iterator i = items.find(item);
- if (i != items.end())
- return i->second;
- else
- return std::set<TAG>();
-}
-
-template<class ITEM, class TAG>
-std::set<ITEM> Fast<ITEM, TAG>::getTaggedItems() const
-{
- std::set<ITEM> res;
- for (typename map<ITEM, std::set<TAG> >::const_iterator i = items.begin();
- i != items.end(); i++)
- res |= i->first;
- return res;
-}
-
-template<class ITEM, class TAG>
-std::set<TAG> Fast<ITEM, TAG>::getAllTags() const
-{
- std::set<TAG> res;
- for (typename map<TAG, std::set<ITEM> >::const_iterator i = tags.begin();
- i != tags.end(); i++)
- res |= i->first;
- return res;
-}
-
-#if 0
-template<class ITEM, class TAG>
-void Fast<ITEM, TAG>::output(Consumer<ITEM, TAG>& consumer) const
-{
- for (typename map<ITEM, std::set<TAG> >::const_iterator i = items.begin();
- i != items.end(); i++)
- consumer.consume(i->first, i->second);
-}
-#endif
-
-template<class ITEM, class TAG>
-void Fast<ITEM, TAG>::applyChange(const PatchList<ITEM, TAG>& change)
-{
- for (typename PatchList<ITEM, TAG>::const_iterator i = change.begin(); i != change.end(); i++)
- {
- // Save the previous tagset in `rev'
- std::set<TAG> prevTags = getTags(i->first);
- std::set<TAG> nextTags = i->second.apply(prevTags);
-
- // Set the new tagset in the item
- items[i->first] = nextTags;
-
- // Fix the itemsets in the involved tags
- std::set<TAG> t = prevTags - nextTags;
- for (typename std::set<TAG>::const_iterator j = t.begin(); j != t.end(); j++)
- {
- std::set<TAG> items = getItems(*j) - i->first;
- if (items.empty())
- tags.erase(*j);
- else
- tags[*j] = items;
- }
- t = nextTags - prevTags;
- for (typename std::set<TAG>::const_iterator j = t.begin(); j != t.end(); j++)
- tags[*j] |= i->first;
- }
-}
-
-template<class ITEM, class TAG>
-std::set<TAG> Fast<ITEM, TAG>::getTagsImplying(const TAG& tag) const
-{
- // tag1 implies tag2 if the itemset of tag1 is a subset of the itemset of tag2
- std::set<TAG> res;
- std::set<ITEM> itemsToCheck = getItems(tag);
- // TODO: choose which one is the most efficient implementation
-#if 0
- // Roughly:
- // O(n[pkgs per tag] * log(nitems) * log(n[items per pkg]) + n[tags per item] * n[items per tag])
- std::set<TAG> tagsToCheck;
- for (std::set<ITEM>::const_iterator i = itemsToCheck.begin();
- i != itemsToCheck.end(); ++i)
- tagsToCheck |= getTags(*i);
- for (std::set<TAG>::const_iterator i = tagsToCheck.begin();
- i != tagsToCheck.end(); ++i)
- if (utils::set_contains(itemsToCheck, getItems(*i)))
- res |= *i;
-#else
- // O(ntags * n[items per tag])
- for (typename std::map<TAG, std::set<ITEM> >::const_iterator i = tags.begin();
- i != tags.end(); ++i)
- if (utils::set_contains(itemsToCheck, getItems(i->first)))
- res |= i->first;
-#endif
- return res - tag;
-}
-
-template<class ITEM, class TAG>
-void Fast<ITEM, TAG>::removeTag(const TAG& tag)
-{
- typename std::map<TAG, std::set<ITEM> >::iterator itag = tags.find(tag);
- for (typename std::set<ITEM>::const_iterator iitemset = itag->second.begin();
- iitemset != itag->second.end(); ++iitemset)
- {
- typename std::map<ITEM, std::set<TAG> >::iterator iitem = items.find(*iitemset);
- iitem->second -= tag;
- if (iitem->second.empty())
- items.erase(iitem);
- }
- tags.erase(itag);
-}
-
-template<class ITEM, class TAG>
-Fast<ITEM, TAG> Fast<ITEM, TAG>::getChildCollection(const TAG& tag) const
-{
- Fast<ITEM, TAG> res;
- outputHavingTags(wibble::singleton(tag), inserter(res));
- res.removeTag(tag);
- return res;
-}
-
-
-
-#if 0
-template<class ITEM, class TAG>
-void Fast<ITEM, TAG>::consumeItem(const ITEM& item, const std::set<TAG>& tags)
-{
- // Add the tags to the item
- items[item] |= tags;
-
- // Add the item to the tags
- for (typename std::set<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
- this->tags[*i] |= item;
-}
-
-template<class ITEM, class TAG>
-void Fast<ITEM, TAG>::consumeItems(const std::set<ITEM>& items, const std::set<TAG>& tags)
-{
- for (typename std::set<ITEM>::const_iterator i = items.begin(); i != items.end(); i++)
- // Add the tags to the item
- this->items[*i] |= tags;
-
- for (typename std::set<TAG>::const_iterator i = tags.begin(); i != tags.end(); i++)
- // Add the items to the tag
- this->tags[*i] |= items;
-}
-#endif
-
-}
-}
-
#ifdef COMPILE_TESTSUITE
+#include <tagcoll/coll/fast.h>
#include <tests/test-utils.h>
#include <tagcoll/coll/simple.h>
+using namespace std;
+
namespace wibble {
namespace tut {
using namespace tagcoll::tests;
@@ -301,6 +133,7 @@
}
#include <tagcoll/test-utils.tcc>
+#include <tagcoll/coll/fast.tcc>
#include <tagcoll/Patches.tcc>
#endif
More information about the Debtags-commits
mailing list