LCOV - code coverage report
Current view: top level - backends/honey - honey_spelling.h (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 5 31 16.1 %
Date: 2019-06-30 05:20:33 Functions: 3 11 27.3 %
Branches: 5 34 14.7 %

           Branch data     Line data    Source code
       1                 :            : /** @file honey_spelling.h
       2                 :            :  * @brief Spelling correction data for a honey database.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007,2008,2009,2010,2011,2014,2015,2016,2017,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                 :            : #ifndef XAPIAN_INCLUDED_HONEY_SPELLING_H
      22                 :            : #define XAPIAN_INCLUDED_HONEY_SPELLING_H
      23                 :            : 
      24                 :            : #include <xapian/types.h>
      25                 :            : 
      26                 :            : #include "honey_lazytable.h"
      27                 :            : #include "api/termlist.h"
      28                 :            : 
      29                 :            : #include <map>
      30                 :            : #include <set>
      31                 :            : #include <string>
      32                 :            : #include <cstring> // For memcpy() and memcmp().
      33                 :            : 
      34                 :            : namespace Honey {
      35                 :            : 
      36                 :            : const unsigned KEY_PREFIX_BOOKEND = 0x00;
      37                 :            : const unsigned KEY_PREFIX_HEAD = 0x01;
      38                 :            : const unsigned KEY_PREFIX_MIDDLE = 0x02;
      39                 :            : const unsigned KEY_PREFIX_TAIL = 0x03;
      40                 :            : const unsigned KEY_PREFIX_WORD = 0x04;
      41                 :            : 
      42                 :            : inline std::string
      43                 :          0 : make_spelling_wordlist_key(const std::string& word)
      44                 :            : {
      45         [ #  # ]:          0 :     if (rare(static_cast<unsigned char>(word[0]) <= KEY_PREFIX_WORD))
      46                 :          0 :         return char(KEY_PREFIX_WORD) + word;
      47                 :          0 :     return word;
      48                 :            : }
      49                 :            : 
      50                 :            : struct fragment {
      51                 :            :     char data[4];
      52                 :            : 
      53                 :            :     /// Default constructor.
      54                 :            :     fragment() { }
      55                 :            : 
      56                 :            :     /// Zero-initialising constructor.
      57                 :          0 :     explicit fragment(int) { std::memset(data, 0, 4); }
      58                 :            : 
      59                 :            :     /// Allow implicit conversion.
      60                 :            :     explicit fragment(char data_[4]) { std::memcpy(data, data_, 4); }
      61                 :            : 
      62                 :          0 :     char & operator[] (unsigned i) { return data[i]; }
      63                 :            :     const char & operator[] (unsigned i) const { return data[i]; }
      64                 :            : 
      65                 :          0 :     operator std::string() const {
      66 [ #  # ][ #  # ]:          0 :         return std::string(data, data[0] == KEY_PREFIX_MIDDLE ? 4 : 3);
      67                 :            :     }
      68                 :            : 
      69                 :          0 :     bool operator<(const fragment &b) const {
      70                 :          0 :         return std::memcmp(data, b.data, 4) < 0;
      71                 :            :     }
      72                 :            : };
      73                 :            : 
      74                 :            : }
      75                 :            : 
      76                 :        710 : class HoneySpellingTable : public HoneyLazyTable {
      77                 :            :     void toggle_word(const std::string & word);
      78                 :            :     void toggle_fragment(Honey::fragment frag, const std::string & word);
      79                 :            : 
      80                 :            :     mutable std::map<std::string, Xapian::termcount> wordfreq_changes;
      81                 :            : 
      82                 :            :     /** Changes to make to the termlists.
      83                 :            :      *
      84                 :            :      *  This list is essentially xor-ed with the list on disk, so an entry
      85                 :            :      *  here either means a new entry needs to be added on disk, or an
      86                 :            :      *  existing entry on disk needs to be removed.  We do it this way so
      87                 :            :      *  we don't need to store an additional add/remove flag for every
      88                 :            :      *  word.
      89                 :            :      */
      90                 :            :     mutable std::map<Honey::fragment, std::set<std::string>> termlist_deltas;
      91                 :            : 
      92                 :            :     /** Used to track an upper bound on wordfreq. */
      93                 :            :     Xapian::termcount wordfreq_upper_bound = 0;
      94                 :            : 
      95                 :            :   public:
      96                 :            :     /** Create a new HoneySpellingTable object.
      97                 :            :      *
      98                 :            :      *  This method does not create or open the table on disk - you
      99                 :            :      *  must call the create() or open() methods respectively!
     100                 :            :      *
     101                 :            :      *  @param dbdir            The directory the honey database is stored in.
     102                 :            :      *  @param readonly         true if we're opening read-only, else false.
     103                 :            :      */
     104                 :        354 :     HoneySpellingTable(const std::string & dbdir, bool readonly)
     105 [ +  - ][ +  - ]:        354 :         : HoneyLazyTable("spelling", dbdir + "/spelling.", readonly) { }
                 [ +  - ]
     106                 :            : 
     107                 :          1 :     HoneySpellingTable(int fd, off_t offset_, bool readonly)
     108 [ +  - ][ +  - ]:          1 :         : HoneyLazyTable("spelling", fd, offset_, readonly) { }
     109                 :            : 
     110                 :            :     /** Merge in batched-up changes. */
     111                 :            :     void merge_changes();
     112                 :            : 
     113                 :            :     void add_word(const std::string & word, Xapian::termcount freqinc);
     114                 :            :     Xapian::termcount remove_word(const std::string & word,
     115                 :            :                                   Xapian::termcount freqdec);
     116                 :            : 
     117                 :            :     TermList * open_termlist(const std::string & word);
     118                 :            : 
     119                 :            :     Xapian::doccount get_word_frequency(const std::string & word) const;
     120                 :            : 
     121                 :            :     void set_wordfreq_upper_bound(Xapian::termcount ub) {
     122                 :            :         wordfreq_upper_bound = ub;
     123                 :            :     }
     124                 :            : 
     125                 :            :     /** Override methods of HoneyTable.
     126                 :            :      *
     127                 :            :      *  NB: these aren't virtual, but we always call them on the subclass in
     128                 :            :      *  cases where it matters.
     129                 :            :      *  @{
     130                 :            :      */
     131                 :            : 
     132                 :            :     bool is_modified() const {
     133                 :            :         return !wordfreq_changes.empty() || HoneyTable::is_modified();
     134                 :            :     }
     135                 :            : 
     136                 :            :     /** Returns updated wordfreq upper bound. */
     137                 :            :     Xapian::termcount flush_db() {
     138                 :            :         merge_changes();
     139                 :            :         HoneyTable::flush_db();
     140                 :            :         return wordfreq_upper_bound;
     141                 :            :     }
     142                 :            : 
     143                 :            :     void cancel(const Honey::RootInfo & root_info,
     144                 :            :                 honey_revision_number_t rev) {
     145                 :            :         // Discard batched-up changes.
     146                 :            :         wordfreq_changes.clear();
     147                 :            :         termlist_deltas.clear();
     148                 :            : 
     149                 :            :         HoneyTable::cancel(root_info, rev);
     150                 :            :     }
     151                 :            : 
     152                 :            :     // @}
     153                 :            : };
     154                 :            : 
     155                 :            : /** The list of words containing a particular trigram. */
     156         [ #  # ]:          0 : class HoneySpellingTermList : public TermList {
     157                 :            :     /// The encoded data.
     158                 :            :     std::string data;
     159                 :            : 
     160                 :            :     /// Position in the data.
     161                 :            :     unsigned p = 0;
     162                 :            : 
     163                 :            :     /// The current term.
     164                 :            :     std::string current_term;
     165                 :            : 
     166                 :            :     /** Number of constant characters on the end of the value.
     167                 :            :      *
     168                 :            :      *  Valid values once iterating are 0, 1, 2.  Before iteration, can be
     169                 :            :      *  0 (no head or tail), 2 (two tails), -1 (one head, one tail -> 1 once
     170                 :            :      *  iterating) or -2 (two heads, no tail -> 0 once iterating).
     171                 :            :      */
     172                 :            :     int tail = 0;
     173                 :            : 
     174                 :            :     /// Copying is not allowed.
     175                 :            :     HoneySpellingTermList(const HoneySpellingTermList &);
     176                 :            : 
     177                 :            :     /// Assignment is not allowed.
     178                 :            :     void operator=(const HoneySpellingTermList &);
     179                 :            : 
     180                 :            :   public:
     181                 :            :     /// Constructor.
     182                 :          0 :     explicit HoneySpellingTermList(const std::string& data_)
     183 [ #  # ][ #  # ]:          0 :         : data(data_) { }
     184                 :            : 
     185                 :            :     /// Constructor for head/bookend/tail terms.
     186                 :          0 :     HoneySpellingTermList(const std::string& data_,
     187                 :            :                           const char* key)
     188 [ #  # ][ #  # ]:          0 :         : data(data_) {
     189                 :          0 :         unsigned char first_ch = key[0];
     190                 :            :         AssertRel(first_ch, <, Honey::KEY_PREFIX_WORD);
     191   [ #  #  #  # ]:          0 :         switch (first_ch) {
     192                 :            :             case Honey::KEY_PREFIX_BOOKEND:
     193                 :          0 :                 tail = -1;
     194                 :          0 :                 break;
     195                 :            :             case Honey::KEY_PREFIX_HEAD:
     196                 :          0 :                 tail = -2;
     197                 :          0 :                 break;
     198                 :            :             case Honey::KEY_PREFIX_TAIL:
     199                 :          0 :                 tail = 2;
     200                 :          0 :                 break;
     201                 :            :         }
     202         [ #  # ]:          0 :         if (tail != 0)
     203         [ #  # ]:          0 :             current_term.assign(key + 1, 2);
     204                 :          0 :     }
     205                 :            : 
     206                 :            :     Xapian::termcount get_approx_size() const;
     207                 :            : 
     208                 :            :     std::string get_termname() const;
     209                 :            : 
     210                 :            :     Xapian::termcount get_wdf() const;
     211                 :            : 
     212                 :            :     Xapian::doccount get_termfreq() const;
     213                 :            : 
     214                 :            :     Xapian::termcount get_collection_freq() const;
     215                 :            : 
     216                 :            :     TermList * next();
     217                 :            : 
     218                 :            :     TermList * skip_to(const std::string & term);
     219                 :            : 
     220                 :            :     bool at_end() const;
     221                 :            : 
     222                 :            :     Xapian::termcount positionlist_count() const;
     223                 :            : 
     224                 :            :     PositionList* positionlist_begin() const;
     225                 :            : };
     226                 :            : 
     227                 :            : #endif // XAPIAN_INCLUDED_HONEY_SPELLING_H

Generated by: LCOV version 1.11