Ticket #671: single_level_readahead.patch

File single_level_readahead.patch, 6.5 KB (added by Will Greenberg, 10 years ago)

Amended patch that only reads the first level of a postlist b-tree

  • 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..3f4d570 100644
    a b ChertDatabase::set_revision_number(chert_revision_number_t new_revision)  
    472472    }
    473473}
    474474
     475void
     476ChertDatabase::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
    475485bool
    476486ChertDatabase::reopen()
    477487{
  • 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..083ce17 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 readahead_for_query(const Xapian::Query &query);
    222224        /** Create and open a chert database.
    223225         *
    224226         *  @exception Xapian::DatabaseCorruptError is thrown if there is no
  • 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..cc761a1 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)
     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..104676b 100644
    a b class XAPIAN_VISIBILITY_DEFAULT ChertTable {  
    334334         */
    335335        void close(bool permanent=false);
    336336
     337    bool readahead_key(const string &key);
     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.