LTP GCOV extension - code coverage report
Current view: directory - ept/debtags - vocabulary.h
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 55
Code covered: 87.3 % Executed lines: 48

       1                 : #ifndef EPT_DEBTAGS_VOCABULARY_H
       2                 : #define EPT_DEBTAGS_VOCABULARY_H
       3                 : 
       4                 : /** @file
       5                 :  * @author Enrico Zini <enrico@enricozini.org>
       6                 :  * Debtags vocabulary access
       7                 :  */
       8                 : 
       9                 : /*
      10                 :  * Copyright (C) 2003,2004,2005,2006,2007  Enrico Zini <enrico@debian.org>
      11                 :  *
      12                 :  * This program is free software; you can redistribute it and/or modify
      13                 :  * it under the terms of the GNU General Public License as published by
      14                 :  * the Free Software Foundation; either version 2 of the License, or
      15                 :  * (at your option) any later version.
      16                 :  *
      17                 :  * This program is distributed in the hope that it will be useful,
      18                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :  * GNU General Public License for more details.
      21                 :  *
      22                 :  * You should have received a copy of the GNU General Public License
      23                 :  * along with this program; if not, write to the Free Software
      24                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      25                 :  */
      26                 : 
      27                 : #include <ept/debtags/tag.h>
      28                 : #include <tagcoll/diskindex/mmap.h>
      29                 : 
      30                 : #include <string>
      31                 : #include <vector>
      32                 : #include <map>
      33                 : 
      34                 : namespace ept {
      35                 : namespace debtags {
      36                 : 
      37                 : class Vocabulary
      38                 : {
      39                 : public:
      40                 :         class FacetIndex : public tagcoll::diskindex::MMap
      41                 :         {
      42                 :         protected:
      43                 :                 // Layout of the data in the index
      44                 :                 struct Item {
      45                 :                         int offset;
      46                 :                         int size;
      47                 :                         int firsttag;
      48                 :                         int lasttag;
      49                 :                         const char name[];
      50                 :                 };
      51            2393 :                 inline Item* item(int id) const
      52                 :                 {
      53            2393 :                         if (id >= 0 && (unsigned)id < size())
      54            2392 :                                 return (Item*)(m_buf + ((int*)m_buf)[id]);
      55               1 :                         return NULL;
      56                 :                 }
      57                 : 
      58                 :         public:
      59              31 :                 FacetIndex() : tagcoll::diskindex::MMap() {}
      60                 :                 FacetIndex(const tagcoll::diskindex::MasterMMap& master, size_t idx)
      61                 :                         : tagcoll::diskindex::MMap(master, idx) {}
      62                 : 
      63                 :                 /// Get the number of facets in the index
      64            2501 :                 size_t size() const { return m_size == 0 ? 0 :  *(int*)m_buf / sizeof(int); }
      65                 :                 /// Get the offset of the facet data in the vocabulary for this facet
      66              59 :                 size_t offset(int id) const { Item* i = item(id); return i == NULL ? 0 : i->offset; }
      67                 :                 /// Get the size of the facet data in the vocabulary for this facet
      68              59 :                 size_t size(int id) const { Item* i = item(id); return i == NULL ? 0 : i->size; }
      69                 :                 /// Get the id of the first tag for this facet
      70              91 :                 int firsttag(int id) const { Item* i = item(id); return i == NULL ? -1 : i->firsttag; }
      71                 :                 /// Get the id of the last tag for this facet
      72            2043 :                 int lasttag(int id) const { Item* i = item(id); return i == NULL ? -1 : i->lasttag; }
      73                 :                 /// Get the name of this facet
      74              88 :                 const char* name(int id) const { Item* i = item(id); return i == NULL ? "" : i->name; }
      75                 :                 /// Get the ID of the facet with this name
      76                 :                 int id(const char* name) const;
      77               7 :                 int id(const std::string& name) const { return id(name.c_str()); }
      78                 :         };
      79                 :         
      80                 :         class TagIndex : public tagcoll::diskindex::MMap
      81                 :         {
      82                 :         protected:
      83                 :                 // Layout of the data in the index
      84                 :                 struct Item {
      85                 :                         int offset;
      86                 :                         int size;
      87                 :                         int facet;
      88                 :                         const char name[];
      89                 :                 };
      90         1112004 :                 inline Item* item(int id) const
      91                 :                 {
      92         1112004 :                         if (id >= 0 && (unsigned)id < size())
      93         1112004 :                                 return (Item*)(m_buf + ((int*)m_buf)[id]);
      94               0 :                         return NULL;
      95                 :                 }
      96                 : 
      97                 :         public:
      98              31 :                 TagIndex() : tagcoll::diskindex::MMap() {}
      99                 :                 TagIndex(const tagcoll::diskindex::MasterMMap& master, size_t idx)
     100                 :                         : tagcoll::diskindex::MMap(master, idx) {}
     101                 : 
     102                 :                 /// Get the number of tags in the index
     103         1327864 :                 size_t size() const { return m_size == 0 ? 0 : *(int*)m_buf / sizeof(int); }
     104                 :                 /// Get the offset of the facet data in the vocabulary for this tag
     105            1242 :                 size_t offset(int id) const { Item* i = item(id); return i == NULL ? 0 : i->offset; }
     106                 :                 /// Get the size of the facet data in the vocabulary for this tag
     107            1242 :                 size_t size(int id) const { Item* i = item(id); return i == NULL ? 0 : i->size; }
     108                 :                 /// Get the id of the facet for this tag
     109               0 :                 int facet(int id) const { Item* i = item(id); return i == NULL ? -1 : i->facet; }
     110                 :                 /// Get the name of this tag
     111            3767 :                 const char* name(int id) const { Item* i = item(id); return i == NULL ? "" : i->name; }
     112                 :                 /// Get the ID of the tag with this name
     113                 :                 int id(const char* name) const;
     114          105755 :                 int id(const std::string& name) const { return id(name.c_str()); }
     115                 :         };
     116                 : 
     117                 : protected:
     118                 :         // Master MMap index container
     119                 :         tagcoll::diskindex::MasterMMap mastermmap;
     120                 : 
     121                 :         time_t m_timestamp;
     122                 : 
     123                 :         // Mmapped vocabulary file
     124                 :         std::string voc_fname;
     125                 :         int voc_fd;
     126                 :         size_t voc_size;
     127                 :         const char* voc_buf;
     128                 :         
     129                 :         // Facet and tag indexes
     130                 :         FacetIndex findex;
     131                 :         TagIndex tindex;
     132                 :         
     133                 :         // Cached parsed facet and tag records
     134                 :         mutable std::vector< std::map<std::string, std::string> > m_facetData;
     135                 :         mutable std::vector< std::map<std::string, std::string> > m_tagData;
     136                 :         // Empty parsed data to return when data is asked for IDs == -1
     137                 :         std::map<std::string, std::string> emptyData;
     138                 : 
     139                 :         void parseVocBuf(std::map<std::string, std::string>& res, size_t ofs, size_t len) const;
     140                 : 
     141                 : public:
     142                 :         Vocabulary();
     143                 :         ~Vocabulary();
     144                 : 
     145                 :         /// Get the timestamp of when the index was last updated
     146                 :         time_t timestamp() const { return m_timestamp; }
     147                 : 
     148                 :         /// Return true if this data source has data, false if it's empty
     149               1 :         bool hasData() const { return m_timestamp != 0; }
     150                 : 
     151                 :         const FacetIndex& facetIndex() const { return findex; }
     152                 :         const TagIndex& tagIndex() const { return tindex; }
     153                 : 
     154                 :         /**
     155                 :          * Check if the vocabulary contains the facet `name'
     156                 :          */
     157               2 :         bool hasFacet(const std::string& name) const
     158                 :         {
     159               2 :                 return findex.id(name.c_str()) != -1;
     160                 :         }
     161                 : 
     162                 :         /**
     163                 :          * Check if the vocabulary contains the tag `fullname'
     164                 :          */
     165             622 :         bool hasTag(const std::string& fullname) const
     166                 :         {
     167             622 :                 return tindex.id(fullname.c_str()) != -1;
     168                 :         }
     169                 : 
     170                 :         /**
     171                 :          * Return the facet with the given name
     172                 :          */
     173                 :         Facet facetByID(int id) const;
     174                 : 
     175                 :         /**
     176                 :          * Return the tag with the given full name
     177                 :          */
     178                 :         Tag tagByID(int id) const;
     179                 : 
     180                 :         template<typename IDS>
     181           84590 :         std::set<Tag> tagsByID(const IDS& ids) const
     182                 :         {
     183           84590 :                 std::set<Tag> res;
     184          507017 :                 for (typename IDS::const_iterator i = ids.begin();
     185                 :                                 i != ids.end(); ++i)
     186          422427 :                         res.insert(tagByID(*i));
     187               0 :                 return res;
     188                 :         }
     189                 : 
     190                 :         /**
     191                 :          * Return the facet for the tag with the given ID
     192                 :          */
     193               0 :         Facet facetByTag(int id) const { return facetByID(tindex.facet(id)); }
     194                 : 
     195                 :         /**
     196                 :          * Return the facet with the given name
     197                 :          */
     198               4 :         Facet facetByName(const std::string& name) const { return facetByID(findex.id(name)); }
     199                 : 
     200                 :         /**
     201                 :          * Return the tag with the given full name
     202                 :          */
     203          105755 :         Tag tagByName(const std::string& fullname) const { return tagByID(tindex.id(fullname)); }
     204                 : 
     205                 :         /**
     206                 :          * Return all the facets in the vocabulary
     207                 :          */
     208               4 :         std::set< Facet > facets() const
     209                 :         {
     210               4 :                 std::set< Facet > res;
     211              91 :                 for (size_t i = 0; i < findex.size(); i++)
     212              87 :                         res.insert(facetByID(i));
     213               0 :                 return res;
     214                 :         }
     215                 : 
     216                 :         /**
     217                 :          * Return all the tags in the vocabulary
     218                 :          */
     219               6 :         std::set< Tag > tags() const
     220                 :         {
     221               6 :                 std::set< Tag > res;
     222            3106 :                 for (size_t i = 0; i < tindex.size(); i++)
     223            3100 :                         res.insert(tagByID(i));
     224               0 :                 return res;
     225                 :         }
     226                 : 
     227                 :         /**
     228                 :          * Return the tags in the given facet
     229                 :          */
     230              91 :         std::set< Tag > tags(int facet) const
     231                 :         {
     232              91 :                 std::set< Tag > res;
     233            2044 :                 for (int i = findex.firsttag(facet); i != -1 && i <= findex.lasttag(facet); i++)
     234            1953 :                         res.insert(tagByID(i));
     235               0 :                 return res;
     236                 :         }
     237                 : 
     238               3 :         std::set< Tag > tags(const std::string& facetName) const
     239                 :         {
     240               3 :                 return tags(findex.id(facetName));
     241                 :         }
     242                 : 
     243                 :         std::set< Tag > tags(const Facet& facet) const
     244                 :         {
     245                 :                 return tags(facet.id());
     246                 :         }
     247                 : 
     248                 : #if 0
     249                 :         /// Get the DerivedTagList with the Equates: expressions read from the vocabulary
     250                 :         const DerivedTagList& getEquations() const throw () { return equations; }
     251                 :         
     252                 :         /// Get a set with all the facets present in the vocabulary that are matched by `filter'
     253                 :         FacetSet facets(const FacetMatcher& filter) const throw () { return getFiltered(filter); }
     254                 : #endif
     255                 : 
     256                 : #if 0
     257                 :         // These functions are here just to be used by Facet and Tag.  I'm not
     258                 :         // making them private because I don't want Facet and Tag to access other
     259                 :         // Vocabulary member, and other classes can't use these anyway as Facet::Data and
     260                 :         // Tag::Data are protected
     261                 :         const Facet::Data& facetData(int idx) { return m_facets[idx]; }
     262                 :         const Tag::Data& tagData(int idx) { return m_tags[idx]; }
     263                 : #endif
     264                 : 
     265                 :         /// Get the facet name given the facet id
     266              88 :         std::string facetName(int id) const { return findex.name(id); }
     267                 : 
     268                 :         /// Get the tag name given the tag id
     269            1904 :         std::string tagName(int id) const { return tindex.name(id); }
     270                 : 
     271                 :         /// Get the tag name given the tag id
     272                 :         std::string tagShortName(int id) const;
     273                 : 
     274                 :         const std::map<std::string, std::string>& facetData(int id) const;
     275                 :         const std::map<std::string, std::string>& tagData(int id) const;
     276                 : };
     277                 : 
     278                 : }
     279                 : }
     280                 : 
     281                 : // vim:set ts=4 sw=4:
     282                 : #endif

Generated by: LTP GCOV extension version 1.6