1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
libtagcoll
TagConsumer // Base class for datastructure to be filled by the
// TagcollParser::parseTagcoll() function (attention, TagcollParser is a namespace)
// The parser calls the consume(itemset) or consume(itemset, tagset) function on reading
// of a line
An example is found at debtags.cc in readFullCollection(const std::string& file, TagcollConsumer<string>& consumer)
TagcollSerializer -> write the data to a FILE*
TagcollSink -> discards all data
ImplicationList -> this maps the tags to their parent tags (map<string, OpSet<string>>)
// BMthis is constructed with the file: const char* fn_impls = "/var/lib/debtags/implications";
// this reads the implications
// Expand implications
ImplicationList implications;
readCollection(fn_impls, implications);
// Pack the structure for faster expansions
implications.pack();
TagcollFilter<string>* ximpl = new ApplyImplications(implications);
// BM ApplyImplications maps every call of consume(tags) through consume(implications->expand(tags))
filters.appendFilter(ximpl);
DerivedTagList // will most likely be very similar to ImplicationList
HandleMaker - maps strings to handle and vice versa (getHandle(string) inserts into the handle maker)
TagcollBuilder - builds a tagged collection using an int to string mapping
FilterChain - if we add consumer and there is no filter yet, it becomes the consumer, else
it will be attached at the last filter as consumer
SmartHierarchyNode - this is what should be used to build the tree!!
HierarchyNode<ITEM, TAG> nodes to iterate through the herarchy
tagcoll
Vocabulary - can read the tag database including the implications and description, it maps the
tags to the associated data
// Definition of tag implication:
// tag1 is implied by tag2 if all items associated to tag2 are also
// associated to tag1
// Also said:
// tag1 implies tag2 if all items associated to tag1 are also associated
// to tag2
// Container for bookmarks stored for computation
template<class ITEM, class TAG=std::string>
class TagCollection
{
protected:
class TagContainer : public std::map<TAG, int> // BM int means cardinality
// TAG is template class - string by default.
{
public:
void add(const TAG& tag, int card = 1) throw ();
void del(const TAG& tag, int card = 1) throw ();
};
// Tags in this collection, with their cardinality
TagContainer tags;
// Tag sets in this collection, with their cardinality
typedef std::map<OpSet<TAG>, OpSet<ITEM> > tagsets_t;
tagsets_t tagsets; // BM maps the set of tags to a set of items, most likely the packages that
// contains these tags
// Items that have no tags in this collection
OpSet<ITEM> untagged;
OpSet<TAG> // BM set of tags
// Get the list of tags that imply one of the tags in `tags'
OpSet<TAG> TagCollection::getImplyingOneOf(const OpSet<TAG>& tags) const throw ();
public:
// Represent a change to the TagCollection
class Change : public std::map< ITEM, OpSet<TAG> > {};
TagCollection() throw () {}
TagCollection(const TagCollection& tc) throw ()
: tags(tc.tags), tagsets(tc.tagsets), untagged(tc.untagged) {}
~TagCollection() throw () {}
TagCollection& operator=(const TagCollection& tc) throw ()
{
tags = tc.tags;
tagsets = tc.tagsets;
untagged = tc.untagged;
return *this;
}
// Get the number of different tags in this collection
int tagCount() const throw () { return tags.size(); }
// Get the number of different tag sets in this collection
int tagsetCount() const throw () { return tagsets.size(); }
// Get the number of untagged items in this collection
int untaggedCount() const throw () { return untagged.size(); }
// Get the total number of items in this collection
int totalCount() const throw ();
// Get the set of untagged items in this collection
OpSet<ITEM> getUntaggedItems() const throw () { return untagged; }
// Get the set of items with the given tagset
OpSet<ITEM> getItemsForTagset(const OpSet<TAG>& ts) const throw ();
// Get the set of tags for the given item
// Warning: it iterates over all tagsets to find out which one is attached
// to the given item
OpSet<TAG> getTagsetForItem(const ITEM& item) const throw ();
// Get the set of all tags in this collection
OpSet<TAG> getAllTags() const throw ();
// Get the set of all tags in this collection that appear in tagsets
// containing `ts'
OpSet<TAG> getCompanionTags(const OpSet<TAG>& ts) const throw ();
// Get the set of all items in this collection
OpSet<ITEM> getAllItems() const throw ();
// Get the set of all items in this collection whose tagsets contain `ts'
OpSet<ITEM> getCompanionItems(const OpSet<TAG>& ts) const throw ();
// Get the set of all items in this collection whose tagsets contain `ts'
std::map< ITEM, OpSet<TAG> > getCompanionItemsAndTagsets(const OpSet<TAG>& ts) const throw ();
// Get the list of tagsets related to the given one, with distance > 0 and <= maxdistance
std::list< OpSet<TAG> > getRelatedTagsets(const OpSet<TAG>& ts, int maxdistance = 1) const throw ();
// Apply a Change to the collection; return a reverse change that can be
// reused to undo the operation
Change applyChange(const Change& change) throw ();
// Add an untagged item to the collection
void add(const ITEM& item) throw ();
// Add a set of untagged items to the collection
void add(const OpSet<ITEM>& items) throw ();
// Add an item with the given tagset to the tagged collection
void add(const OpSet<TAG>& tagset, const ITEM& item) throw ();
// Add a set of items with the given tagset to the tagged collection
void add(const OpSet<TAG>& tagset, const OpSet<ITEM>& items) throw ();
// Return a tagged collection with all tagsets of this one that contain the
// tag `tag', but with the tag removed
TagCollection<ITEM, TAG> getChildCollection(const TAG& tag) const throw ();
// Return a tagged collection with all tagsets of this one that are
// nonempty when stripped by the tag `tag' and all tags that imply it
TagCollection<ITEM, TAG> getCollectionWithoutTags(const OpSet<TAG>& tag) const throw ();
// Return the tagged collection with all tagsets of this one that do not
// contain the tag `tag'
TagCollection<ITEM, TAG> getCollectionWithoutTagsetsHaving(const TAG& tag) const throw ();
// Return the tagged collection with all tagsets of this one that do not
// contain the tags in `tags'
TagCollection<ITEM, TAG> getCollectionWithoutTagsetsHavingAnyOf(const OpSet<TAG>& tag) const throw ();
// Return the tag with maximum cardinality
TAG findTagWithMaxCardinalityNotIn(const OpSet<TAG>& tags, int* card = 0) const throw ();
// Return the list of tags that the given tag implies
OpSet<TAG> TagCollection::getImpliedBy(const TAG& tag) const throw ();
// Return a collection where equivalent tags are merged.
// Equivalent tags are tags which are attached to the same set of items
// Merging two equivalent tags A and B is done renaming both of them in the
// tag "A, B"
void mergeEquivalentTags() throw ();
// Remove all the tags with cardinality less than `card'
void removeTagsWithCardinalityLessThan(int card) throw ();
// Output the contents of the collection to a TagcollConsumer
void output(TagcollConsumer<ITEM, TAG>& cons) const throw ();
};
|