debtags.h

Go to the documentation of this file.
00001 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*-
00002 /* @file
00003  * @author Enrico Zini (enrico) <enrico@enricozini.org>
00004  */
00005 
00006 /*
00007  * libpkg Debtags data provider
00008  *
00009  * Copyright (C) 2003-2007  Enrico Zini <enrico@debian.org>
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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     // Master mmap index container
00070     tagcoll::diskindex::MasterMMap mastermmap;
00071 
00072     // Debtags database
00073     tagcoll::coll::IntDiskIndex m_rocoll;
00074     tagcoll::coll::Patched< tagcoll::coll::IntDiskIndex > m_coll;
00075 
00076     // Package name to ID mapping
00077     PkgId m_pkgid;
00078 
00079     // Tag vocabulary
00080     Vocabulary m_voc;
00081 
00082     // User rc directory to store patches
00083     std::string rcdir;
00084 
00085     // Last modification timestamp of the index
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         // Nothing to do in this case
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     //static bool hasTagDatabase();
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 // vim:set ts=4 sw=4:
00407 #endif

Generated on Fri Sep 14 23:09:13 2007 for libept by  doxygen 1.5.3