LCOV - code coverage report
Current view: top level - backends/honey - honey_positionlist.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 4ba52dacf4fb Lines: 64 93 68.8 %
Date: 2019-05-20 14:58:19 Functions: 8 12 66.7 %
Branches: 35 96 36.5 %

           Branch data     Line data    Source code
       1                 :            : /** @file honey_positionlist.cc
       2                 :            :  * @brief A position list in a honey database.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2004,2005,2006,2008,2009,2010,2013,2017,2019 Olly Betts
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU General Public License as
       8                 :            :  * published by the Free Software Foundation; either version 2 of the
       9                 :            :  * License, or (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
      19                 :            :  * USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : 
      24                 :            : #include "honey_positionlist.h"
      25                 :            : 
      26                 :            : #include <xapian/types.h>
      27                 :            : 
      28                 :            : #include "bitstream.h"
      29                 :            : #include "debuglog.h"
      30                 :            : #include "honey_cursor.h"
      31                 :            : #include "pack.h"
      32                 :            : 
      33                 :            : #include <string>
      34                 :            : 
      35                 :            : using namespace std;
      36                 :            : 
      37                 :            : void
      38                 :          0 : HoneyPositionTable::pack(string & s,
      39                 :            :                          const Xapian::VecCOW<Xapian::termpos> & vec) const
      40                 :            : {
      41                 :            :     LOGCALL_VOID(DB, "HoneyPositionTable::pack", s | vec);
      42                 :            :     Assert(!vec.empty());
      43                 :            : 
      44                 :          0 :     pack_uint(s, vec.back());
      45                 :            : 
      46         [ #  # ]:          0 :     if (vec.size() > 1) {
      47         [ #  # ]:          0 :         BitWriter wr(s);
      48 [ #  # ][ #  # ]:          0 :         wr.encode(vec[0], vec.back());
                 [ #  # ]
      49 [ #  # ][ #  # ]:          0 :         wr.encode(vec.size() - 2, vec.back() - vec[0]);
                 [ #  # ]
      50         [ #  # ]:          0 :         wr.encode_interpolative(vec, 0, vec.size() - 1);
      51 [ #  # ][ #  # ]:          0 :         swap(s, wr.freeze());
      52                 :            :     }
      53                 :          0 : }
      54                 :            : 
      55                 :            : Xapian::termcount
      56                 :       1203 : HoneyPositionTable::positionlist_count(Xapian::docid did,
      57                 :            :                                        const string & term) const
      58                 :            : {
      59                 :            :     LOGCALL(DB, Xapian::termcount, "HoneyPositionTable::positionlist_count", did | term);
      60                 :            : 
      61         [ +  - ]:       1203 :     string data;
      62 [ +  - ][ +  - ]:       1203 :     if (!get_exact_entry(make_key(did, term), data)) {
                 [ -  + ]
      63                 :          0 :         RETURN(0);
      64                 :            :     }
      65                 :            : 
      66                 :       1203 :     const char * pos = data.data();
      67                 :       1203 :     const char * end = pos + data.size();
      68                 :            :     Xapian::termpos pos_last;
      69         [ -  + ]:       1203 :     if (!unpack_uint(&pos, end, &pos_last)) {
      70 [ #  # ][ #  # ]:          0 :         throw Xapian::DatabaseCorruptError("Position list data corrupt");
                 [ #  # ]
      71                 :            :     }
      72         [ +  + ]:       1203 :     if (pos == end) {
      73                 :            :         // Special case for single entry position list.
      74                 :       1033 :         RETURN(1);
      75                 :            :     }
      76                 :            : 
      77                 :            :     // Skip the header we just read.
      78                 :        340 :     BitReader rd(pos, end);
      79         [ +  - ]:        170 :     Xapian::termpos pos_first = rd.decode(pos_last);
      80         [ +  - ]:        170 :     Xapian::termpos pos_size = rd.decode(pos_last - pos_first) + 2;
      81                 :       1203 :     RETURN(pos_size);
      82                 :            : }
      83                 :            : 
      84                 :            : ///////////////////////////////////////////////////////////////////////////
      85                 :            : 
      86                 :            : void
      87                 :       3259 : HoneyBasePositionList::set_data(const string& data)
      88                 :            : {
      89                 :            :     LOGCALL_VOID(DB, "HoneyBasePositionList::set_data", data);
      90                 :            : 
      91                 :       3259 :     have_started = false;
      92                 :            : 
      93         [ -  + ]:       3259 :     if (data.empty()) {
      94                 :            :         // There's no positional information for this term.
      95                 :          0 :         size = 0;
      96                 :          0 :         last = 0;
      97                 :          0 :         current_pos = 1;
      98                 :       3259 :         return;
      99                 :            :     }
     100                 :            : 
     101                 :       3259 :     const char* pos = data.data();
     102                 :       3259 :     const char* end = pos + data.size();
     103                 :            :     Xapian::termpos pos_last;
     104         [ -  + ]:       3259 :     if (!unpack_uint(&pos, end, &pos_last)) {
     105 [ #  # ][ #  # ]:          0 :         throw Xapian::DatabaseCorruptError("Position list data corrupt");
                 [ #  # ]
     106                 :            :     }
     107                 :            : 
     108         [ +  + ]:       3259 :     if (pos == end) {
     109                 :            :         // Special case for single entry position list.
     110                 :       2807 :         size = 1;
     111                 :       2807 :         current_pos = last = pos_last;
     112                 :       2807 :         return;
     113                 :            :     }
     114                 :            : 
     115                 :        452 :     rd.init(pos, end);
     116         [ +  - ]:        452 :     Xapian::termpos pos_first = rd.decode(pos_last);
     117         [ +  - ]:        452 :     Xapian::termpos pos_size = rd.decode(pos_last - pos_first) + 2;
     118         [ +  - ]:        452 :     rd.decode_interpolative(0, pos_size - 1, pos_first, pos_last);
     119                 :        452 :     size = pos_size;
     120                 :        452 :     last = pos_last;
     121                 :        452 :     current_pos = pos_first;
     122                 :            : }
     123                 :            : 
     124                 :            : Xapian::termcount
     125                 :         94 : HoneyBasePositionList::get_approx_size() const
     126                 :            : {
     127                 :            :     LOGCALL(DB, Xapian::termcount, "HoneyBasePositionList::get_approx_size", NO_ARGS);
     128                 :         94 :     RETURN(size);
     129                 :            : }
     130                 :            : 
     131                 :            : Xapian::termpos
     132                 :          0 : HoneyBasePositionList::back() const
     133                 :            : {
     134                 :            :     LOGCALL(DB, Xapian::termpos, "HoneyBasePositionList::back", NO_ARGS);
     135                 :          0 :     RETURN(last);
     136                 :            : }
     137                 :            : 
     138                 :            : Xapian::termpos
     139                 :       5038 : HoneyBasePositionList::get_position() const
     140                 :            : {
     141                 :            :     LOGCALL(DB, Xapian::termpos, "HoneyBasePositionList::get_position", NO_ARGS);
     142                 :            :     Assert(have_started);
     143                 :       5038 :     RETURN(current_pos);
     144                 :            : }
     145                 :            : 
     146                 :            : bool
     147                 :       6202 : HoneyBasePositionList::next()
     148                 :            : {
     149                 :            :     LOGCALL(DB, bool, "HoneyBasePositionList::next", NO_ARGS);
     150         [ +  + ]:       6202 :     if (rare(!have_started)) {
     151                 :       2896 :         have_started = true;
     152                 :       2896 :         return current_pos <= last;
     153                 :            :     }
     154         [ +  + ]:       3306 :     if (current_pos == last) {
     155                 :       2640 :         return false;
     156                 :            :     }
     157                 :        666 :     current_pos = rd.decode_interpolative_next();
     158                 :        666 :     return true;
     159                 :            : }
     160                 :            : 
     161                 :            : bool
     162                 :        418 : HoneyBasePositionList::skip_to(Xapian::termpos termpos)
     163                 :            : {
     164                 :            :     LOGCALL(DB, bool, "HoneyBasePositionList::skip_to", termpos);
     165                 :        418 :     have_started = true;
     166         [ +  + ]:        418 :     if (termpos >= last) {
     167         [ +  + ]:        170 :         if (termpos == last) {
     168                 :         48 :             current_pos = last;
     169                 :         48 :             return true;
     170                 :            :         }
     171                 :        122 :         return false;
     172                 :            :     }
     173         [ +  + ]:        316 :     while (current_pos < termpos) {
     174         [ -  + ]:         68 :         if (current_pos == last) {
     175                 :          0 :             return false;
     176                 :            :         }
     177                 :         68 :         current_pos = rd.decode_interpolative_next();
     178                 :            :     }
     179                 :        248 :     return true;
     180                 :            : }
     181                 :            : 
     182         [ #  # ]:          0 : HoneyPositionList::HoneyPositionList(string&& data)
     183                 :            : {
     184                 :            :     LOGCALL_CTOR(DB, "HoneyPositionList", data);
     185                 :            : 
     186         [ #  # ]:          0 :     pos_data = std::move(data);
     187                 :            : 
     188         [ #  # ]:          0 :     set_data(pos_data);
     189                 :          0 : }
     190                 :            : 
     191                 :       2641 : HoneyPositionList::HoneyPositionList(const HoneyTable& table,
     192                 :            :                                      Xapian::docid did,
     193         [ +  - ]:       2642 :                                      const string& term)
     194                 :            : {
     195                 :            :     LOGCALL_CTOR(DB, "HoneyPositionList", table | did | term);
     196                 :            : 
     197         [ -  + ]:       2640 :     if (!table.get_exact_entry(HoneyPositionTable::make_key(did, term),
     198 [ +  - ][ +  + ]:       2641 :                                pos_data)) {
     199         [ #  # ]:          0 :         pos_data.clear();
     200                 :            :     }
     201                 :            : 
     202         [ +  - ]:       2640 :     set_data(pos_data);
     203                 :       2640 : }
     204                 :            : 
     205                 :            : void
     206                 :          0 : HoneyRePositionList::assign_data(string&& data)
     207                 :            : {
     208                 :            :     LOGCALL_VOID(DB, "HoneyRePositionList::assign_data", data);
     209                 :            : 
     210                 :            :     // We need to ensure the data stays valid while in use, so abuse the cursor
     211                 :            :     // current_tag member as somewhere to store it.
     212                 :          0 :     cursor.to_end();
     213                 :          0 :     cursor.current_tag = std::move(data);
     214                 :            : 
     215                 :          0 :     set_data(cursor.current_tag);
     216                 :          0 : }
     217                 :            : 
     218                 :            : void
     219                 :        619 : HoneyRePositionList::read_data(Xapian::docid did,
     220                 :            :                                const string& term)
     221                 :            : {
     222                 :            :     LOGCALL_VOID(DB, "HoneyRePositionList::read_data", did | term);
     223                 :            : 
     224 [ +  - ][ -  + ]:        619 :     if (!cursor.find_exact(HoneyPositionTable::make_key(did, term))) {
     225                 :          0 :         cursor.current_tag.clear();
     226                 :            :     } else {
     227                 :        619 :         cursor.read_tag();
     228                 :            :     }
     229                 :            : 
     230                 :        619 :     set_data(cursor.current_tag);
     231                 :        619 : }

Generated by: LCOV version 1.11