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
00066 class Debtags : public tagcoll::coll::Collection<Debtags>
00067 {
00068 protected:
00069
00070 tagcoll::diskindex::MasterMMap mastermmap;
00071
00072
00073 tagcoll::coll::IntDiskIndex m_rocoll;
00074 tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > m_coll;
00075
00076
00077 PkgId m_pkgid;
00078
00079
00080 Vocabulary m_voc;
00081
00082
00083 std::string rcdir;
00084
00085
00086 time_t m_timestamp;
00087
00088 std::string packageByID(int id) const
00089 {
00090 return m_pkgid.byID(id);
00091 }
00092
00093 template<typename IDS>
00094 std::set<std::string> packagesById(const IDS& ids) const
00095 {
00096 std::set<std::string> pkgs;
00097 for (typename IDS::const_iterator i = ids.begin();
00098 i != ids.end(); ++i)
00099 pkgs.insert(packageByID(*i));
00100 return pkgs;
00101 }
00102
00103 int idByPackage(const std::string& pkg) const
00104 {
00105 return m_pkgid.byName(pkg);
00106 }
00107
00108 template<typename PKGS>
00109 std::set<int> idsByPackages(const PKGS& pkgs) const
00110 {
00111 std::set<int> ids;
00112 for (typename PKGS::const_iterator i = pkgs.begin();
00113 i != pkgs.end(); ++i)
00114 ids.insert(idByPackage(*i));
00115 return ids;
00116 }
00117
00118 public:
00119 typedef tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > coll_type;
00120 typedef std::pair< std::string, std::set<Tag> > value_type;
00121
00122 class const_iterator
00123 {
00124 const Debtags& coll;
00125 Debtags::coll_type::const_iterator ci;
00126 mutable const Debtags::value_type* cached_val;
00127
00128 protected:
00129 const_iterator(const Debtags& coll,
00130 const Debtags::coll_type::const_iterator& ci)
00131 : coll(coll), ci(ci), cached_val(0) {}
00132
00133 public:
00134 ~const_iterator()
00135 {
00136 if (cached_val)
00137 delete cached_val;
00138 }
00139 const Debtags::value_type operator*() const
00140 {
00141 if (cached_val)
00142 return *cached_val;
00143
00144 return make_pair(coll.packageByID(ci->first), coll.vocabulary().tagsByID(ci->second));
00145 }
00146 const Debtags::value_type* operator->() const
00147 {
00148 if (cached_val)
00149 return cached_val;
00150 return cached_val = new Debtags::value_type(*(*this));
00151 }
00152 const_iterator& operator++()
00153 {
00154 ++ci;
00155 if (cached_val)
00156 {
00157 delete cached_val;
00158 cached_val = 0;
00159 }
00160 return *this;
00161 }
00162 bool operator==(const const_iterator& iter) const
00163 {
00164 return ci == iter.ci;
00165 }
00166 bool operator!=(const const_iterator& iter) const
00167 {
00168 return ci != iter.ci;
00169 }
00170
00171 friend class Debtags;
00172 };
00173 const_iterator begin() const { return const_iterator(*this, m_coll.begin()); }
00174 const_iterator end() const { return const_iterator(*this, m_coll.end()); }
00175
00183 Debtags(bool editable = false);
00184 ~Debtags() {}
00185
00187 time_t timestamp() const { return m_timestamp; }
00188
00190 bool hasData() const { return m_timestamp != 0; }
00191
00192 coll_type& tagdb() { return m_coll; }
00193 const coll_type& tagdb() const { return m_coll; }
00194 tagcoll::PatchList<std::string, Tag> changes() const;
00195
00196 #if 0
00197 template<typename ITEMS, typename TAGS>
00198 void insert(const ITEMS& items, const TAGS& tags)
00199 {
00200 for (typename ITEMS::const_iterator i = items.begin();
00201 i != items.end(); ++i)
00202 m_changes.addPatch(Patch(*i, tags, TagSet()));
00203 }
00204
00205 template<typename ITEMS>
00206 void insert(const ITEMS& items, const wibble::Empty<Tag>& tags)
00207 {
00208
00209 }
00210
00214 const Patches& changes() const { return m_changes; }
00215
00219 void resetChanges() { m_changes.clear(); }
00220
00224 void setChanges(const Patches& changes);
00225
00229 void addChanges(const Patches& changes);
00230 #endif
00231
00232 bool hasTag(const Tag& tag) const { return m_coll.hasTag(tag.id()); }
00233
00234 std::set<Tag> getTagsOfItem(const std::string& item) const
00235 {
00236 int id = idByPackage(item);
00237 if (id == -1) return std::set<Tag>();
00238 return vocabulary().tagsByID(m_coll.getTagsOfItem(id));
00239 }
00240
00241 template<typename ITEMS>
00242 std::set<Tag> getTagsOfItems(const ITEMS& items) const
00243 {
00244 return vocabulary().tagsByID(m_coll.getTagsOfItems(idsByPackages(items)));
00245 }
00246
00247 std::set<std::string> getItemsHavingTag(const Tag& tag) const
00248 {
00249 return packagesById(m_coll.getItemsHavingTag(tag.id()));
00250 }
00251 template<typename TAGS>
00252 std::set<std::string> getItemsHavingTags(const TAGS& tags) const
00253 {
00254 std::set<int> itags;
00255 for (typename TAGS::const_iterator i = tags.begin();
00256 i != tags.end(); ++i)
00257 itags.insert(i->id());
00258 return packagesById(m_coll.getItemsHavingTags(itags));
00259 }
00260
00261 #if 0
00262 ItemSet getTaggedItems() const;
00263 #endif
00264 std::set<Tag> getAllTags() const
00265 {
00266 return vocabulary().tagsByID(m_coll.getAllTags());
00267 }
00268
00270 Vocabulary& vocabulary() { return m_voc; }
00272 const Vocabulary& vocabulary() const { return m_voc; }
00273
00279 PkgId& pkgid() { return m_pkgid; }
00285 const PkgId& pkgid() const { return m_pkgid; }
00286
00287 int getCardinality(const Tag& tag) const
00288 {
00289 return m_coll.getCardinality(tag.id());
00290 }
00291
00292 void applyChange(const tagcoll::PatchList<std::string, Tag>& change)
00293 {
00294 using namespace tagcoll;
00295 PatchList<int, int> intp;
00296 for (PatchList<std::string, Tag>::const_iterator i = change.begin();
00297 i != change.end(); ++i)
00298 {
00299 Patch<int, int> p(idByPackage(i->first));
00300 for (std::set<Tag>::const_iterator j = i->second.added.begin();
00301 j != i->second.added.end(); ++j)
00302 p.add(j->id());
00303 for (std::set<Tag>::const_iterator j = i->second.removed.begin();
00304 j != i->second.removed.end(); ++j)
00305 p.remove(j->id());
00306 intp.addPatch(p);
00307 }
00308 m_coll.applyChange(intp);
00309 }
00310
00311 #if 0
00312 template<typename OUT>
00313 void output(OUT out) const
00314 {
00315 for (const_iterator i = begin(); i != end(); ++i)
00316 {
00317 *out = *i;
00318 ++out;
00319 }
00320 }
00321 #endif
00322
00323
00324
00329
00330
00331
00336 void savePatch();
00337
00342 void savePatch(const tagcoll::PatchList<std::string, std::string>& patch);
00343
00348 void savePatch(const tagcoll::PatchList<std::string, Tag>& patch);
00349
00354 void sendPatch();
00355
00359 void sendPatch(const tagcoll::PatchList<std::string, std::string>& patch);
00360
00364 void sendPatch(const tagcoll::PatchList<std::string, Tag>& patch);
00365
00366
00372 template<typename OUT>
00373 void outputSystem(const OUT& cons);
00374
00380 template<typename OUT>
00381 void outputSystem(const std::string& filename, const OUT& out);
00382
00389 template<typename OUT>
00390 void outputPatched(const OUT& cons);
00391
00398 template<typename OUT>
00399 void outputPatched(const std::string& filename, const OUT& out);
00400 };
00401
00402
00403 }
00404 }
00405
00406
00407 #endif