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