root / tags / 1.0.8 / xapian-core / backends / flint / flint_alltermslist.cc

Revision 9277, 4.5 kB (checked in by olly, 16 months ago)

backends/flint/flint_alltermslist.cc: Rework
FlintAllTermsList::skip_to() to use FlintCursor::find_entry_ge().

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* flint_alltermslist.cc: A termlist containing all terms in a flint database.
2 *
3 * Copyright (C) 2005,2007 Olly Betts
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
18 * USA
19 */
20
21#include <config.h>
22
23#include "flint_alltermslist.h"
24#include "flint_postlist.h"
25#include "flint_utils.h"
26
27#include "stringutils.h"
28
29void
30FlintAllTermsList::read_termfreq_and_collfreq() const
31{
32    DEBUGCALL(DB, void, "FlintAllTermsList::read_termfreq_and_collfreq", "");
33    Assert(!current_term.empty());
34    Assert(!at_end());
35
36    // Unpack the termfreq and collfreq from the tag.  Only do this if
37    // one or other is actually read.
38    cursor->read_tag();
39    const char *p = cursor->current_tag.data();
40    const char *pend = p + cursor->current_tag.size();
41    FlintPostList::read_number_of_entries(&p, pend, &termfreq, &collfreq);
42}
43
44FlintAllTermsList::~FlintAllTermsList()
45{
46    DEBUGCALL(DB, void, "~FlintAllTermsList", "");
47    delete cursor;
48}
49
50Xapian::termcount
51FlintAllTermsList::get_approx_size() const
52{
53    DEBUGCALL(DB, Xapian::termcount, "FlintAllTermsList::get_approx_size", "");
54    RETURN(approx_size);
55}
56
57string
58FlintAllTermsList::get_termname() const
59{
60    DEBUGCALL(DB, string, "FlintAllTermsList::get_termname", "");
61    Assert(!current_term.empty());
62    Assert(!at_end());
63    RETURN(current_term);
64}
65
66Xapian::doccount
67FlintAllTermsList::get_termfreq() const
68{
69    DEBUGCALL(DB, Xapian::doccount, "FlintAllTermsList::get_termfreq", "");
70    Assert(!current_term.empty());
71    Assert(!at_end());
72    if (termfreq == 0) read_termfreq_and_collfreq();
73    RETURN(termfreq);
74}
75
76Xapian::termcount
77FlintAllTermsList::get_collection_freq() const
78{
79    DEBUGCALL(DB, Xapian::termcount, "FlintAllTermsList::get_collection_freq", "");
80    Assert(!current_term.empty());
81    Assert(!at_end());
82    if (termfreq == 0) read_termfreq_and_collfreq();
83    RETURN(collfreq);
84}
85
86TermList *
87FlintAllTermsList::next()
88{
89    DEBUGCALL(DB, TermList *, "FlintAllTermsList::next", "");
90    Assert(!at_end());
91    // Set termfreq to 0 to indicate no termfreq/collfreq have been read for
92    // the current term.
93    termfreq = 0;
94
95    while (true) {
96        cursor->next();
97        if (cursor->after_end()) {
98            current_term = "";
99            break;
100        }
101
102        const char *p = cursor->current_key.data();
103        const char *pend = p + cursor->current_key.size();
104        if (!unpack_string_preserving_sort(&p, pend, current_term)) {
105            throw Xapian::DatabaseCorruptError("PostList table key has unexpected format");
106        }
107
108        if (!startswith(current_term, prefix)) {
109            // We've reached the end of the prefixed terms.
110            cursor->to_end();
111            current_term = "";
112            break;
113        }
114
115        // If this key is for the first chunk of a postlist, we're done.
116        // Otherwise we need to skip past continuation chunks until we find the
117        // first chunk of the next postlist.
118        if (p == pend) break;
119    }
120    RETURN(NULL);
121}
122
123TermList *
124FlintAllTermsList::skip_to(const string &term)
125{
126    DEBUGCALL(DB, TermList *, "FlintAllTermsList::skip_to", term);
127    Assert(!at_end());
128    // Set termfreq to 0 to indicate no termfreq/collfreq have been read for
129    // the current term.
130    termfreq = 0;
131
132    if (cursor->find_entry_ge(pack_string_preserving_sort(term))) {
133        // The exact term we asked for is there, so just copy it rather than
134        // wasting effort unpacking it from the key.
135        current_term = term;
136    } else {
137        if (cursor->after_end()) {
138            current_term = "";
139            RETURN(NULL);
140        }
141
142        const char *p = cursor->current_key.data();
143        const char *pend = p + cursor->current_key.size();
144        if (!unpack_string_preserving_sort(&p, pend, current_term)) {
145            throw Xapian::DatabaseCorruptError("PostList table key has unexpected format");
146        }
147    }
148
149    if (!startswith(current_term, prefix)) {
150        // We've reached the end of the prefixed terms.
151        cursor->to_end();
152        current_term = "";
153    }
154
155    RETURN(NULL);
156}
157
158bool
159FlintAllTermsList::at_end() const
160{
161    DEBUGCALL(DB, bool, "FlintAllTermsList::at_end", "");
162    RETURN(cursor->after_end());
163}
Note: See TracBrowser for help on using the browser.