LCOV - code coverage report
Current view: top level - weight - weightinternal.h (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core c2b6f1024d3a Lines: 58 78 74.4 %
Date: 2019-05-16 09:13:18 Functions: 13 15 86.7 %
Branches: 29 56 51.8 %

           Branch data     Line data    Source code
       1                 :            : /** @file weightinternal.h
       2                 :            :  * @brief Xapian::Weight::Internal class, holding database and term statistics.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007 Lemur Consulting Ltd
       5                 :            :  * Copyright (C) 2009,2010,2011,2013,2014,2015 Olly Betts
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU General Public License as
       9                 :            :  * published by the Free Software Foundation; either version 2 of the
      10                 :            :  * License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this program; if not, write to the Free Software
      19                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #ifndef XAPIAN_INCLUDED_WEIGHTINTERNAL_H
      23                 :            : #define XAPIAN_INCLUDED_WEIGHTINTERNAL_H
      24                 :            : 
      25                 :            : #include "xapian/weight.h"
      26                 :            : 
      27                 :            : #include "xapian/database.h"
      28                 :            : #include "xapian/error.h"
      29                 :            : #include "xapian/query.h"
      30                 :            : 
      31                 :            : #include "backends/databaseinternal.h"
      32                 :            : #include "internaltypes.h"
      33                 :            : #include "omassert.h"
      34                 :            : 
      35                 :            : #include <cerrno>
      36                 :            : #include <cstdlib>
      37                 :            : #include <map>
      38                 :            : #include <string>
      39                 :            : 
      40                 :            : /// The frequencies for a term.
      41                 :            : struct TermFreqs {
      42                 :            :     Xapian::doccount termfreq;
      43                 :            :     Xapian::doccount reltermfreq;
      44                 :            :     Xapian::termcount collfreq;
      45                 :            :     double max_part;
      46                 :            : 
      47                 :     266208 :     TermFreqs() : termfreq(0), reltermfreq(0), collfreq(0), max_part(0.0) {}
      48                 :      24569 :     TermFreqs(Xapian::doccount termfreq_,
      49                 :            :               Xapian::doccount reltermfreq_,
      50                 :            :               Xapian::termcount collfreq_,
      51                 :            :               double max_part_ = 0.0)
      52                 :            :         : termfreq(termfreq_),
      53                 :            :           reltermfreq(reltermfreq_),
      54                 :            :           collfreq(collfreq_),
      55                 :      24569 :           max_part(max_part_) {}
      56                 :            : 
      57                 :       7380 :     void operator+=(const TermFreqs & other) {
      58                 :       7380 :         termfreq += other.termfreq;
      59                 :       7380 :         reltermfreq += other.reltermfreq;
      60                 :       7380 :         collfreq += other.collfreq;
      61                 :       7380 :         max_part += other.max_part;
      62                 :       7380 :     }
      63                 :            : 
      64                 :            :     /// Return a std::string describing this object.
      65                 :            :     std::string get_description() const;
      66                 :            : };
      67                 :            : 
      68                 :            : namespace Xapian {
      69                 :            : 
      70                 :            : class RSet;
      71                 :            : 
      72                 :            : /** Class to hold statistics for a given collection. */
      73                 :     382710 : class Weight::Internal {
      74                 :            : #ifdef XAPIAN_ASSERTIONS
      75                 :            :     /** Number of sub-databases. */
      76                 :            :     size_t subdbs;
      77                 :            : 
      78                 :            :     /** True if we've finalised the stats.
      79                 :            :      *
      80                 :            :      *  Used for assertions.
      81                 :            :      */
      82                 :            :     mutable bool finalised;
      83                 :            : #endif
      84                 :            : 
      85                 :            :   public:
      86                 :            :     /** Total length of all documents in the collection. */
      87                 :            :     Xapian::totallength total_length;
      88                 :            : 
      89                 :            :     /** Number of documents in the collection. */
      90                 :            :     Xapian::doccount collection_size;
      91                 :            : 
      92                 :            :     /** Number of relevant documents in the collection. */
      93                 :            :     Xapian::doccount rset_size;
      94                 :            : 
      95                 :            :     /** Number of terms in the collection. */
      96                 :            :     Xapian::termcount total_term_count;
      97                 :            : 
      98                 :            :     /** Has max_part been set for any term?
      99                 :            :      *
     100                 :            :      *  If not, we can avoid having to serialise max_part.
     101                 :            :      */
     102                 :            :     bool have_max_part;
     103                 :            : 
     104                 :            :     /** Database to get the bounds on doclength and wdf from. */
     105                 :            :     Xapian::Database db;
     106                 :            : 
     107                 :            :     /** The query. */
     108                 :            :     Xapian::Query query;
     109                 :            : 
     110                 :            :     /** Map of term frequencies and relevant term frequencies for the
     111                 :            :      *  collection. */
     112                 :            :     std::map<std::string, TermFreqs> termfreqs;
     113                 :            : 
     114                 :     191355 :     Internal()
     115                 :            :         :
     116                 :            : #ifdef XAPIAN_ASSERTIONS
     117                 :            :           subdbs(0), finalised(false),
     118                 :            : #endif
     119                 :            :           total_length(0), collection_size(0), rset_size(0),
     120         [ +  - ]:     191355 :           total_term_count(0), have_max_part(false) { }
     121                 :            : 
     122                 :            :     /** Add in the supplied statistics from a sub-database.
     123                 :            :      *
     124                 :            :      *  Used for remote databases, where we pass across a serialised stats
     125                 :            :      *  object, unserialise it, and add it to our total.
     126                 :            :      */
     127                 :            :     Internal & operator+=(const Internal & inc);
     128                 :            : 
     129                 :     160123 :     void set_query(const Xapian::Query &query_) {
     130                 :            :         AssertEq(subdbs, 0);
     131                 :     160123 :         query = query_;
     132                 :     160123 :     }
     133                 :            : 
     134                 :            :     /// Accumulate the rtermfreqs for terms in the query.
     135                 :            :     void accumulate_stats(const Xapian::Database::Internal &sub_db,
     136                 :            :                           const Xapian::RSet &rset);
     137                 :            : 
     138                 :            :     /** Get the frequencies for the given term.
     139                 :            :      *
     140                 :            :      *  termfreq is "n_t", the number of documents in the collection indexed by
     141                 :            :      *  the given term.
     142                 :            :      *
     143                 :            :      *  reltermfreq is "r_t", the number of relevant documents in the
     144                 :            :      *  collection indexed by the given term.
     145                 :            :      *
     146                 :            :      *  collfreq is the total number of occurrences of the term in all
     147                 :            :      *  documents.
     148                 :            :      */
     149                 :     309783 :     bool get_stats(const std::string & term,
     150                 :            :                    Xapian::doccount & termfreq,
     151                 :            :                    Xapian::doccount & reltermfreq,
     152                 :            :                    Xapian::termcount & collfreq) const {
     153                 :            : #ifdef XAPIAN_ASSERTIONS
     154                 :            :         finalised = true;
     155                 :            : #endif
     156                 :            :         // We pass an empty std::string for term when calculating the extra
     157                 :            :         // weight.
     158         [ -  + ]:     309783 :         if (term.empty()) {
     159                 :          0 :             termfreq = collection_size;
     160                 :          0 :             collfreq = collection_size;
     161                 :          0 :             reltermfreq = rset_size;
     162                 :          0 :             return true;
     163                 :            :         }
     164                 :            : 
     165         [ +  - ]:     309783 :         auto i = termfreqs.find(term);
     166         [ +  + ]:     309783 :         if (i == termfreqs.end()) {
     167                 :         14 :             termfreq = reltermfreq = collfreq = 0;
     168                 :         14 :             return false;
     169                 :            :         }
     170                 :            : 
     171                 :     309769 :         termfreq = i->second.termfreq;
     172                 :     309769 :         reltermfreq = i->second.reltermfreq;
     173                 :     309769 :         collfreq = i->second.collfreq;
     174                 :     309783 :         return true;
     175                 :            :     }
     176                 :            : 
     177                 :            :     /// Get just the termfreq.
     178                 :        126 :     bool get_stats(const std::string & term,
     179                 :            :                    Xapian::doccount & termfreq) const {
     180                 :            :         Xapian::doccount dummy1;
     181                 :            :         Xapian::termcount dummy2;
     182         [ +  - ]:        126 :         return get_stats(term, termfreq, dummy1, dummy2);
     183                 :            :     }
     184                 :            : 
     185                 :            :     /// Get the termweight.
     186                 :        626 :     bool get_termweight(const std::string & term, double & termweight) const {
     187                 :            : #ifdef XAPIAN_ASSERTIONS
     188                 :            :         finalised = true;
     189                 :            : #endif
     190                 :        626 :         termweight = 0.0;
     191         [ -  + ]:        626 :         if (term.empty()) {
     192                 :          0 :             return false;
     193                 :            :         }
     194                 :            : 
     195         [ +  - ]:        626 :         auto i = termfreqs.find(term);
     196         [ +  + ]:        626 :         if (i == termfreqs.end()) {
     197                 :         14 :             return false;
     198                 :            :         }
     199                 :            : 
     200                 :        612 :         termweight = i->second.max_part;
     201                 :        626 :         return true;
     202                 :            :     }
     203                 :            : 
     204                 :            :     /** Get the minimum and maximum termweights.
     205                 :            :      *
     206                 :            :      *  Used by the snippet code.
     207                 :            :      */
     208                 :        501 :     void get_max_termweight(double & min_tw, double & max_tw) {
     209                 :        501 :         auto i = termfreqs.begin();
     210 [ +  + ][ +  + ]:        999 :         while (i != termfreqs.end() && i->second.max_part == 0.0) ++i;
         [ +  - ][ +  + ]
     211         [ +  + ]:        501 :         if (rare(i == termfreqs.end())) {
     212                 :        236 :             min_tw = max_tw = 0.0;
     213                 :        236 :             return;
     214                 :            :         }
     215                 :        265 :         min_tw = max_tw = i->second.max_part;
     216         [ +  + ]:        478 :         while (++i != termfreqs.end()) {
     217                 :        213 :             double max_part = i->second.max_part;
     218         [ -  + ]:        213 :             if (max_part > max_tw) {
     219                 :          0 :                 max_tw = max_part;
     220 [ +  + ][ -  + ]:        213 :             } else if (max_part < min_tw && max_part != 0.0) {
     221                 :          0 :                 min_tw = max_part;
     222                 :            :             }
     223                 :            :         }
     224                 :            :     }
     225                 :            : 
     226                 :            :     /// Set max_part for a term.
     227                 :     310719 :     void set_max_part(const std::string & term, double max_part) {
     228                 :     310719 :         have_max_part = true;
     229                 :            :         Assert(!term.empty());
     230         [ +  - ]:     310719 :         auto i = termfreqs.find(term);
     231         [ +  - ]:     310719 :         if (i != termfreqs.end())
     232                 :     310719 :             i->second.max_part += max_part;
     233                 :     310719 :     }
     234                 :            : 
     235                 :     487692 :     Xapian::doclength get_average_length() const {
     236                 :            : #ifdef XAPIAN_ASSERTIONS
     237                 :            :         finalised = true;
     238                 :            : #endif
     239         [ +  + ]:     487692 :         if (rare(collection_size == 0)) return 0;
     240                 :     487487 :         return Xapian::doclength(total_length) / collection_size;
     241                 :            :     }
     242                 :            : 
     243                 :            :     /** Set the "bounds" stats from Database @a db. */
     244                 :     170536 :     void set_bounds_from_db(const Xapian::Database &db_) {
     245                 :            :         Assert(!finalised);
     246                 :     170536 :         db = db_;
     247                 :     170536 :     }
     248                 :            : 
     249                 :            :     /// Return a std::string describing this object.
     250                 :            :     std::string get_description() const;
     251                 :            : 
     252                 :          0 :     static bool double_param(const char ** p, double * ptr_val) {
     253                 :            :         char *end;
     254                 :          0 :         errno = 0;
     255                 :          0 :         double v = strtod(*p, &end);
     256 [ #  # ][ #  # ]:          0 :         if (*p == end || errno) return false;
     257                 :          0 :         *p = end;
     258                 :          0 :         *ptr_val = v;
     259                 :          0 :         return true;
     260                 :            :     }
     261                 :            : 
     262                 :          0 :     static void parameter_error(const char * msg,
     263                 :            :                                 const std::string & scheme) {
     264         [ #  # ]:          0 :         std::string m(msg);
     265         [ #  # ]:          0 :         m += ": '";
     266         [ #  # ]:          0 :         m += scheme;
     267         [ #  # ]:          0 :         m += "'";
     268 [ #  # ][ #  # ]:          0 :         throw InvalidArgumentError(m);
     269                 :            :     }
     270                 :            : };
     271                 :            : 
     272                 :            : }
     273                 :            : 
     274                 :            : #endif // XAPIAN_INCLUDED_WEIGHTINTERNAL_H

Generated by: LCOV version 1.11