00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include "brass_alltermslist.h"
00024 #include "brass_postlist.h"
00025
00026 #include "debuglog.h"
00027 #include "pack.h"
00028 #include "stringutils.h"
00029
00030 void
00031 BrassAllTermsList::read_termfreq_and_collfreq() const
00032 {
00033 LOGCALL_VOID(DB, "BrassAllTermsList::read_termfreq_and_collfreq", NO_ARGS);
00034 Assert(!current_term.empty());
00035 Assert(!at_end());
00036
00037
00038
00039 cursor->read_tag();
00040 const char *p = cursor->current_tag.data();
00041 const char *pend = p + cursor->current_tag.size();
00042 BrassPostList::read_number_of_entries(&p, pend, &termfreq, &collfreq);
00043 }
00044
00045 BrassAllTermsList::~BrassAllTermsList()
00046 {
00047 LOGCALL_DTOR(DB, "BrassAllTermsList");
00048 delete cursor;
00049 }
00050
00051 string
00052 BrassAllTermsList::get_termname() const
00053 {
00054 LOGCALL(DB, string, "BrassAllTermsList::get_termname", NO_ARGS);
00055 Assert(!current_term.empty());
00056 Assert(!at_end());
00057 RETURN(current_term);
00058 }
00059
00060 Xapian::doccount
00061 BrassAllTermsList::get_termfreq() const
00062 {
00063 LOGCALL(DB, Xapian::doccount, "BrassAllTermsList::get_termfreq", NO_ARGS);
00064 Assert(!current_term.empty());
00065 Assert(!at_end());
00066 if (termfreq == 0) read_termfreq_and_collfreq();
00067 RETURN(termfreq);
00068 }
00069
00070 Xapian::termcount
00071 BrassAllTermsList::get_collection_freq() const
00072 {
00073 LOGCALL(DB, Xapian::termcount, "BrassAllTermsList::get_collection_freq", NO_ARGS);
00074 Assert(!current_term.empty());
00075 Assert(!at_end());
00076 if (termfreq == 0) read_termfreq_and_collfreq();
00077 RETURN(collfreq);
00078 }
00079
00080 TermList *
00081 BrassAllTermsList::next()
00082 {
00083 LOGCALL(DB, TermList *, "BrassAllTermsList::next", NO_ARGS);
00084 Assert(!at_end());
00085
00086
00087 termfreq = 0;
00088
00089 if (rare(!cursor)) {
00090 cursor = database->postlist_table.cursor_get();
00091 Assert(cursor);
00092
00093 if (prefix.empty()) {
00094 (void)cursor->find_entry_ge(string("\x00\xff", 2));
00095 } else {
00096 const string & key = pack_brass_postlist_key(prefix);
00097 if (cursor->find_entry_ge(key)) {
00098
00099
00100 current_term = prefix;
00101 RETURN(NULL);
00102 }
00103 }
00104 goto first_time;
00105 }
00106
00107 while (true) {
00108 cursor->next();
00109 first_time:
00110 if (cursor->after_end()) {
00111 current_term.resize(0);
00112 RETURN(NULL);
00113 }
00114
00115 const char *p = cursor->current_key.data();
00116 const char *pend = p + cursor->current_key.size();
00117 if (!unpack_string_preserving_sort(&p, pend, current_term)) {
00118 throw Xapian::DatabaseCorruptError("PostList table key has unexpected format");
00119 }
00120
00121
00122
00123
00124 if (p == pend) break;
00125 }
00126
00127 if (!startswith(current_term, prefix)) {
00128
00129 cursor->to_end();
00130 current_term.resize(0);
00131 }
00132
00133 RETURN(NULL);
00134 }
00135
00136 TermList *
00137 BrassAllTermsList::skip_to(const string &term)
00138 {
00139 LOGCALL(DB, TermList *, "BrassAllTermsList::skip_to", term);
00140 Assert(!at_end());
00141
00142
00143 termfreq = 0;
00144
00145 if (rare(!cursor)) {
00146 cursor = database->postlist_table.cursor_get();
00147 Assert(cursor);
00148 }
00149
00150 string key = pack_brass_postlist_key(term);
00151 if (cursor->find_entry_ge(key)) {
00152
00153
00154 current_term = term;
00155 } else {
00156 if (cursor->after_end()) {
00157 current_term.resize(0);
00158 RETURN(NULL);
00159 }
00160
00161 const char *p = cursor->current_key.data();
00162 const char *pend = p + cursor->current_key.size();
00163 if (!unpack_string_preserving_sort(&p, pend, current_term)) {
00164 throw Xapian::DatabaseCorruptError("PostList table key has unexpected format");
00165 }
00166 }
00167
00168 if (!startswith(current_term, prefix)) {
00169
00170 cursor->to_end();
00171 current_term.resize(0);
00172 }
00173
00174 RETURN(NULL);
00175 }
00176
00177 bool
00178 BrassAllTermsList::at_end() const
00179 {
00180 LOGCALL(DB, bool, "BrassAllTermsList::at_end", NO_ARGS);
00181 RETURN(cursor && cursor->after_end());
00182 }