LCOV - code coverage report
Current view: top level - include/xapian - matchspy.h (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 16 16 100.0 %
Date: 2019-06-30 05:20:33 Functions: 10 10 100.0 %
Branches: 4 8 50.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file matchspy.h
       2                 :            :  * @brief MatchSpy implementation.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007,2008,2009,2010,2011,2012,2013,2014,2015 Olly Betts
       5                 :            :  * Copyright (C) 2007,2009 Lemur Consulting Ltd
       6                 :            :  * Copyright (C) 2010 Richard Boulton
       7                 :            :  *
       8                 :            :  * This program is free software; you can redistribute it and/or modify
       9                 :            :  * it under the terms of the GNU General Public License as published by
      10                 :            :  * the Free Software Foundation; either version 2 of the License, or
      11                 :            :  * (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This program is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16                 :            :  * GNU General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU General Public License
      19                 :            :  * along with this program; if not, write to the Free Software
      20                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      21                 :            :  */
      22                 :            : 
      23                 :            : #ifndef XAPIAN_INCLUDED_MATCHSPY_H
      24                 :            : #define XAPIAN_INCLUDED_MATCHSPY_H
      25                 :            : 
      26                 :            : #if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
      27                 :            : # error "Never use <xapian/matchspy.h> directly; include <xapian.h> instead."
      28                 :            : #endif
      29                 :            : 
      30                 :            : #include <xapian/attributes.h>
      31                 :            : #include <xapian/intrusive_ptr.h>
      32                 :            : #include <xapian/termiterator.h>
      33                 :            : #include <xapian/visibility.h>
      34                 :            : 
      35                 :            : #include <string>
      36                 :            : #include <map>
      37                 :            : 
      38                 :            : namespace Xapian {
      39                 :            : 
      40                 :            : class Document;
      41                 :            : class Registry;
      42                 :            : 
      43                 :            : /** Abstract base class for match spies.
      44                 :            :  *
      45                 :            :  *  The subclasses will generally accumulate information seen during the match,
      46                 :            :  *  to calculate aggregate functions, or other profiles of the matching
      47                 :            :  *  documents.
      48                 :            :  */
      49                 :            : class XAPIAN_VISIBILITY_DEFAULT MatchSpy
      50                 :            :     : public Xapian::Internal::opt_intrusive_base {
      51                 :            :   private:
      52                 :            :     /// Don't allow assignment.
      53                 :            :     void operator=(const MatchSpy &) = delete;
      54                 :            : 
      55                 :            :     /// Don't allow copying.
      56                 :            :     MatchSpy(const MatchSpy &) = delete;
      57                 :            : 
      58                 :            :   public:
      59                 :            :     /// Default constructor, needed by subclass constructors.
      60                 :       3376 :     XAPIAN_NOTHROW(MatchSpy()) {}
      61                 :            : 
      62                 :            :     /** Virtual destructor, because we have virtual methods. */
      63                 :            :     virtual ~MatchSpy();
      64                 :            : 
      65                 :            :     /** Register a document with the match spy.
      66                 :            :      *
      67                 :            :      *  This is called by the matcher once with each document seen by the
      68                 :            :      *  matcher during the match process.  Note that the matcher will often not
      69                 :            :      *  see all the documents which match the query, due to optimisations which
      70                 :            :      *  allow low-weighted documents to be skipped, and allow the match process
      71                 :            :      *  to be terminated early.
      72                 :            :      *
      73                 :            :      *  @param doc The document seen by the match spy.
      74                 :            :      *  @param wt The weight of the document.
      75                 :            :      */
      76                 :            :     virtual void operator()(const Xapian::Document &doc,
      77                 :            :                             double wt) = 0;
      78                 :            : 
      79                 :            :     /** Clone the match spy.
      80                 :            :      *
      81                 :            :      *  The clone should inherit the configuration of the parent, but need not
      82                 :            :      *  inherit the state.  ie, the clone does not need to be passed
      83                 :            :      *  information about the results seen by the parent.
      84                 :            :      *
      85                 :            :      *  If you don't want to support the remote backend in your match spy, you
      86                 :            :      *  can use the default implementation which simply throws
      87                 :            :      *  Xapian::UnimplementedError.
      88                 :            :      *
      89                 :            :      *  Note that the returned object will be deallocated by Xapian after use
      90                 :            :      *  with "delete".  If you want to handle the deletion in a special way
      91                 :            :      *  (for example when wrapping the Xapian API for use from another
      92                 :            :      *  language) then you can define a static <code>operator delete</code>
      93                 :            :      *  method in your subclass as shown here:
      94                 :            :      *  https://trac.xapian.org/ticket/554#comment:1
      95                 :            :      */
      96                 :            :     virtual MatchSpy * clone() const;
      97                 :            : 
      98                 :            :     /** Return the name of this match spy.
      99                 :            :      *
     100                 :            :      *  This name is used by the remote backend.  It is passed with the
     101                 :            :      *  serialised parameters to the remote server so that it knows which class
     102                 :            :      *  to create.
     103                 :            :      *
     104                 :            :      *  Return the full namespace-qualified name of your class here - if your
     105                 :            :      *  class is called MyApp::FooMatchSpy, return "MyApp::FooMatchSpy" from
     106                 :            :      *  this method.
     107                 :            :      *
     108                 :            :      *  If you don't want to support the remote backend in your match spy, you
     109                 :            :      *  can use the default implementation which simply throws
     110                 :            :      *  Xapian::UnimplementedError.
     111                 :            :      */
     112                 :            :     virtual std::string name() const;
     113                 :            : 
     114                 :            :     /** Return this object's parameters serialised as a single string.
     115                 :            :      *
     116                 :            :      *  If you don't want to support the remote backend in your match spy, you
     117                 :            :      *  can use the default implementation which simply throws
     118                 :            :      *  Xapian::UnimplementedError.
     119                 :            :      */
     120                 :            :     virtual std::string serialise() const;
     121                 :            : 
     122                 :            :     /** Unserialise parameters.
     123                 :            :      *
     124                 :            :      *  This method unserialises parameters serialised by the @a serialise()
     125                 :            :      *  method and allocates and returns a new object initialised with them.
     126                 :            :      *
     127                 :            :      *  If you don't want to support the remote backend in your match spy, you
     128                 :            :      *  can use the default implementation which simply throws
     129                 :            :      *  Xapian::UnimplementedError.
     130                 :            :      *
     131                 :            :      *  Note that the returned object will be deallocated by Xapian after use
     132                 :            :      *  with "delete".  If you want to handle the deletion in a special way
     133                 :            :      *  (for example when wrapping the Xapian API for use from another
     134                 :            :      *  language) then you can define a static <code>operator delete</code>
     135                 :            :      *  method in your subclass as shown here:
     136                 :            :      *  https://trac.xapian.org/ticket/554#comment:1
     137                 :            :      *
     138                 :            :      *  @param serialised       A string containing the serialised results.
     139                 :            :      *  @param context  Registry object to use for unserialisation to permit
     140                 :            :      *                  MatchSpy subclasses with sub-MatchSpy objects to be
     141                 :            :      *                  implemented.
     142                 :            :      */
     143                 :            :     virtual MatchSpy * unserialise(const std::string & serialised,
     144                 :            :                                    const Registry & context) const;
     145                 :            : 
     146                 :            :     /** Serialise the results of this match spy.
     147                 :            :      *
     148                 :            :      *  If you don't want to support the remote backend in your match spy, you
     149                 :            :      *  can use the default implementation which simply throws
     150                 :            :      *  Xapian::UnimplementedError.
     151                 :            :      */
     152                 :            :     virtual std::string serialise_results() const;
     153                 :            : 
     154                 :            :     /** Unserialise some results, and merge them into this matchspy.
     155                 :            :      *
     156                 :            :      *  The order in which results are merged should not be significant, since
     157                 :            :      *  this order is not specified (and will vary depending on the speed of
     158                 :            :      *  the search in each sub-database).
     159                 :            :      *
     160                 :            :      *  If you don't want to support the remote backend in your match spy, you
     161                 :            :      *  can use the default implementation which simply throws
     162                 :            :      *  Xapian::UnimplementedError.
     163                 :            :      *
     164                 :            :      *  @param serialised       A string containing the serialised results.
     165                 :            :      */
     166                 :            :     virtual void merge_results(const std::string & serialised);
     167                 :            : 
     168                 :            :     /** Return a string describing this object.
     169                 :            :      *
     170                 :            :      *  This default implementation returns a generic answer, to avoid forcing
     171                 :            :      *  those deriving their own MatchSpy subclasses from having to implement
     172                 :            :      *  this (they may not care what get_description() gives for their
     173                 :            :      *  subclass).
     174                 :            :      */
     175                 :            :     virtual std::string get_description() const;
     176                 :            : 
     177                 :            :     /** Start reference counting this object.
     178                 :            :      *
     179                 :            :      *  You can hand ownership of a dynamically allocated MatchSpy
     180                 :            :      *  object to Xapian by calling release() and then passing the object to a
     181                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
     182                 :            :      *  longer required.
     183                 :            :      */
     184                 :         50 :     MatchSpy * release() {
     185                 :         50 :         opt_intrusive_base::release();
     186                 :         50 :         return this;
     187                 :            :     }
     188                 :            : 
     189                 :            :     /** Start reference counting this object.
     190                 :            :      *
     191                 :            :      *  You can hand ownership of a dynamically allocated MatchSpy
     192                 :            :      *  object to Xapian by calling release() and then passing the object to a
     193                 :            :      *  Xapian method.  Xapian will arrange to delete the object once it is no
     194                 :            :      *  longer required.
     195                 :            :      */
     196                 :            :     const MatchSpy * release() const {
     197                 :            :         opt_intrusive_base::release();
     198                 :            :         return this;
     199                 :            :     }
     200                 :            : };
     201                 :            : 
     202                 :            : 
     203                 :            : /** Class for counting the frequencies of values in the matching documents.
     204                 :            :  */
     205         [ -  + ]:       6464 : class XAPIAN_VISIBILITY_DEFAULT ValueCountMatchSpy : public MatchSpy {
     206                 :            :   public:
     207                 :            :     struct Internal;
     208                 :            : 
     209                 :            : #ifndef SWIG // SWIG doesn't need to know about the internal class
     210                 :            :     /// @private @internal
     211                 :        184 :     struct XAPIAN_VISIBILITY_DEFAULT Internal
     212                 :            :             : public Xapian::Internal::intrusive_base
     213                 :            :     {
     214                 :            :         /// The slot to count.
     215                 :            :         Xapian::valueno slot;
     216                 :            : 
     217                 :            :         /// Total number of documents seen by the match spy.
     218                 :            :         Xapian::doccount total;
     219                 :            : 
     220                 :            :         /// The values seen so far, together with their frequency.
     221                 :            :         std::map<std::string, Xapian::doccount> values;
     222                 :            : 
     223                 :            :         Internal() : slot(Xapian::BAD_VALUENO), total(0) {}
     224                 :        184 :         explicit Internal(Xapian::valueno slot_) : slot(slot_), total(0) {}
     225                 :            :     };
     226                 :            : #endif
     227                 :            : 
     228                 :            :   protected:
     229                 :            :     /** @private @internal Reference counted internals. */
     230                 :            :     Xapian::Internal::intrusive_ptr<Internal> internal;
     231                 :            : 
     232                 :            :   public:
     233                 :            :     /// Construct an empty ValueCountMatchSpy.
     234                 :       3118 :     ValueCountMatchSpy() {}
     235                 :            : 
     236                 :            :     /// Construct a MatchSpy which counts the values in a particular slot.
     237                 :         92 :     explicit ValueCountMatchSpy(Xapian::valueno slot_)
     238 [ +  - ][ +  - ]:         92 :             : internal(new Internal(slot_)) {}
     239                 :            : 
     240                 :            :     /** Return the total number of documents tallied. */
     241                 :         54 :     size_t XAPIAN_NOTHROW(get_total() const) {
     242         [ +  - ]:         54 :         return internal.get() ? internal->total : 0;
     243                 :            :     }
     244                 :            : 
     245                 :            :     /** Get an iterator over the values seen in the slot.
     246                 :            :      *
     247                 :            :      *  Items will be returned in ascending alphabetical order.
     248                 :            :      *
     249                 :            :      *  During the iteration, the frequency of the current value can be
     250                 :            :      *  obtained with the get_termfreq() method on the iterator.
     251                 :            :      */
     252                 :            :     TermIterator values_begin() const;
     253                 :            : 
     254                 :            :     /** End iterator corresponding to values_begin() */
     255                 :        174 :     TermIterator XAPIAN_NOTHROW(values_end() const) {
     256                 :        174 :         return TermIterator();
     257                 :            :     }
     258                 :            : 
     259                 :            :     /** Get an iterator over the most frequent values seen in the slot.
     260                 :            :      *
     261                 :            :      *  Items will be returned in descending order of frequency.  Values with
     262                 :            :      *  the same frequency will be returned in ascending alphabetical order.
     263                 :            :      *
     264                 :            :      *  During the iteration, the frequency of the current value can be
     265                 :            :      *  obtained with the get_termfreq() method on the iterator.
     266                 :            :      *
     267                 :            :      *  @param maxvalues The maximum number of values to return.
     268                 :            :      */
     269                 :            :     TermIterator top_values_begin(size_t maxvalues) const;
     270                 :            : 
     271                 :            :     /** End iterator corresponding to top_values_begin() */
     272                 :       2328 :     TermIterator XAPIAN_NOTHROW(top_values_end(size_t) const) {
     273                 :       2328 :         return TermIterator();
     274                 :            :     }
     275                 :            : 
     276                 :            :     /** Implementation of virtual operator().
     277                 :            :      *
     278                 :            :      *  This implementation tallies values for a matching document.
     279                 :            :      *
     280                 :            :      *  @param doc      The document to tally values for.
     281                 :            :      *  @param wt       The weight of the document (ignored by this class).
     282                 :            :      */
     283                 :            :     void operator()(const Xapian::Document &doc, double wt);
     284                 :            : 
     285                 :            :     virtual MatchSpy * clone() const;
     286                 :            :     virtual std::string name() const;
     287                 :            :     virtual std::string serialise() const;
     288                 :            :     virtual MatchSpy * unserialise(const std::string & serialised,
     289                 :            :                                    const Registry & context) const;
     290                 :            :     virtual std::string serialise_results() const;
     291                 :            :     virtual void merge_results(const std::string & serialised);
     292                 :            :     virtual std::string get_description() const;
     293                 :            : };
     294                 :            : 
     295                 :            : }
     296                 :            : 
     297                 :            : #endif // XAPIAN_INCLUDED_MATCHSPY_H

Generated by: LCOV version 1.11