LCOV - code coverage report
Current view: top level - backends/honey - honey_termlist.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 67 83 80.7 %
Date: 2019-06-30 05:20:33 Functions: 11 12 91.7 %
Branches: 31 66 47.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file honey_termlist.cc
       2                 :            :  * @brief A TermList in a honey database.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007,2008,2009,2010,2011,2018 Olly Betts
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or modify
       7                 :            :  * it under the terms of the GNU General Public License as published by
       8                 :            :  * the Free Software Foundation; either version 2 of the License, or
       9                 :            :  * (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This program 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
      14                 :            :  * GNU General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU General Public License
      17                 :            :  * along with this program; if not, write to the Free Software
      18                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      19                 :            :  */
      20                 :            : 
      21                 :            : #include <config.h>
      22                 :            : 
      23                 :            : #include "honey_termlist.h"
      24                 :            : 
      25                 :            : #include "expand/expandweight.h"
      26                 :            : 
      27                 :            : using namespace std;
      28                 :            : 
      29                 :            : [[noreturn]]
      30                 :            : static void
      31                 :          0 : throw_database_corrupt(const char* item, const char* pos)
      32                 :            : {
      33         [ #  # ]:          0 :     string message;
      34         [ #  # ]:          0 :     if (pos != NULL) {
      35         [ #  # ]:          0 :         message = "Value overflow unpacking termlist: ";
      36                 :            :     } else {
      37         [ #  # ]:          0 :         message = "Out of data unpacking termlist: ";
      38                 :            :     }
      39         [ #  # ]:          0 :     message += item;
      40 [ #  # ][ #  # ]:          0 :     throw Xapian::DatabaseCorruptError(message);
      41                 :            : }
      42                 :            : 
      43                 :      40831 : HoneyTermList::HoneyTermList(const HoneyDatabase* db_, Xapian::docid did_)
      44 [ +  - ][ +  - ]:      40836 :     : db(db_), did(did_)
      45                 :            : {
      46         [ +  + ]:      81657 :     if (!db->termlist_table.get_exact_entry(HoneyTermListTable::make_key(did),
      47   [ +  -  +  + ]:      81662 :                                             data)) {
      48                 :            :         // Document with no terms or values, or one which doesn't exist.
      49                 :          2 :         termlist_size = 0;
      50                 :          2 :         doclen = 0;
      51                 :          2 :         pos = end = data.data();
      52                 :      40826 :         return;
      53                 :            :     }
      54                 :            : 
      55                 :      40824 :     pos = data.data();
      56                 :      40824 :     end = pos + data.size();
      57                 :            : 
      58         [ -  + ]:      40824 :     if (pos == end)
      59                 :          0 :         throw_database_corrupt("No termlist data", pos);
      60                 :            : 
      61                 :      40824 :     size_t slot_enc_size = *pos++;
      62                 :            : 
      63                 :            :     // If the top bit is clear we have a 7-bit bitmap of slots used.
      64         [ +  + ]:      40824 :     if (slot_enc_size & 0x80) {
      65                 :        806 :         slot_enc_size &= 0x7f;
      66         [ -  + ]:        806 :         if (slot_enc_size == 0) {
      67         [ #  # ]:          0 :             if (!unpack_uint(&pos, end, &slot_enc_size)) {
      68 [ #  # ][ #  # ]:          5 :                 throw Xapian::DatabaseCorruptError("Termlist encoding corrupt");
                 [ #  # ]
      69                 :            :             }
      70                 :            :         }
      71                 :            : 
      72                 :            :         // Skip encoded slot data.
      73                 :        806 :         pos += slot_enc_size;
      74                 :            :     }
      75                 :            : 
      76         [ -  + ]:      40824 :     if (pos == end) {
      77                 :            :         // Document with values but no terms.
      78                 :          0 :         termlist_size = 0;
      79                 :          0 :         doclen = 0;
      80                 :          0 :         return;
      81                 :            :     }
      82                 :            : 
      83         [ -  + ]:      40824 :     if (!unpack_uint(&pos, end, &termlist_size)) {
      84                 :          0 :         throw_database_corrupt("termlist length", pos);
      85                 :            :     }
      86                 :      40824 :     ++termlist_size;
      87                 :            : 
      88         [ -  + ]:      40824 :     if (!unpack_uint(&pos, end, &doclen)) {
      89                 :      40824 :         throw_database_corrupt("doclen", pos);
      90                 :            :     }
      91                 :            : }
      92                 :            : 
      93                 :            : Xapian::termcount
      94                 :      10090 : HoneyTermList::get_approx_size() const
      95                 :            : {
      96                 :      10090 :     return termlist_size;
      97                 :            : }
      98                 :            : 
      99                 :            : void
     100                 :       1387 : HoneyTermList::accumulate_stats(Xapian::Internal::ExpandStats& stats) const
     101                 :            : {
     102                 :            :     Assert(!at_end());
     103                 :            :     stats.accumulate(current_wdf,
     104                 :            :                      doclen,
     105                 :       1387 :                      get_termfreq(),
     106                 :       1387 :                      db->get_doccount());
     107                 :       1387 : }
     108                 :            : 
     109                 :            : std::string
     110                 :      59214 : HoneyTermList::get_termname() const
     111                 :            : {
     112                 :            :     Assert(!at_end());
     113                 :      59214 :     return current_term;
     114                 :            : }
     115                 :            : 
     116                 :            : Xapian::termcount
     117                 :      45220 : HoneyTermList::get_wdf() const
     118                 :            : {
     119                 :            :     Assert(!at_end());
     120                 :      45220 :     return current_wdf;
     121                 :            : }
     122                 :            : 
     123                 :            : Xapian::doccount
     124                 :      23796 : HoneyTermList::get_termfreq() const
     125                 :            : {
     126                 :            :     Assert(!at_end());
     127         [ +  - ]:      23796 :     if (current_termfreq == 0)
     128                 :      23796 :         db->get_freqs(current_term, &current_termfreq, NULL);
     129                 :      23794 :     return current_termfreq;
     130                 :            : }
     131                 :            : 
     132                 :            : TermList*
     133                 :      45559 : HoneyTermList::next()
     134                 :            : {
     135                 :            :     Assert(!at_end());
     136                 :            : 
     137         [ +  + ]:      45559 :     if (pos == end) {
     138                 :            :         // Set pos to NULL so at_end() returns true.
     139                 :      20212 :         pos = NULL;
     140                 :      20212 :         return NULL;
     141                 :            :     }
     142                 :            : 
     143                 :      25347 :     current_wdf = 0;
     144                 :            : 
     145         [ +  + ]:      25347 :     if (!current_term.empty()) {
     146                 :       5108 :         size_t reuse = static_cast<unsigned char>(*pos++);
     147         [ +  - ]:       5108 :         if (reuse > current_term.size()) {
     148                 :       5108 :             current_wdf = reuse / (current_term.size() + 1);
     149                 :       5108 :             reuse = reuse % (current_term.size() + 1);
     150                 :            :         }
     151                 :       5108 :         current_term.resize(reuse);
     152                 :            :     }
     153                 :            : 
     154         [ +  + ]:      25347 :     if (current_wdf) {
     155                 :       5108 :         --current_wdf;
     156                 :            :     } else {
     157         [ -  + ]:      20239 :         if (!unpack_uint(&pos, end, &current_wdf)) {
     158                 :          0 :             throw_database_corrupt("wdf", pos);
     159                 :            :         }
     160                 :            :     }
     161                 :            : 
     162         [ -  + ]:      25347 :     if (pos == end)
     163                 :          0 :         throw_database_corrupt("term", NULL);
     164                 :            : 
     165                 :      25347 :     size_t append = static_cast<unsigned char>(*pos++);
     166         [ -  + ]:      25347 :     if (size_t(end - pos) < append)
     167                 :          0 :         throw_database_corrupt("term", NULL);
     168                 :            : 
     169                 :      25347 :     current_term.append(pos, append);
     170                 :      25347 :     pos += append;
     171                 :            : 
     172                 :            :     // Indicate that termfreq hasn't been read for the current term.
     173                 :      25347 :     current_termfreq = 0;
     174                 :            : 
     175                 :      25347 :     return NULL;
     176                 :            : }
     177                 :            : 
     178                 :            : TermList*
     179                 :         74 : HoneyTermList::skip_to(const std::string& term)
     180                 :            : {
     181 [ +  + ][ +  + ]:        568 :     while (!at_end() && current_term < term) {
                 [ +  + ]
     182                 :        494 :         HoneyTermList::next();
     183                 :            :     }
     184                 :         74 :     return NULL;
     185                 :            : }
     186                 :            : 
     187                 :            : bool
     188                 :      45726 : HoneyTermList::at_end() const
     189                 :            : {
     190                 :      45726 :     return pos == NULL;
     191                 :            : }
     192                 :            : 
     193                 :            : Xapian::termcount
     194                 :      11203 : HoneyTermList::positionlist_count() const
     195                 :            : {
     196                 :      11203 :     return db->position_table.positionlist_count(did, current_term);
     197                 :            : }
     198                 :            : 
     199                 :            : PositionList*
     200                 :      22403 : HoneyTermList::positionlist_begin() const
     201                 :            : {
     202                 :      22403 :     return db->open_position_list(did, current_term);
     203                 :            : }

Generated by: LCOV version 1.11