00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <config.h>
00024 #include "quartz_alltermslist.h"
00025 #include "quartz_utils.h"
00026 #include "quartz_postlist.h"
00027
00028 #include "stringutils.h"
00029
00030 QuartzAllTermsList::QuartzAllTermsList(Xapian::Internal::RefCntPtr<const Xapian::Database::Internal> database_,
00031 AutoPtr<Bcursor> pl_cursor_,
00032 quartz_tablesize_t size_,
00033 const string & prefix_)
00034 : database(database_), pl_cursor(pl_cursor_), size(size_),
00035 started(false), prefix(prefix_)
00036 {
00037 DEBUGCALL(DB, void, "QuartzAllTermsList", "[database_], [pl_cursor_]");
00038 if (prefix.empty()) {
00039
00040 pl_cursor->find_entry(string());
00041
00042 if (pl_cursor->current_key.empty()) {
00043 pl_cursor->next();
00044 }
00045 } else {
00046
00047 if (!pl_cursor->find_entry(pack_string_preserving_sort(prefix))) {
00048
00049
00050 pl_cursor->next();
00051 }
00052 }
00053
00054 is_at_end = pl_cursor->after_end();
00055 if (!is_at_end) {
00056 const char *start = pl_cursor->current_key.data();
00057 const char *end = start + pl_cursor->current_key.length();
00058 if (!unpack_string_preserving_sort(&start, end, current_term)) {
00059 throw Xapian::DatabaseCorruptError("Failed to read the key field from a Bcursor's key");
00060 }
00061 }
00062
00063 if (!startswith(current_term, prefix))
00064 is_at_end = true;
00065
00066 have_stats = false;
00067 }
00068
00069 QuartzAllTermsList::~QuartzAllTermsList()
00070 {
00071 DEBUGCALL(DB, void, "~QuartzAllTermsList", "");
00072 }
00073
00074 string
00075 QuartzAllTermsList::get_termname() const
00076 {
00077 DEBUGCALL(DB, string, "QuartzAllTermsList::get_termname", "");
00078 Assert(started);
00079 RETURN(current_term);
00080 }
00081
00082 void QuartzAllTermsList::get_stats() const
00083 {
00084 pl_cursor->read_tag();
00085 const char *start = pl_cursor->current_tag.data();
00086 const char *end = start + pl_cursor->current_tag.length();
00087 QuartzPostList::read_number_of_entries(&start, end,
00088 &termfreq, &collection_freq);
00089
00090 have_stats = true;
00091 }
00092
00093 Xapian::doccount
00094 QuartzAllTermsList::get_termfreq() const
00095 {
00096 DEBUGCALL(DB, Xapian::doccount, "QuartzAllTermsList::get_termfreq", "");
00097 Assert(started);
00098 if (have_stats) {
00099 RETURN(termfreq);
00100 } else if (!is_at_end) {
00101 get_stats();
00102 RETURN(termfreq);
00103 }
00104 throw Xapian::InvalidArgumentError("Attempt to get termfreq after end");
00105 }
00106
00107 Xapian::termcount
00108 QuartzAllTermsList::get_collection_freq() const
00109 {
00110 DEBUGCALL(DB, Xapian::termcount, "QuartzAllTermsList::get_collection_freq", "");
00111 Assert(started);
00112 if (have_stats) {
00113 RETURN(collection_freq);
00114 } else if (!is_at_end) {
00115 get_stats();
00116 RETURN(collection_freq);
00117 }
00118 throw Xapian::InvalidArgumentError("Attempt to get collection_freq after end");
00119 }
00120
00121 TermList *
00122 QuartzAllTermsList::skip_to(const string &tname)
00123 {
00124 DEBUGCALL(DB, TermList *, "QuartzAllTermsList::skip_to", tname);
00125 DEBUGLINE(DB, "QuartzAllTermList::skip_to(" << tname << ")");
00126 started = true;
00127 string key;
00128 key = pack_string_preserving_sort(tname);
00129
00130 have_stats = false;
00131
00132 if (!pl_cursor->find_entry(key)) {
00133 if (pl_cursor->after_end()) {
00134 is_at_end = true;
00135 } else {
00136 next();
00137
00138 }
00139 } else {
00140
00141
00142 current_term = tname;
00143
00144
00145 if (!startswith(current_term, prefix))
00146 is_at_end = true;
00147 }
00148 RETURN(NULL);
00149 }
00150
00151 TermList *
00152 QuartzAllTermsList::next()
00153 {
00154 DEBUGCALL(DB, TermList *, "QuartzAllTermsList::next", "");
00155 if (!started) {
00156 started = true;
00157 } else {
00158 while (true) {
00159 pl_cursor->next();
00160
00161 is_at_end = pl_cursor->after_end();
00162
00163 if (is_at_end) break;
00164
00165 const char *start = pl_cursor->current_key.data();
00166 const char *end = start + pl_cursor->current_key.length();
00167 if (!unpack_string_preserving_sort(&start, end, current_term)) {
00168 throw Xapian::DatabaseCorruptError("Failed to read the key field from a Bcursor's key");
00169 }
00170 if (!startswith(current_term, prefix)) {
00171 is_at_end = true;
00172 break;
00173 }
00174
00175 if (start == end) break;
00176 }
00177
00178 have_stats = false;
00179 }
00180 RETURN(NULL);
00181 }
00182
00183 bool
00184 QuartzAllTermsList::at_end() const
00185 {
00186 DEBUGCALL(DB, bool, "QuartzAllTermsList::at_end", "");
00187 RETURN(is_at_end);
00188 }