Ticket #671: readahead_perf_fix_with_glass.patch

File readahead_perf_fix_with_glass.patch, 12.0 KB (added by Will Greenberg, 10 years ago)
  • 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..8039960 100644
    a b  
    3232#include "xapian/intrusive_ptr.h"
    3333#include <xapian/types.h>
    3434#include <xapian/database.h>
     35#include <xapian/query.h>
    3536#include <xapian/document.h>
    3637#include <xapian/positioniterator.h>
    3738#include <xapian/termiterator.h>
    class Database::Internal : public Xapian::Internal::intrusive_base {  
    105106         */
    106107        virtual void keep_alive();
    107108
     109    virtual void readahead_for_query (const Xapian::Query & query);
     110
    108111        //////////////////////////////////////////////////////////////////
    109112        // Database statistics:
    110113        // ====================
  • xapian-core/backends/glass/glass_database.cc

    diff --git a/xapian-core/backends/glass/glass_database.cc b/xapian-core/backends/glass/glass_database.cc
    index 32d7d20..6208be3 100644
    a b GlassDatabase::set_revision_number(int flags, glass_revision_number_t new_revisi  
    347347    changes.commit(new_revision, flags);
    348348}
    349349
     350void
     351GlassDatabase::request_document(Xapian::docid did) const
     352{
     353    docdata_table.readahead_for_document(did);
     354}
     355
     356void
     357GlassDatabase::readahead_for_query(const Xapian::Query &query)
     358{
     359    Xapian::TermIterator t;
     360    for (t = query.get_terms_begin(); t != Xapian::TermIterator(); ++t) {
     361        const string & term = *t;
     362        postlist_table.readahead_key(term);
     363    }
     364}
     365
    350366bool
    351367GlassDatabase::reopen()
    352368{
  • xapian-core/backends/glass/glass_database.h

    diff --git a/xapian-core/backends/glass/glass_database.h b/xapian-core/backends/glass/glass_database.h
    index 0f1fedd..7eb9e78 100644
    a b class GlassDatabase : public Xapian::Database::Internal {  
    207207                                     glass_revision_number_t * endrev) const;
    208208
    209209    public:
     210
     211    void request_document(Xapian::docid /*did*/) const;
     212    void readahead_for_query(const Xapian::Query &query);
    210213        /** Create and open a glass database.
    211214         *
    212215         *  @exception Xapian::DatabaseCorruptError is thrown if a problem is
  • xapian-core/backends/glass/glass_docdata.h

    diff --git a/xapian-core/backends/glass/glass_docdata.h b/xapian-core/backends/glass/glass_docdata.h
    index 4fbf57a..6e0fbc1 100644
    a b class GlassDocDataTable : public GlassLazyTable {  
    9999     *               there's no such document, or the document has no data).
    100100     */
    101101    bool delete_document_data(Xapian::docid did) { return del(make_key(did)); }
     102
     103    void readahead_for_document(Xapian::docid did) const {
     104        readahead_key(make_key(did));
     105    }
    102106};
    103107
    104108#endif // XAPIAN_INCLUDED_GLASS_DOCDATA_H
  • xapian-core/backends/glass/glass_table.cc

    diff --git a/xapian-core/backends/glass/glass_table.cc b/xapian-core/backends/glass/glass_table.cc
    index d90f869..2b9bc02 100644
    a b GlassTable::del(const string &key)  
    11531153    RETURN(true);
    11541154}
    11551155
     1156void
     1157GlassTable::readahead_block(uint4 n) const
     1158{
     1159    if (rare(handle == -2))
     1160        GlassTable::throw_database_closed();
     1161
     1162    /* Use the base bit_map_size not the bitmap's size, because
     1163     * the latter is uninitialised in readonly mode.
     1164     */
     1165    Assert(n / CHAR_BIT < base.get_bit_map_size());
     1166
     1167    io_readahead_block(handle, block_size, n);
     1168}
     1169
     1170bool
     1171GlassTable::readahead_key(const string &key) const
     1172{
     1173    LOGCALL(DB, bool, "GlassTable::readahead_key", key);
     1174    Assert(!key.empty());
     1175
     1176    form_key(key);
     1177
     1178    const byte * p;
     1179    int c;
     1180
     1181    Key ktkey = kt.key();
     1182
     1183    // We'll only readahead the first level, since descending the B-tree would
     1184    // require actual reads that would likely hurt performance more than help.
     1185    p = C[level].get_p();
     1186    c = find_in_block(p, ktkey, false, C[level].c);
     1187    uint4 n = Item(p, c).block_given_by();
     1188
     1189    readahead_block(n);
     1190    RETURN(true);
     1191}
     1192
    11561193bool
    11571194GlassTable::get_exact_entry(const string &key, string & tag) const
    11581195{
  • xapian-core/backends/glass/glass_table.h

    diff --git a/xapian-core/backends/glass/glass_table.h b/xapian-core/backends/glass/glass_table.h
    index c9b2282..bb37691 100644
    a b class GlassTable {  
    346346         */
    347347        void close(bool permanent=false);
    348348
     349    bool readahead_key(const string &key) const;
     350
    349351        /** Determine whether the btree exists on disk.
    350352         */
    351353        bool exists() const;
    class GlassTable {  
    604606        bool find(Glass::Cursor *) const;
    605607        int delete_kt();
    606608        void read_block(uint4 n, byte *p) const;
     609    void readahead_block(uint4 n) const;
    607610        void write_block(uint4 n, const byte *p, bool appending = false) const;
    608611        XAPIAN_NORETURN(void set_overwritten() const);
    609612        void block_to_cursor(Glass::Cursor *C_, int j, uint4 n) const;
  • xapian-core/common/io_utils.cc

    diff --git a/xapian-core/common/io_utils.cc b/xapian-core/common/io_utils.cc
    index fefef8e..55ecc5d 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#ifdef HAVE_POSIX_FADVISE
     111    off_t o = b * n;
     112    posix_fadvise(fd, o, n, POSIX_FADV_WILLNEED);
     113#endif
     114}
     115
     116void
    108117io_read_block(int fd, char * p, size_t n, off_t b)
    109118{
    110119    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/configure.ac

    diff --git a/xapian-core/configure.ac b/xapian-core/configure.ac
    index 1ab4694..edb03bf 100644
    a b AC_CHECK_DECL([fdatasync(int)], [  
    912912)
    913913
    914914AC_CHECK_FUNCS([fsync])
     915AC_CHECK_FUNCS([posix_fadvise])
    915916
    916917dnl HP-UX has pread and pwrite, but they don't work!  Apparently this problem
    917918dnl manifests when largefile support is enabled, and we definitely want that
  • 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.