diff --git a/xapian-core/backends/chert/chert_database.cc b/xapian-core/backends/chert/chert_database.cc
index ff60d96..3f4d570 100644
|
a
|
b
|
ChertDatabase::set_revision_number(chert_revision_number_t new_revision)
|
| 472 | 472 | } |
| 473 | 473 | } |
| 474 | 474 | |
| | 475 | void |
| | 476 | ChertDatabase::readahead_for_query(const Xapian::Query &query) |
| | 477 | { |
| | 478 | Xapian::TermIterator t; |
| | 479 | for (t = query.get_terms_begin(); t != Xapian::TermIterator(); ++t) { |
| | 480 | const string & term = *t; |
| | 481 | postlist_table.readahead_key(term); |
| | 482 | } |
| | 483 | } |
| | 484 | |
| 475 | 485 | bool |
| 476 | 486 | ChertDatabase::reopen() |
| 477 | 487 | { |
diff --git a/xapian-core/backends/chert/chert_database.h b/xapian-core/backends/chert/chert_database.h
index b7375d1..083ce17 100644
|
a
|
b
|
class ChertDatabase : public Xapian::Database::Internal {
|
| 219 | 219 | chert_revision_number_t * startrev, |
| 220 | 220 | chert_revision_number_t * endrev) const; |
| 221 | 221 | public: |
| | 222 | |
| | 223 | void readahead_for_query(const Xapian::Query &query); |
| 222 | 224 | /** Create and open a chert database. |
| 223 | 225 | * |
| 224 | 226 | * @exception Xapian::DatabaseCorruptError is thrown if there is no |
diff --git a/xapian-core/backends/chert/chert_table.cc b/xapian-core/backends/chert/chert_table.cc
index a18bb5a..6c77ff1 100644
|
a
|
b
|
static inline byte *zeroed_new(size_t size)
|
| 167 | 167 | |
| 168 | 168 | #define BYTE_PAIR_RANGE (1 << 2 * CHAR_BIT) |
| 169 | 169 | |
| | 170 | void |
| | 171 | ChertTable::readahead_block(uint4 n) const |
| | 172 | { |
| | 173 | if (rare(handle == -2)) |
| | 174 | ChertTable::throw_database_closed(); |
| | 175 | |
| | 176 | /* Use the base bit_map_size not the bitmap's size, because |
| | 177 | * the latter is uninitialised in readonly mode. |
| | 178 | */ |
| | 179 | Assert(n / CHAR_BIT < base.get_bit_map_size()); |
| | 180 | |
| | 181 | io_readahead_block(handle, block_size, n); |
| | 182 | } |
| | 183 | |
| 170 | 184 | /// read_block(n, p) reads block n of the DB file to address p. |
| 171 | 185 | void |
| 172 | 186 | ChertTable::read_block(uint4 n, byte * p) const |
| … |
… |
ChertTable::del(const string &key)
|
| 1134 | 1148 | } |
| 1135 | 1149 | |
| 1136 | 1150 | bool |
| | 1151 | ChertTable::readahead_key(const string &key) |
| | 1152 | { |
| | 1153 | LOGCALL(DB, bool, "ChertTable::readahead_key", key); |
| | 1154 | Assert(!key.empty()); |
| | 1155 | |
| | 1156 | form_key(key); |
| | 1157 | |
| | 1158 | const byte * p; |
| | 1159 | int c; |
| | 1160 | |
| | 1161 | Key ktkey = kt.key(); |
| | 1162 | for (int j = level; j > 0; --j) { |
| | 1163 | p = C[j].p; |
| | 1164 | c = find_in_block(p, ktkey, false, C[j].c); |
| | 1165 | C[j].c = c; |
| | 1166 | uint4 n = Item(p, c).block_given_by(); |
| | 1167 | if (n != C[j].n) { |
| | 1168 | readahead_block(n); |
| | 1169 | } |
| | 1170 | C[j].n = n; |
| | 1171 | } |
| | 1172 | p = C[0].p; |
| | 1173 | c = find_in_block(p, ktkey, true, C[0].c); |
| | 1174 | C[0].c = c; |
| | 1175 | if (c < DIR_START) { |
| | 1176 | RETURN(false); |
| | 1177 | } |
| | 1178 | RETURN(true); |
| | 1179 | } |
| | 1180 | |
| | 1181 | bool |
| 1137 | 1182 | ChertTable::get_exact_entry(const string &key, string & tag) const |
| 1138 | 1183 | { |
| 1139 | 1184 | LOGCALL(DB, bool, "ChertTable::get_exact_entry", key | tag); |
diff --git a/xapian-core/backends/chert/chert_table.h b/xapian-core/backends/chert/chert_table.h
index 2ea61ec..104676b 100644
|
a
|
b
|
class XAPIAN_VISIBILITY_DEFAULT ChertTable {
|
| 334 | 334 | */ |
| 335 | 335 | void close(bool permanent=false); |
| 336 | 336 | |
| | 337 | bool readahead_key(const string &key); |
| | 338 | |
| 337 | 339 | /** Determine whether the btree exists on disk. |
| 338 | 340 | */ |
| 339 | 341 | bool exists() const; |
| … |
… |
class XAPIAN_VISIBILITY_DEFAULT ChertTable {
|
| 627 | 629 | bool find(Cursor *) const; |
| 628 | 630 | int delete_kt(); |
| 629 | 631 | void read_block(uint4 n, byte *p) const; |
| | 632 | void readahead_block(uint4 n) const; |
| 630 | 633 | void write_block(uint4 n, const byte *p) const; |
| 631 | 634 | XAPIAN_NORETURN(void set_overwritten() const); |
| 632 | 635 | void block_to_cursor(Cursor *C_, int j, uint4 n) const; |
diff --git a/xapian-core/backends/database.cc b/xapian-core/backends/database.cc
index e98b32a..7cc8d6d 100644
|
a
|
b
|
Database::Internal::keep_alive()
|
| 50 | 50 | } |
| 51 | 51 | |
| 52 | 52 | |
| | 53 | void |
| | 54 | Database::Internal::readahead_for_query (const Xapian::Query & query) |
| | 55 | { |
| | 56 | (void)query; |
| | 57 | throw Xapian::UnimplementedError("This backend doesn't support readaheads"); |
| | 58 | } |
| | 59 | |
| 53 | 60 | Xapian::doccount |
| 54 | 61 | Database::Internal::get_value_freq(Xapian::valueno) const |
| 55 | 62 | { |
diff --git a/xapian-core/backends/database.h b/xapian-core/backends/database.h
index a0e7b43..351e9a7 100644
|
a
|
b
|
class Database::Internal : public Xapian::Internal::intrusive_base {
|
| 105 | 105 | */ |
| 106 | 106 | virtual void keep_alive(); |
| 107 | 107 | |
| | 108 | virtual void readahead_for_query (const Xapian::Query & query); |
| | 109 | |
| 108 | 110 | ////////////////////////////////////////////////////////////////// |
| 109 | 111 | // Database statistics: |
| 110 | 112 | // ==================== |
diff --git a/xapian-core/common/io_utils.cc b/xapian-core/common/io_utils.cc
index fefef8e..9dc267f 100644
|
a
|
b
|
throw_block_error(const char * s, off_t b, int e)
|
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | void |
| | 108 | io_readahead_block(int fd, size_t n, off_t b) |
| | 109 | { |
| | 110 | off_t o = b * n; |
| | 111 | posix_fadvise(fd, o, n, POSIX_FADV_WILLNEED); |
| | 112 | } |
| | 113 | |
| | 114 | void |
| 108 | 115 | io_read_block(int fd, char * p, size_t n, off_t b) |
| 109 | 116 | { |
| 110 | 117 | off_t o = b * n; |
diff --git a/xapian-core/common/io_utils.h b/xapian-core/common/io_utils.h
index 89d5d46..8b470ef 100644
|
a
|
b
|
inline void io_write(int fd, const unsigned char * p, size_t n) {
|
| 82 | 82 | io_write(fd, reinterpret_cast<const char *>(p), n); |
| 83 | 83 | } |
| 84 | 84 | |
| | 85 | /// Readahead block b size n bytes from file descriptor fd |
| | 86 | void io_readahead_block(int fd, size_t n, off_t b); |
| | 87 | |
| 85 | 88 | /// Read block b size n bytes into buffer p from file descriptor fd. |
| 86 | 89 | void io_read_block(int fd, char * p, size_t n, off_t b); |
| 87 | 90 | |
diff --git a/xapian-core/include/xapian/database.h b/xapian-core/include/xapian/database.h
index 78f14d9..ab0339e 100644
|
a
|
b
|
|
| 36 | 36 | #include <xapian/attributes.h> |
| 37 | 37 | #include <xapian/intrusive_ptr.h> |
| 38 | 38 | #include <xapian/types.h> |
| | 39 | #include <xapian/query.h> |
| 39 | 40 | #include <xapian/positioniterator.h> |
| 40 | 41 | #include <xapian/postingiterator.h> |
| 41 | 42 | #include <xapian/termiterator.h> |
diff --git a/xapian-core/matcher/multimatch.cc b/xapian-core/matcher/multimatch.cc
index ef8525e..a221cd6 100644
|
a
|
b
|
MultiMatch::MultiMatch(const Xapian::Database &db_,
|
| 332 | 332 | is_remote[i] = true; |
| 333 | 333 | } else { |
| 334 | 334 | smatch = new LocalSubMatch(subdb, query, qlen, subrsets[i], weight); |
| | 335 | subdb->readahead_for_query(query); |
| 335 | 336 | } |
| 336 | 337 | #else |
| 337 | 338 | // Avoid unused parameter warnings. |