xapian-core  2.0.0
multi_valuelist.cc
Go to the documentation of this file.
1 
4 /* Copyright (C) 2007,2008,2009,2011,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, see
18  * <https://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "multi_valuelist.h"
24 
25 #include <xapian/error.h>
26 
27 #include "heap.h"
28 #include "omassert.h"
29 
30 #include <algorithm>
31 
32 using namespace std;
34 
38  bool operator()(const SubValueList *a, const SubValueList *b) const {
39  Xapian::docid did_a = a->get_docid();
40  Xapian::docid did_b = b->get_docid();
41  if (did_a > did_b) return true;
42  if (did_a < did_b) return false;
43  return a->shard > b->shard;
44  }
45 };
46 
48 {
49  while (count)
50  delete valuelists[--count];
51  delete [] valuelists;
52 }
53 
56 {
57  Assert(!at_end());
58  return current_docid;
59 }
60 
61 std::string
63 {
64  Assert(!at_end());
65  return valuelists[0]->get_value();
66 }
67 
70 {
71  return slot;
72 }
73 
74 bool
76 {
77  return count == 0;
78 }
79 
80 void
82 {
83  if (current_docid == 0) {
84  // Make valuelists into a heap so that the one with the earliest
85  // sorting docid is at the top of the heap.
86  Xapian::doccount j = 0;
87  for (Xapian::doccount i = 0; i != count; ++i) {
88  valuelists[i]->next();
89  if (valuelists[i]->at_end()) {
90  delete valuelists[i];
91  valuelists[i] = 0;
92  } else {
93  if (i != j)
94  swap(valuelists[i], valuelists[j]);
95  ++j;
96  }
97  }
98  count = j;
99  if (rare(count == 0))
100  return;
101 
102  Heap::make(valuelists, valuelists + count,
104  } else {
105  // Advance to the next docid.
106  SubValueList * vl = valuelists[0];
107  vl->next();
108  if (vl->at_end()) {
109  Heap::pop(valuelists, valuelists + count,
111  delete vl;
112  if (--count == 0)
113  return;
114  } else {
115  Heap::replace(valuelists, valuelists + count,
117  }
118  }
119 
120  current_docid = valuelists[0]->get_merged_docid(n_shards);
121 }
122 
123 void
125 {
126  // Assume the skip is likely to be a long distance, and rebuild the heap
127  // from scratch. FIXME: It would be useful to profile this against an
128  // approach more like that next() uses if this ever gets heavy use.
129  Xapian::doccount j = 0;
130  for (Xapian::doccount i = 0; i != count; ++i) {
131  valuelists[i]->skip_to(did, n_shards);
132  if (valuelists[i]->at_end()) {
133  delete valuelists[i];
134  valuelists[i] = 0;
135  } else {
136  if (i != j)
137  swap(valuelists[i], valuelists[j]);
138  ++j;
139  }
140  }
141  count = j;
142  if (rare(count == 0))
143  return;
144 
145  Heap::make(valuelists, valuelists + count, CompareSubValueListsByDocId());
146 
147  current_docid = valuelists[0]->get_merged_docid(n_shards);
148 }
149 
150 bool
152 {
153  // FIXME: just run check on the subvaluelist which would hold that docid.
154  skip_to(did);
155  return true;
156 }
157 
158 string
160 {
161  return "MultiValueList()"; // FIXME: improve description...
162 }
bool check(Xapian::docid did)
Check if the specified docid occurs in this valuestream.
Xapian::valueno get_valueno() const
Return the value slot for the current position/this iterator.
std::string get_value() const
Return the value at the current position.
std::string get_description() const
Return a string description of this object.
void next()
Advance the current position to the next document in the value stream.
~MultiValueList()
Destructor.
bool at_end() const
Return true if the current position is past the last entry in this list.
Xapian::docid get_docid() const
Return the docid at the current position.
void skip_to(Xapian::docid)
Skip forward to the specified docid.
A smart pointer that uses intrusive reference counting.
Definition: intrusive_ptr.h:83
#define rare(COND)
Definition: config.h:607
Hierarchy of classes which Xapian can throw as exceptions.
C++ STL heap implementation with extensions.
Class for merging ValueList objects from subdatabases.
void pop(_RandomAccessIterator first, _RandomAccessIterator last, _Compare comp)
Definition: heap.h:213
void replace(_RandomAccessIterator first, _RandomAccessIterator last, _Compare comp)
Definition: heap.h:230
void make(_RandomAccessIterator first, _RandomAccessIterator last, _Compare comp)
Definition: heap.h:259
unsigned valueno
The number for a value slot in a document.
Definition: types.h:90
unsigned XAPIAN_DOCID_BASE_TYPE doccount
A count of documents.
Definition: types.h:37
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
Definition: types.h:51
Various assertion macros.
#define Assert(COND)
Definition: omassert.h:122
Comparison functor which orders SubValueList* by ascending docid.
bool operator()(const SubValueList *a, const SubValueList *b) const
Order by ascending docid.
Xapian::docid get_docid() const
bool at_end() const
unsigned shard