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