xapian-core  2.0.0
ortermlist.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2007-2024 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, see
18  * <https://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "ortermlist.h"
24 
25 #include "debuglog.h"
26 #include "omassert.h"
27 
29 
30 using namespace std;
31 
32 void
34 {
35  Assert(!left->get_termname().empty());
36  Assert(!right->get_termname().empty());
37 }
38 
40 {
41  delete left;
42  delete right;
43 }
44 
47 {
48  LOGCALL(EXPAND, Xapian::termcount, "OrTermList::get_approx_size", NO_ARGS);
49  // This is actually the upper bound, but we only use this to order the
50  // binary tree of OrTermList objects so it's probably not worth trying
51  // to be more sophisticated.
52  RETURN(left->get_approx_size() + right->get_approx_size());
53 }
54 
55 void
57 {
58  LOGCALL_VOID(EXPAND, "OrTermList::accumulate_stats", stats);
59  check_started();
60  if (cmp <= 0)
61  left->accumulate_stats(stats);
62  if (cmp >= 0)
63  right->accumulate_stats(stats);
64 }
65 
68 {
69  LOGCALL(EXPAND, Xapian::termcount, "OrTermList::get_wdf", NO_ARGS);
70  check_started();
71  if (cmp < 0) RETURN(left->get_wdf());
72  if (cmp > 0) RETURN(right->get_wdf());
73  RETURN(left->get_wdf() + right->get_wdf());
74 }
75 
78 {
79  LOGCALL(EXPAND, Xapian::doccount, "OrTermList::get_termfreq", NO_ARGS);
80  check_started();
81  if (cmp < 0)
82  RETURN(left->get_termfreq());
83  Assert(cmp > 0 || left->get_termfreq() == right->get_termfreq());
84  RETURN(right->get_termfreq());
85 }
86 
87 TermList *
89 {
90  LOGCALL(EXPAND, TermList *, "OrTermList::next", NO_ARGS);
91  // If we've not started yet, cmp will be zero so we'll take the third case
92  // below which is what we want to do to get started.
93  if (cmp < 0) {
94  TermList* lret = left->next();
95  if (lret == left) {
96  TermList *ret = right;
97  right = NULL;
98  // Prune.
99  RETURN(ret);
100  }
101  if (lret) {
102  delete left;
103  left = lret;
104  }
105  } else if (cmp > 0) {
106  TermList* rret = right->next();
107  if (rret == right) {
108  TermList *ret = left;
109  left = NULL;
110  // Prune.
111  RETURN(ret);
112  }
113  if (rret) {
114  delete right;
115  right = rret;
116  }
117  } else {
118  TermList* lret = left->next();
119  if (lret && lret != left) {
120  delete left;
121  left = lret;
122  lret = NULL;
123  }
124  TermList* rret = right->next();
125  if (rret && rret != right) {
126  delete right;
127  right = rret;
128  rret = NULL;
129  }
130  if (lret) {
131  if (rret)
132  return this;
133  TermList *ret = right;
134  right = NULL;
135  // Prune.
136  RETURN(ret);
137  }
138  if (rret) {
139  TermList *ret = left;
140  left = NULL;
141  // Prune.
142  RETURN(ret);
143  }
144  }
145  cmp = left->get_termname().compare(right->get_termname());
146  current_term = cmp < 0 ? left->get_termname() : right->get_termname();
147  RETURN(NULL);
148 }
149 
150 TermList*
152 {
153  LOGCALL(EXPAND, TermList *, "OrTermList::skip_to", term);
154  TermList* lret = left->skip_to(term);
155  if (lret && lret != left) {
156  delete left;
157  left = lret;
158  lret = NULL;
159  }
160  TermList* rret = right->skip_to(term);
161  if (rret && rret != right) {
162  delete right;
163  right = rret;
164  rret = NULL;
165  }
166  if (lret) {
167  // Left at end.
168  if (rret) {
169  // Both at end.
170  RETURN(this);
171  }
172  TermList *ret = right;
173  right = NULL;
174  // Prune.
175  RETURN(ret);
176  }
177  if (rret) {
178  // Right at end.
179  TermList *ret = left;
180  left = NULL;
181  // Prune.
182  RETURN(ret);
183  }
184  cmp = left->get_termname().compare(right->get_termname());
185  current_term = cmp < 0 ? left->get_termname() : right->get_termname();
186  RETURN(NULL);
187 }
188 
191 {
192  Assert(false);
193  return 0;
194 }
195 
198 {
199  Assert(false);
200  return NULL;
201 }
202 
203 
206 {
207  LOGCALL(EXPAND, Xapian::doccount, "FreqAdderOrTermList::get_termfreq", NO_ARGS);
208  check_started();
209  if (cmp < 0) RETURN(left->get_termfreq());
210  if (cmp > 0) RETURN(right->get_termfreq());
211  RETURN(left->get_termfreq() + right->get_termfreq());
212 }
Xapian::doccount get_termfreq() const
Return the term frequency for the term at the current position.
Definition: ortermlist.cc:205
Xapian::termcount get_approx_size() const
Return approximate size of this termlist.
Definition: ortermlist.cc:46
TermList * next()
Advance the current position to the next term in the termlist.
Definition: ortermlist.cc:88
TermList * skip_to(std::string_view term)
Skip forward to the specified term.
Definition: ortermlist.cc:151
void check_started() const
Check that next() has already been called.
Definition: ortermlist.cc:33
PositionList * positionlist_begin() const
Return PositionList for the current position.
Definition: ortermlist.cc:197
Xapian::doccount get_termfreq() const
Return the term frequency for the term at the current position.
Definition: ortermlist.cc:77
void accumulate_stats(Xapian::Internal::ExpandStats &stats) const
Collate weighting information for the current term.
Definition: ortermlist.cc:56
Xapian::termcount get_wdf() const
Return the wdf for the term at the current position.
Definition: ortermlist.cc:67
Xapian::termcount positionlist_count() const
Return the length of the position list for the current position.
Definition: ortermlist.cc:190
Collates statistics while calculating term weight in an ESet.
Definition: expandweight.h:37
Abstract base class for iterating term positions in a document.
Definition: positionlist.h:32
Abstract base class for termlists.
Definition: termlist.h:42
virtual Internal * skip_to(std::string_view term)=0
Skip forward to the specified term.
virtual Internal * next()=0
Advance the current position to the next term in the termlist.
string term
Debug logging macros.
#define RETURN(...)
Definition: debuglog.h:484
#define LOGCALL(CATEGORY, TYPE, FUNC, PARAMS)
Definition: debuglog.h:478
#define LOGCALL_VOID(CATEGORY, FUNC, PARAMS)
Definition: debuglog.h:479
unsigned XAPIAN_TERMCOUNT_BASE_TYPE termcount
A counts of terms.
Definition: types.h:64
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
Definition: types.h:37
Various assertion macros.
#define Assert(COND)
Definition: omassert.h:122
Merge two TermList objects using an OR operation.
Class for iterating over term positions.