Ticket #671: postlist_record_readahead.patch

File postlist_record_readahead.patch, 7.7 KB (added by Will Greenberg, 9 years ago)

Implemented readahead for both multi-db queries and MSet::fetch optimization

  • xapian-core/backends/chert/chert_database.cc

    diff --git a/xapian-core/backends/chert/chert_database.cc b/xapian-core/backends/chert/chert_database.cc
    index ff60d96..538554d 100644
    a b ChertDatabase::set_revision_number(chert_revision_number_t new_revision)  
    472472    }
    473473}
    474474
     475void
     476ChertDatabase::request_document(Xapian::docid did) const
     477{
     478    record_table.readahead_for_record(did);
     479}
     480
     481void
     482ChertDatabase::readahead_for_query(const Xapian::Query &query)
     483{
     484    Xapian::TermIterator t;
     485    for (t = query.get_terms_begin(); t != Xapian::TermIterator(); ++t) {
     486        const string & term = *t;
     487        postlist_table.readahead_key(term);
     488    }
     489}
     490
    475491bool
    476492ChertDatabase::reopen()
    477493{
  • xapian-core/backends/chert/chert_database.h

    diff --git a/xapian-core/backends/chert/chert_database.h b/xapian-core/backends/chert/chert_database.h
    index b7375d1..8445e60 100644
    a b class ChertDatabase : public Xapian::Database::Internal {  
    219219                                     chert_revision_number_t * startrev,
    220220                                     chert_revision_number_t * endrev) const;
    221221    public:
     222
     223    void request_document(Xapian::docid /*did*/) const;
     224    void readahead_for_query(const Xapian::Query &query);
    222225        /** Create and open a chert database.
    223226         *
    224227         *  @exception Xapian::DatabaseCorruptError is thrown if there is no
  • xapian-core/backends/chert/chert_record.cc

    diff --git a/xapian-core/backends/chert/chert_record.cc b/xapian-core/backends/chert/chert_record.cc
    index 55ba264..000ec8d 100644
    a b ChertRecordTable::get_doccount() const  
    6666}
    6767
    6868void
     69ChertRecordTable::readahead_for_record(Xapian::docid did) const
     70{
     71    readahead_key(make_key(did));
     72}
     73
     74void
    6975ChertRecordTable::replace_record(const string & data, Xapian::docid did)
    7076{
    7177    LOGCALL_VOID(DB, "ChertRecordTable::replace_record", data | did);
  • xapian-core/backends/chert/chert_record.h

    diff --git a/xapian-core/backends/chert/chert_record.h b/xapian-core/backends/chert/chert_record.h
    index 0f6607d..48917ca 100644
    a b class ChertRecordTable : public ChertTable {  
    6565         */
    6666        void replace_record(const string & data, Xapian::docid did);
    6767
     68    void readahead_for_record(Xapian::docid did) const;
     69
    6870        /** Delete a record from the table.
    6971         */
    7072        void delete_record(Xapian::docid did);
  • xapian-core/backends/chert/chert_table.cc

    diff --git a/xapian-core/backends/chert/chert_table.cc b/xapian-core/backends/chert/chert_table.cc
    index a18bb5a..b603db3 100644
    a b static inline byte *zeroed_new(size_t size)  
    167167
    168168#define BYTE_PAIR_RANGE (1 << 2 * CHAR_BIT)
    169169
     170void
     171ChertTable::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
    170184/// read_block(n, p) reads block n of the DB file to address p.
    171185void
    172186ChertTable::read_block(uint4 n, byte * p) const
    ChertTable::del(const string &key)  
    11341148}
    11351149
    11361150bool
     1151ChertTable::readahead_key(const string &key) const
     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
     1163    // We'll only readahead the first level, since descending the B-tree would
     1164    // require actual reads that would likely hurt performance more than help.
     1165    p = C[level].p;
     1166    c = find_in_block(p, ktkey, false, C[level].c);
     1167    uint4 n = Item(p, c).block_given_by();
     1168
     1169    readahead_block(n);
     1170    RETURN(true);
     1171}
     1172
     1173bool
    11371174ChertTable::get_exact_entry(const string &key, string & tag) const
    11381175{
    11391176    LOGCALL(DB, bool, "ChertTable::get_exact_entry", key | tag);
  • xapian-core/backends/chert/chert_table.h

    diff --git a/xapian-core/backends/chert/chert_table.h b/xapian-core/backends/chert/chert_table.h
    index 2ea61ec..dd5c6c2 100644
    a b class XAPIAN_VISIBILITY_DEFAULT ChertTable {  
    334334         */
    335335        void close(bool permanent=false);
    336336
     337    bool readahead_key(const string &key) const;
     338
    337339        /** Determine whether the btree exists on disk.
    338340         */
    339341        bool exists() const;
    class XAPIAN_VISIBILITY_DEFAULT ChertTable {  
    627629        bool find(Cursor *) const;
    628630        int delete_kt();
    629631        void read_block(uint4 n, byte *p) const;
     632    void readahead_block(uint4 n) const;
    630633        void write_block(uint4 n, const byte *p) const;
    631634        XAPIAN_NORETURN(void set_overwritten() const);
    632635        void block_to_cursor(Cursor *C_, int j, uint4 n) const;
  • xapian-core/backends/database.cc

    diff --git a/xapian-core/backends/database.cc b/xapian-core/backends/database.cc
    index e98b32a..7cc8d6d 100644
    a b Database::Internal::keep_alive()  
    5050}
    5151
    5252
     53void
     54Database::Internal::readahead_for_query (const Xapian::Query & query)
     55{
     56    (void)query;
     57    throw Xapian::UnimplementedError("This backend doesn't support readaheads");
     58}
     59
    5360Xapian::doccount
    5461Database::Internal::get_value_freq(Xapian::valueno) const
    5562{
  • xapian-core/backends/database.h

    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 {  
    105105         */
    106106        virtual void keep_alive();
    107107
     108    virtual void readahead_for_query (const Xapian::Query & query);
     109
    108110        //////////////////////////////////////////////////////////////////
    109111        // Database statistics:
    110112        // ====================
  • xapian-core/common/io_utils.cc

    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)  
    105105}
    106106
    107107void
     108io_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
     114void
    108115io_read_block(int fd, char * p, size_t n, off_t b)
    109116{
    110117    off_t o = b * n;
  • xapian-core/common/io_utils.h

    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) {  
    8282    io_write(fd, reinterpret_cast<const char *>(p), n);
    8383}
    8484
     85/// Readahead block b size n bytes from file descriptor fd
     86void io_readahead_block(int fd, size_t n, off_t b);
     87
    8588/// Read block b size n bytes into buffer p from file descriptor fd.
    8689void io_read_block(int fd, char * p, size_t n, off_t b);
    8790
  • xapian-core/include/xapian/database.h

    diff --git a/xapian-core/include/xapian/database.h b/xapian-core/include/xapian/database.h
    index 78f14d9..ab0339e 100644
    a b  
    3636#include <xapian/attributes.h>
    3737#include <xapian/intrusive_ptr.h>
    3838#include <xapian/types.h>
     39#include <xapian/query.h>
    3940#include <xapian/positioniterator.h>
    4041#include <xapian/postingiterator.h>
    4142#include <xapian/termiterator.h>
  • xapian-core/matcher/multimatch.cc

    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_,  
    332332                is_remote[i] = true;
    333333            } else {
    334334                smatch = new LocalSubMatch(subdb, query, qlen, subrsets[i], weight);
     335        subdb->readahead_for_query(query);
    335336            }
    336337#else
    337338            // Avoid unused parameter warnings.