xapian-core  2.0.0
andnotpostlist.cc
Go to the documentation of this file.
1 
4 /* Copyright 2017,2022 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 "andnotpostlist.h"
24 
25 #include <algorithm>
26 
27 using namespace std;
28 
29 PostList*
30 AndNotPostList::next(double w_min)
31 {
32  while (true) {
33  PostList* result = pl->next(w_min);
34  if (result) {
35  delete pl;
36  pl = result;
37  }
38  if (pl->at_end()) {
39  result = pl;
40  pl = NULL;
41  return result;
42  }
43  Xapian::docid l_did = pl->get_docid();
44  if (l_did > r_did) {
45  bool r_valid;
46  result = r->check(l_did, 0, r_valid);
47  if (result) {
48  delete r;
49  r = result;
50  }
51  if (!r_valid)
52  return NULL;
53  if (r->at_end()) {
54  result = pl;
55  pl = NULL;
56  return result;
57  }
58  r_did = r->get_docid();
59  }
60  if (l_did < r_did)
61  break;
62  }
63  return NULL;
64 }
65 
66 PostList*
68 {
69  if (did > pl->get_docid()) {
70  PostList* result = pl->skip_to(did, w_min);
71  if (result) {
72  delete pl;
73  pl = result;
74  }
75  if (pl->at_end()) {
76  result = pl;
77  pl = NULL;
78  return result;
79  }
80  Xapian::docid l_did = pl->get_docid();
81  if (l_did > r_did) {
82  bool r_valid;
83  result = r->check(l_did, 0, r_valid);
84  if (result) {
85  delete r;
86  r = result;
87  }
88  if (!r_valid)
89  return NULL;
90  if (r->at_end()) {
91  result = pl;
92  pl = NULL;
93  return result;
94  }
95  r_did = r->get_docid();
96  }
97  if (l_did == r_did) {
98  // Advance to the next match.
99  return AndNotPostList::next(w_min);
100  }
101  }
102  return NULL;
103 }
104 
105 PostList*
106 AndNotPostList::check(Xapian::docid did, double w_min, bool& valid)
107 {
108  PostList* result = pl->check(did, w_min, valid);
109  if (result) {
110  delete pl;
111  pl = result;
112  }
113  if (valid) {
114  if (pl->at_end()) {
115  result = pl;
116  pl = NULL;
117  return result;
118  }
119  Xapian::docid l_did = pl->get_docid();
120  if (l_did > r_did) {
121  bool r_valid;
122  result = r->check(l_did, 0, r_valid);
123  if (result) {
124  delete r;
125  r = result;
126  }
127  if (!r_valid)
128  return NULL;
129  if (r->at_end()) {
130  result = pl;
131  pl = NULL;
132  return result;
133  }
134  r_did = r->get_docid();
135  }
136  if (l_did == r_did) {
137  // For check() we can simply indicate !valid.
138  valid = false;
139  }
140  }
141  return NULL;
142 }
143 
144 string
146 {
147  string desc = "AndNotPostList(";
148  desc += pl->get_description();
149  desc += ", ";
150  desc += r->get_description();
151  desc += ')';
152  return desc;
153 }
PostList class implementing Query::OP_AND_NOT.
PostList * skip_to(Xapian::docid did, double w_min)
Skip forward to the specified docid.
std::string get_description() const
Return a string description of this object.
PostList * check(Xapian::docid did, double w_min, bool &valid)
Check if the specified docid occurs in this postlist.
Abstract base class for postlists.
Definition: postlist.h:40
virtual PostList * skip_to(Xapian::docid did, double w_min)=0
Skip forward to the specified docid.
virtual PostList * next(double w_min)=0
Advance the current position to the next document in the postlist.
virtual Xapian::docid get_docid() const =0
Return the current docid.
PostList * next()
Advance the current position to the next document in the postlist.
Definition: postlist.h:168
virtual PostList * check(Xapian::docid did, double w_min, bool &valid)
Check if the specified docid occurs in this postlist.
Definition: postlist.cc:52
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
Definition: types.h:51