diff --git a/xapian-core/backends/brass/brass_dbcheck.cc b/xapian-core/backends/brass/brass_dbcheck.cc index 01e93a59565..4d7a45db3e5 100644 --- a/xapian-core/backends/brass/brass_dbcheck.cc +++ b/xapian-core/backends/brass/brass_dbcheck.cc @@ -617,37 +617,61 @@ check_brass_table(const char * tablename, string filename, } lastdid += did; bool bad = false; + + // Read the data of skip-list format while (true) { - Xapian::termcount wdf; - if (!unpack_uint(&pos, end, &wdf)) { - if (out) - *out << "Failed to unpack wdf" << endl; - ++errors; - bad = true; - break; - } - ++tf; - cf += wdf; - - if (pos == end) break; - - Xapian::docid inc; - if (!unpack_uint(&pos, end, &inc)) { - if (out) - *out << "Failed to unpack docid increase" << endl; - ++errors; - bad = true; - break; - } - ++inc; - did += inc; - if (did > lastdid) { - if (out) - *out << "docid " << did << " > last docid " << lastdid - << endl; - ++errors; - } + Xapian::docid inc = 0; + if (!unpack_uint(&pos, end, &inc)) { + if (out) + *out << "Failed to unpack docid increase" << endl; + ++errors; + bad = true; + break; + } + while (inc == (unsigned)-1) { + if (!unpack_uint(&pos, end, &inc)) { + if (out) + *out << "Failed to unpack skip info" << endl; + ++errors; + bad = true; + break; + } + if (!unpack_uint(&pos, end, &inc)) { + if (out) + *out << "Failed to unpack skip info" << endl; + ++errors; + bad = true; + break; + } + if (!unpack_uint(&pos, end, &inc)) { + if (out) + *out << "Failed to unpack docid increase" << endl; + ++errors; + bad = true; + break; + } + } + did += inc; + if (did > lastdid) { + if (out) + *out << "docid " << did << " > last docid " << lastdid + << endl; + ++errors; + } + Xapian::termcount wdf; + if (!unpack_uint(&pos, end, &wdf)) { + if (out) + *out << "Failed to unpack wdf" << endl; + ++errors; + bad = true; + break; + } + ++tf; + cf += wdf; + + if (pos == end) break; } + if (bad) { continue; } diff --git a/xapian-core/backends/brass/brass_postlist.cc b/xapian-core/backends/brass/brass_postlist.cc index b90edd73ae2..9813dba2c41 100644 --- a/xapian-core/backends/brass/brass_postlist.cc +++ b/xapian-core/backends/brass/brass_postlist.cc @@ -1342,9 +1342,20 @@ SkipListWriter::merge_postlist_changes(const string& term) * document ID of the first document in the chunk (encoded as length of * representation in first byte, and then docid). * - * there are two kinds of postlist, - * one is for document length, another is normal postlist storing wdf. - * doc length postlist adopts fixed-width format while normal postlist adopts skip-list format. + * There are two kinds of postlist: + * One is for storing document length, its termname is always a null string "", + * another is normal postlist storing wdf, it has normal termname. + * Document length postlist adopts fixed-width format while normal postlist adopts skip-list format. + * + * A chunk (except for the first chunk) contains: + * + * 1) bool - true if this is the last chunk. + * 2) difference between final docid in chunk and first docid. + * 3) data of fixed-width format or skip-list format + * + * The first chunk begins with the number of entries, the collection + * frequency, then the docid of the first document, then has the header of a + * standard chunk. */ BrassPostList::BrassPostList(intrusive_ptr this_db_, const string & term_,