1 : /*
2 : * Merge tags of items appearing multiple times in a stream of tagged items
3 : *
4 : * Copyright (C) 2003--2006 Enrico Zini <enrico@debian.org>
5 : *
6 : * This library is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public
8 : * License as published by the Free Software Foundation; either
9 : * version 2.1 of the License, or (at your option) any later version.
10 : *
11 : * This library is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this library; if not, write to the Free Software
18 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 : */
20 :
21 : #ifndef TAGCOLL_COLL_SIMPLE_TCC
22 : #define TAGCOLL_COLL_SIMPLE_TCC
23 :
24 : #include <tagcoll/utils/set.h>
25 : #include <tagcoll/coll/simple.h>
26 : #include <tagcoll/patch.h>
27 :
28 : #include <wibble/operators.h>
29 :
30 : using namespace std;
31 : using namespace wibble::operators;
32 :
33 : namespace tagcoll {
34 : namespace coll {
35 :
36 :
37 : template<class ITEM, class TAG> template<typename ITEMS, typename TAGS>
38 42293 : void Simple<ITEM, TAG>::insert(const ITEMS& items, const TAGS& tags)
39 : {
40 : using namespace wibble::operators;
41 :
42 42295 : if (tags.empty())
43 0 : return;
44 84590 : for (typename ITEMS::const_iterator i = items.begin();
45 : i != items.end(); ++i)
46 : {
47 42295 : typename std::map< ITEM, std::set<TAG> >::iterator iter = coll.find(*i);
48 42295 : if (iter == coll.end())
49 21149 : coll.insert(std::make_pair(*i, std::set<TAG>() | tags));
50 : else
51 21146 : iter->second |= tags;
52 : }
53 : }
54 :
55 : template<class ITEM, class TAG>
56 : std::set<TAG> Simple<ITEM, TAG>::getTagsOfItem(const ITEM& item) const
57 : {
58 2 : typename map< ITEM, std::set<TAG> >::const_iterator i = coll.find(item);
59 :
60 2 : if (i == coll.end())
61 0 : return std::set<TAG>();
62 : else
63 2 : return i->second;
64 : }
65 :
66 : template<class ITEM, class TAG>
67 : std::set<ITEM> Simple<ITEM, TAG>::getItemsHavingTag(const TAG& tag) const
68 : {
69 : std::set<ITEM> res;
70 : for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
71 : i != coll.end(); i++)
72 : if (i->second.find(tag) != i->second.end())
73 : res |= i->first;
74 : return res;
75 : }
76 :
77 : template<class ITEM, class TAG> template<typename TAGS>
78 : std::set<ITEM> Simple<ITEM, TAG>::getItemsHavingTags(const TAGS& tags) const
79 : {
80 : std::set<ITEM> res;
81 : for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
82 : i != coll.end(); i++)
83 : if (utils::set_contains(i->second, tags))
84 : res |= i->first;
85 : return res;
86 : }
87 :
88 : #if 0
89 : template<class T, class Tag>
90 : void Simple<T, Tag>::outputReversed(Consumer<Tag, T>& consumer) const
91 : {
92 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
93 : i != coll.end(); i++)
94 : {
95 : std::set<T> items;
96 : items |= i->first;
97 : consumer.consume(i->second, items);
98 : }
99 : }
100 : #endif
101 :
102 : template<class ITEM, class TAG> template<typename TAGS, typename OUT>
103 : void Simple<ITEM, TAG>::outputHavingTags(const TAGS& ts, OUT out) const
104 : {
105 : for (typename map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
106 : i != coll.end(); ++i)
107 : if (utils::set_contains(i->second, ts))
108 : {
109 : *out = *i;
110 : ++out;
111 : }
112 : }
113 :
114 :
115 :
116 : template<class T, class Tag>
117 : void Simple<T, Tag>::applyChange(const PatchList<T, Tag>& change)
118 : {
119 : for (typename PatchList<T, Tag>::const_iterator i = change.begin(); i != change.end(); i++)
120 : {
121 : typename map< T, std::set<Tag> >::iterator it = coll.find(i->first);
122 : if (it == coll.end())
123 : {
124 : // If the item doesn't exist, create it
125 : coll.insert(make_pair(i->first, i->second.added));
126 : } else {
127 : it->second = i->second.apply(it->second);
128 : }
129 : }
130 : }
131 :
132 : template<typename ITEM, typename TAG>
133 : std::set<ITEM> Simple<ITEM, TAG>::getTaggedItems() const
134 : {
135 : std::set<ITEM> res;
136 : for (typename std::map< ITEM, std::set<TAG> >::const_iterator i = coll.begin();
137 : i != coll.end(); i++)
138 : res.insert(i->first);
139 : return res;
140 : }
141 :
142 : template<class T, class Tag>
143 : std::set<Tag> Simple<T, Tag>::getAllTags() const
144 : {
145 3 : std::set<Tag> tags;
146 :
147 6 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
148 : i != coll.end(); i++)
149 3 : tags |= i->second;
150 :
151 0 : return tags;
152 : }
153 :
154 : template<class T, class Tag>
155 : std::set<Tag> Simple<T, Tag>::getCompanionTags(const std::set<Tag>& ts) const
156 : {
157 : std::set<Tag> tags;
158 :
159 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
160 : i != coll.end(); i++)
161 : if (utils::set_contains(i->second, (ts)))
162 : tags |= i->second - ts;
163 :
164 : return tags;
165 : }
166 :
167 : template<class T, class Tag>
168 : std::set<T> Simple<T, Tag>::getRelatedItems(const std::set<Tag>& tags, int maxdistance) const
169 : {
170 : std::set<T> res;
171 :
172 : for (typename map< T, std::set<Tag> >::const_iterator i = coll.begin();
173 : i != coll.end(); i++)
174 : {
175 : int dist = utils::set_distance(tags, i->second);
176 : if (dist >= 0 && dist <= maxdistance)
177 : res |= i->first;
178 : }
179 :
180 : return res;
181 : }
182 :
183 : template<class T, class Tag>
184 : unsigned int Simple<T, Tag>::itemCount() const
185 : {
186 5 : return coll.size();
187 : }
188 :
189 : }
190 : }
191 :
192 : #include <tagcoll/coll/base.tcc>
193 :
194 : #endif
195 :
196 : // vim:set ts=4 sw=4:
|