Branch data Line data Source code
1 : : /** @file chert_valuelist.cc
2 : : * @brief Chert class for value streams.
3 : : */
4 : : /* Copyright (C) 2007,2008 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, write to the Free Software
18 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : : */
20 : :
21 : : #include <config.h>
22 : :
23 : : #include "chert_valuelist.h"
24 : :
25 : : #include "chert_cursor.h"
26 : : #include "chert_database.h"
27 : : #include "omassert.h"
28 : : #include "str.h"
29 : :
30 : : using namespace std;
31 : :
32 : : bool
33 : 16702 : ChertValueList::update_reader()
34 : : {
35 : 16702 : Xapian::docid first_did = docid_from_key(slot, cursor->current_key);
36 [ + + ]: 16702 : if (!first_did) return false;
37 : :
38 : 15074 : cursor->read_tag();
39 : 15074 : const string & tag = cursor->current_tag;
40 : 15074 : reader.assign(tag.data(), tag.size(), first_did);
41 : 16702 : return true;
42 : : }
43 : :
44 : 2688 : ChertValueList::~ChertValueList()
45 : : {
46 [ + + ][ # # ]: 2688 : delete cursor;
[ # # ]
47 [ + - ][ # # ]: 2688 : }
[ # # ]
48 : :
49 : : Xapian::docid
50 : 52777 : ChertValueList::get_docid() const
51 : : {
52 : : Assert(!at_end());
53 : 52777 : return reader.get_docid();
54 : : }
55 : :
56 : : Xapian::valueno
57 : 26689 : ChertValueList::get_valueno() const
58 : : {
59 : 26689 : return slot;
60 : : }
61 : :
62 : : std::string
63 : 60295 : ChertValueList::get_value() const
64 : : {
65 : : Assert(!at_end());
66 : 60295 : return reader.get_value();
67 : : }
68 : :
69 : : bool
70 : 61136 : ChertValueList::at_end() const
71 : : {
72 : 61136 : return cursor == NULL;
73 : : }
74 : :
75 : : void
76 : 12299 : ChertValueList::next()
77 : : {
78 [ + + ]: 12299 : if (!cursor) {
79 : 1551 : cursor = db->get_postlist_cursor();
80 [ - + ]: 1551 : if (!cursor) return;
81 : 1551 : cursor->find_entry_ge(make_valuechunk_key(slot, 1));
82 [ + + ]: 10748 : } else if (!reader.at_end()) {
83 : 10691 : reader.next();
84 [ + + ]: 10691 : if (!reader.at_end()) return;
85 : 898 : cursor->next();
86 : : }
87 : :
88 [ + - ]: 2506 : if (!cursor->after_end()) {
89 [ + + ]: 2506 : if (update_reader()) {
90 [ + - ]: 1670 : if (!reader.at_end()) return;
91 : : }
92 : : }
93 : :
94 : : // We've reached the end.
95 [ + - ]: 836 : delete cursor;
96 : 12299 : cursor = NULL;
97 : : }
98 : :
99 : : void
100 : 17253 : ChertValueList::skip_to(Xapian::docid did)
101 : : {
102 [ - + ]: 17253 : if (!cursor) {
103 : 0 : cursor = db->get_postlist_cursor();
104 [ # # ]: 0 : if (!cursor) return;
105 [ + + ]: 17253 : } else if (!reader.at_end()) {
106 : 17159 : reader.skip_to(did);
107 [ + + ]: 17159 : if (!reader.at_end()) return;
108 : : }
109 : :
110 [ + + ]: 1391 : if (!cursor->find_entry(make_valuechunk_key(slot, did))) {
111 [ + - ]: 934 : if (update_reader()) {
112 : 934 : reader.skip_to(did);
113 [ + + ]: 934 : if (!reader.at_end()) return;
114 : : }
115 : : // The requested docid is between two chunks.
116 : 672 : cursor->next();
117 : : }
118 : :
119 : : // Either an exact match, or in a gap before the start of a chunk.
120 [ + - ]: 1129 : if (!cursor->after_end()) {
121 [ + + ]: 1129 : if (update_reader()) {
122 [ + - ]: 457 : if (!reader.at_end()) return;
123 : : }
124 : : }
125 : :
126 : : // We've reached the end.
127 [ + - ]: 672 : delete cursor;
128 : 17253 : cursor = NULL;
129 : : }
130 : :
131 : : bool
132 : 31892 : ChertValueList::check(Xapian::docid did)
133 : : {
134 [ + + ]: 31892 : if (!cursor) {
135 : 1137 : cursor = db->get_postlist_cursor();
136 [ - + ]: 1137 : if (!cursor) return true;
137 [ + + ]: 30755 : } else if (!reader.at_end()) {
138 : : // Check for the requested docid in the current block.
139 : 30640 : reader.skip_to(did);
140 [ + + ]: 30640 : if (!reader.at_end()) return true;
141 : : }
142 : :
143 : : // Try moving to the appropriate chunk.
144 [ + + ]: 12133 : if (!cursor->find_entry(make_valuechunk_key(slot, did))) {
145 : : // We're in a chunk which might contain the docid.
146 [ + + ]: 5584 : if (update_reader()) {
147 : 5464 : reader.skip_to(did);
148 [ + + ]: 5464 : if (!reader.at_end()) return true;
149 : : }
150 : 294 : return false;
151 : : }
152 : :
153 : : // We had an exact match for a chunk starting with specified docid.
154 : : Assert(!cursor->after_end());
155 : 6549 : if (!update_reader()) {
156 : : // We found the exact key we built, so it must match the slot.
157 : : // Therefore update_reader() "can't possibly fail".
158 : : Assert(false);
159 : : }
160 : :
161 : 31892 : return true;
162 : : }
163 : :
164 : : string
165 : 0 : ChertValueList::get_description() const
166 : : {
167 : 0 : string desc("ChertValueList(slot=");
168 : 0 : desc += str(slot);
169 : 0 : desc += ')';
170 : 0 : return desc;
171 : : }
|