1 /** @file glass_valuelist.cc
2 * @brief Glass class for value streams.
4 /* Copyright (C) 2007,2008,2009 Olly Betts
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.
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.
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
23 #include "glass_valuelist.h"
25 #include "glass_cursor.h"
26 #include "glass_database.h"
30 using namespace Glass
;
34 GlassValueList::update_reader()
36 Xapian::docid first_did
= docid_from_key(slot
, cursor
->current_key
);
37 if (!first_did
) return false;
40 const string
& tag
= cursor
->current_tag
;
41 reader
.assign(tag
.data(), tag
.size(), first_did
);
45 GlassValueList::~GlassValueList()
51 GlassValueList::get_docid() const
54 return reader
.get_docid();
58 GlassValueList::get_valueno() const
64 GlassValueList::get_value() const
67 return reader
.get_value();
71 GlassValueList::at_end() const
73 return cursor
== NULL
;
77 GlassValueList::next()
80 cursor
= db
->get_postlist_cursor();
82 cursor
->find_entry_ge(make_valuechunk_key(slot
, 1));
83 } else if (!reader
.at_end()) {
85 if (!reader
.at_end()) return;
89 if (!cursor
->after_end()) {
90 if (update_reader()) {
91 if (!reader
.at_end()) return;
95 // We've reached the end.
101 GlassValueList::skip_to(Xapian::docid did
)
104 cursor
= db
->get_postlist_cursor();
106 } else if (!reader
.at_end()) {
108 if (!reader
.at_end()) return;
111 if (!cursor
->find_entry(make_valuechunk_key(slot
, did
))) {
112 if (update_reader()) {
114 if (!reader
.at_end()) return;
116 // The requested docid is between two chunks.
120 // Either an exact match, or in a gap before the start of a chunk.
121 if (!cursor
->after_end()) {
122 if (update_reader()) {
123 if (!reader
.at_end()) return;
127 // We've reached the end.
133 GlassValueList::check(Xapian::docid did
)
136 cursor
= db
->get_postlist_cursor();
137 if (!cursor
) return true;
138 } else if (!reader
.at_end()) {
139 // Check for the requested docid in the current block.
141 if (!reader
.at_end()) return true;
144 // Try moving to the appropriate chunk.
145 if (!cursor
->find_entry(make_valuechunk_key(slot
, did
))) {
146 // We're in a chunk which might contain the docid.
147 if (update_reader()) {
149 if (!reader
.at_end()) return true;
154 // We had an exact match for a chunk starting with specified docid.
155 Assert(!cursor
->after_end());
156 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".
166 GlassValueList::get_description() const
168 string
desc("GlassValueList(slot=");