00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EPT_DEBTAGS_DEBTAGS_H
00027 #define EPT_DEBTAGS_DEBTAGS_H
00028
00029 #include <ept/debtags/tag.h>
00030 #include <ept/debtags/vocabulary.h>
00031 #include <ept/debtags/maint/pkgid.h>
00032
00033 #include <tagcoll/coll/base.h>
00034 #include <tagcoll/coll/intdiskindex.h>
00035 #include <tagcoll/coll/patched.h>
00036
00037 namespace ept {
00038 namespace debtags {
00039 class Debtags;
00040 }
00041 }
00042
00043 namespace tagcoll {
00044 template< typename _, typename _1 > class PatchList;
00045
00046 namespace coll {
00047
00048 template<>
00049 struct coll_traits< ept::debtags::Debtags >
00050 {
00051 typedef std::string item_type;
00052 typedef ept::debtags::Tag tag_type;
00053 typedef std::set< ept::debtags::Tag > tagset_type;
00054 typedef std::set< std::string > itemset_type;
00055 };
00056
00057 }
00058 }
00059
00060 namespace ept {
00061 namespace debtags {
00062
00075 class Debtags : public tagcoll::coll::Collection<Debtags>
00076 {
00077 protected:
00078
00079 tagcoll::diskindex::MasterMMap mastermmap;
00080
00081
00082 tagcoll::coll::IntDiskIndex m_rocoll;
00083 tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > m_coll;
00084
00085
00086 PkgId m_pkgid;
00087
00088
00089 Vocabulary m_voc;
00090
00091
00092 std::string rcdir;
00093
00094
00095 time_t m_timestamp;
00096
00097 std::string packageByID(int id) const
00098 {
00099 return m_pkgid.byID(id);
00100 }
00101
00102 template<typename IDS>
00103 std::set<std::string> packagesById(const IDS& ids) const
00104 {
00105 std::set<std::string> pkgs;
00106 for (typename IDS::const_iterator i = ids.begin();
00107 i != ids.end(); ++i)
00108 pkgs.insert(packageByID(*i));
00109 return pkgs;
00110 }
00111
00112 int idByPackage(const std::string& pkg) const
00113 {
00114 return m_pkgid.byName(pkg);
00115 }
00116
00117 template<typename PKGS>
00118 std::set<int> idsByPackages(const PKGS& pkgs) const
00119 {
00120 std::set<int> ids;
00121 for (typename PKGS::const_iterator i = pkgs.begin();
00122 i != pkgs.end(); ++i)
00123 ids.insert(idByPackage(*i));
00124 return ids;
00125 }
00126
00127 public:
00128 typedef tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > coll_type;
00129 typedef std::pair< std::string, std::set<Tag> > value_type;
00130
00131 class const_iterator
00132 {
00133 const Debtags& coll;
00134 Debtags::coll_type::const_iterator ci;
00135 mutable const Debtags::value_type* cached_val;
00136
00137 protected:
00138 const_iterator(const Debtags& coll,
00139 const Debtags::coll_type::const_iterator& ci)
00140 : coll(coll), ci(ci), cached_val(0) {}
00141
00142 public:
00143 ~const_iterator()
00144 {
00145 if (cached_val)
00146 delete cached_val;
00147 }
00148 const Debtags::value_type operator*() const
00149 {
00150 if (cached_val)
00151 return *cached_val;
00152
00153 return make_pair(coll.packageByID(ci->first), coll.vocabulary().tagsByID(ci->second));
00154 }
00155 const Debtags::value_type* operator->() const
00156 {
00157 if (cached_val)
00158 return cached_val;
00159 return cached_val = new Debtags::value_type(*(*this));
00160 }
00161 const_iterator& operator++()
00162 {
00163 ++ci;
00164 if (cached_val)
00165 {
00166 delete cached_val;
00167 cached_val = 0;
00168 }
00169 return *this;
00170 }
00171 bool operator==(const const_iterator& iter) const
00172 {
00173 return ci == iter.ci;
00174 }
00175 bool operator!=(const const_iterator& iter) const
00176 {
00177 return ci != iter.ci;
00178 }
00179
00180 friend class Debtags;
00181 };
00182 const_iterator begin() const { return const_iterator(*this, m_coll.begin()); }
00183 const_iterator end() const { return const_iterator(*this, m_coll.end()); }
00184
00193 Debtags(bool editable = false);
00194 ~Debtags() {}
00195
00197 time_t timestamp() const { return m_timestamp; }
00198
00200 bool hasData() const { return m_timestamp != 0; }
00201
00202 coll_type& tagdb() { return m_coll; }
00203 const coll_type& tagdb() const { return m_coll; }
00204 tagcoll::PatchList<std::string, Tag> changes() const;
00205
00206 #if 0
00207 template<typename ITEMS, typename TAGS>
00208 void insert(const ITEMS& items, const TAGS& tags)
00209 {
00210 for (typename ITEMS::const_iterator i = items.begin();
00211 i != items.end(); ++i)
00212 m_changes.addPatch(Patch(*i, tags, TagSet()));
00213 }
00214
00215 template<typename ITEMS>
00216 void insert(const ITEMS& items, const wibble::Empty<Tag>& tags)
00217 {
00218
00219 }
00220
00224 const Patches& changes() const { return m_changes; }
00225
00229 void resetChanges() { m_changes.clear(); }
00230
00234 void setChanges(const Patches& changes);
00235
00239 void addChanges(const Patches& changes);
00240 #endif
00241
00242 bool hasTag(const Tag& tag) const { return m_coll.hasTag(tag.id()); }
00243
00244 std::set<Tag> getTagsOfItem(const std::string& item) const
00245 {
00246 int id = idByPackage(item);
00247 if (id == -1) return std::set<Tag>();
00248 return vocabulary().tagsByID(m_coll.getTagsOfItem(id));
00249 }
00250
00251 template<typename ITEMS>
00252 std::set<Tag> getTagsOfItems(const ITEMS& items) const
00253 {
00254 return vocabulary().tagsByID(m_coll.getTagsOfItems(idsByPackages(items)));
00255 }
00256
00257 std::set<std::string> getItemsHavingTag(const Tag& tag) const
00258 {
00259 return packagesById(m_coll.getItemsHavingTag(tag.id()));
00260 }
00261 template<typename TAGS>
00262 std::set<std::string> getItemsHavingTags(const TAGS& tags) const
00263 {
00264 std::set<int> itags;
00265 for (typename TAGS::const_iterator i = tags.begin();
00266 i != tags.end(); ++i)
00267 itags.insert(i->id());
00268 return packagesById(m_coll.getItemsHavingTags(itags));
00269 }
00270
00271 #if 0
00272 ItemSet getTaggedItems() const;
00273 #endif
00274 std::set<Tag> getAllTags() const
00275 {
00276 return vocabulary().tagsByID(m_coll.getAllTags());
00277 }
00278
00280 Vocabulary& vocabulary() { return m_voc; }
00282 const Vocabulary& vocabulary() const { return m_voc; }
00283
00289 PkgId& pkgid() { return m_pkgid; }
00295 const PkgId& pkgid() const { return m_pkgid; }
00296
00297 int getCardinality(const Tag& tag) const
00298 {
00299 return m_coll.getCardinality(tag.id());
00300 }
00301
00302 void applyChange(const tagcoll::PatchList<std::string, Tag>& change)
00303 {
00304 using namespace tagcoll;
00305 PatchList<int, int> intp;
00306 for (PatchList<std::string, Tag>::const_iterator i = change.begin();
00307 i != change.end(); ++i)
00308 {
00309 Patch<int, int> p(idByPackage(i->first));
00310 for (std::set<Tag>::const_iterator j = i->second.added.begin();
00311 j != i->second.added.end(); ++j)
00312 p.add(j->id());
00313 for (std::set<Tag>::const_iterator j = i->second.removed.begin();
00314 j != i->second.removed.end(); ++j)
00315 p.remove(j->id());
00316 intp.addPatch(p);
00317 }
00318 m_coll.applyChange(intp);
00319 }
00320
00321 #if 0
00322 template<typename OUT>
00323 void output(OUT out) const
00324 {
00325 for (const_iterator i = begin(); i != end(); ++i)
00326 {
00327 *out = *i;
00328 ++out;
00329 }
00330 }
00331 #endif
00332
00333
00334
00339
00340
00341
00346 void savePatch();
00347
00352 void savePatch(const tagcoll::PatchList<std::string, std::string>& patch);
00353
00358 void savePatch(const tagcoll::PatchList<std::string, Tag>& patch);
00359
00364 void sendPatch();
00365
00369 void sendPatch(const tagcoll::PatchList<std::string, std::string>& patch);
00370
00374 void sendPatch(const tagcoll::PatchList<std::string, Tag>& patch);
00375
00376
00382 template<typename OUT>
00383 void outputSystem(const OUT& cons);
00384
00390 template<typename OUT>
00391 void outputSystem(const std::string& filename, const OUT& out);
00392
00399 template<typename OUT>
00400 void outputPatched(const OUT& cons);
00401
00408 template<typename OUT>
00409 void outputPatched(const std::string& filename, const OUT& out);
00410 };
00411
00412
00413 }
00414 }
00415
00416
00417 #endif