Ticket #278: max_changesets.diff

File max_changesets.diff, 11.4 KB (added by Dan, 13 years ago)

Updated diff with tests

  • xapian-core/backends/brass/brass_database.cc

    diff --git a/xapian-core/backends/brass/brass_database.cc b/xapian-core/backends/brass/brass_database.cc
    index 56f534e..aa6f9fa 100644
    a b  
    77 * Copyright 2006,2008 Lemur Consulting Ltd
    88 * Copyright 2009 Richard Boulton
    99 * Copyright 2009 Kan-Ru Chen
     10 * Copyright 2011 Dan Colish
    1011 *
    1112 * This program is free software; you can redistribute it and/or
    1213 * modify it under the terms of the GNU General Public License as
    BrassDatabase::set_revision_number(brass_revision_number_t new_revision)  
    470471
    471472        throw;
    472473    }
     474   
     475    // Only remove the oldest_changeset if we successfully write a new changeset and
     476    // we have a revision number greater than max_changesets
     477    if (changes_fd >= 0 && max_changesets < new_revision) {
     478        // use the oldest changeset we know about to being deleting
     479        // if nothing went wrong only one file should be deleted, otherwise
     480        // attempts will be made to clean up more
     481        brass_revision_number_t oldest_changeset = get_oldest_changeset();
     482        unsigned int stop_changeset = new_revision - max_changesets;
     483        while (oldest_changeset < stop_changeset) {
     484            if (io_unlink(db_dir + "/changes" + str(oldest_changeset))) {
     485                LOGLINE(DB, "Removed changeset " << oldest_changeset);
     486            } else {
     487                LOGLINE(DB, "Skipping changeset " << oldest_changeset <<
     488                        ", likely removed before");
     489            }
     490            set_oldest_changeset(oldest_changeset++);
     491        }
     492    }
    473493}
    474494
    475495void
    BrassDatabase::get_uuid() const  
    10081028    RETURN(version_file.get_uuid_string());
    10091029}
    10101030
     1031brass_revision_number_t
     1032BrassDatabase::get_oldest_changeset() const
     1033{
     1034    LOGCALL(DB, brass_revision_number_t, "BrassDatabase::get_oldest_changeset", NO_ARGS);
     1035    return stats.get_oldest_changeset();
     1036}
     1037
     1038void
     1039BrassDatabase::set_oldest_changeset(brass_revision_number_t changeset)
     1040{
     1041    LOGCALL(DB, void, "BrassDatabase::set_oldest_changeset", changeset);
     1042    stats.set_oldest_changeset(changeset);
     1043}
     1044
    10111045///////////////////////////////////////////////////////////////////////////
    10121046
    10131047BrassWritableDatabase::BrassWritableDatabase(const string &dir, int action,
  • xapian-core/backends/brass/brass_database.h

    diff --git a/xapian-core/backends/brass/brass_database.h b/xapian-core/backends/brass/brass_database.h
    index 6f8e928..408fc5b 100644
    a b  
    44 * Copyright 2002 Ananova Ltd
    55 * Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2010 Olly Betts
    66 * Copyright 2008 Lemur Consulting Ltd
     7 * Copyright 2011 Dan Colish
    78 *
    89 * This program is free software; you can redistribute it and/or
    910 * modify it under the terms of the GNU General Public License as
    class BrassDatabase : public Xapian::Database::Internal {  
    216217        void get_changeset_revisions(const string & path,
    217218                                     brass_revision_number_t * startrev,
    218219                                     brass_revision_number_t * endrev) const;
     220
     221        /** Get the oldest changeset on disk
     222         */
     223        brass_revision_number_t get_oldest_changeset() const;
     224       
     225        /** Set the new oldest changeset on disk
     226         */
     227        void set_oldest_changeset(brass_revision_number_t oldest_changeset);
     228
    219229    public:
    220230        /** Create and open a brass database.
    221231         *
  • xapian-core/backends/brass/brass_dbstats.cc

    diff --git a/xapian-core/backends/brass/brass_dbstats.cc b/xapian-core/backends/brass/brass_dbstats.cc
    index d4bff9e..9d5bcec 100644
    a b  
    22 * @brief Brass class for database statistics.
    33 */
    44/* Copyright (C) 2009 Olly Betts
     5 * Copyright (C) 2011 Dan Colish
    56 *
    67 * This program is free software; you can redistribute it and/or
    78 * modify it under the terms of the GNU General Public License as
    BrassDatabaseStats::read(BrassPostListTable & postlist_table)  
    3536    string data;
    3637    if (!postlist_table.get_exact_entry(DATABASE_STATS_KEY, data)) {
    3738        // If there's no entry yet, then all the values are zero.
    38         total_doclen = 0;
    39         last_docid = 0;
    40         doclen_lbound = 0;
    41         doclen_ubound = 0;
    42         wdf_ubound = 0;
     39        zero();
    4340        return;
    4441    }
    4542
    BrassDatabaseStats::read(BrassPostListTable & postlist_table)  
    5047        unpack_uint(&p, end, &doclen_lbound) &&
    5148        unpack_uint(&p, end, &wdf_ubound) &&
    5249        unpack_uint(&p, end, &doclen_ubound) &&
     50        unpack_uint(&p, end, &oldest_changeset) &&
    5351        unpack_uint_last(&p, end, &total_doclen)) {
    5452        // doclen_ubound should always be >= wdf_ubound, so we store the
    5553        // difference as it may encode smaller.  wdf_ubound is likely to
    BrassDatabaseStats::write(BrassPostListTable & postlist_table) const  
    7573    // difference as it may encode smaller.  wdf_ubound is likely to
    7674    // be larger than doclen_lbound.
    7775    pack_uint(data, doclen_ubound - wdf_ubound);
     76    pack_uint(data, oldest_changeset);
    7877    // Micro-optimisation: total_doclen is likely to be the largest value, so
    7978    // store it last as pack_uint_last() uses a slightly more compact encoding
    8079    // - this could save us a few bytes!
  • xapian-core/backends/brass/brass_dbstats.h

    diff --git a/xapian-core/backends/brass/brass_dbstats.h b/xapian-core/backends/brass/brass_dbstats.h
    index d3a281e..131afd8 100644
    a b  
    22 * @brief Brass class for database statistics.
    33 */
    44/* Copyright (C) 2009 Olly Betts
     5 * Copyright (C) 2011 Dan Colish
    56 *
    67 * This program is free software; you can redistribute it and/or
    78 * modify it under the terms of the GNU General Public License as
    class BrassDatabaseStats {  
    5152    /// An upper bound on the greatest wdf in this database.
    5253    Xapian::termcount wdf_ubound;
    5354
     55    /// Oldest changeset removed when max_changesets is set
     56    brass_revision_number_t oldest_changeset;
     57
    5458  public:
    5559    BrassDatabaseStats()
    5660        : total_doclen(0), last_docid(0), doclen_lbound(0), doclen_ubound(0),
    57           wdf_ubound(0) { }
     61          wdf_ubound(0), oldest_changeset(0) { }
    5862
    5963    totlen_t get_total_doclen() const { return total_doclen; }
    6064
    class BrassDatabaseStats {  
    7074
    7175    Xapian::termcount get_wdf_upper_bound() const { return wdf_ubound; }
    7276
     77    brass_revision_number_t get_oldest_changeset() const { return oldest_changeset; }
     78
    7379    void zero() {
    7480        total_doclen = 0;
    7581        last_docid = 0;
    7682        doclen_lbound = 0;
    7783        doclen_ubound = 0;
    7884        wdf_ubound = 0;
     85        oldest_changeset = 0;
    7986    }
    8087
    8188    void read(BrassPostListTable & postlist_table);
    8289
    8390    void set_last_docid(Xapian::docid did) { last_docid = did; }
    8491
     92    void set_oldest_changeset(brass_revision_number_t changeset) { oldest_changeset = changeset; }
     93
    8594    void add_document(Xapian::termcount doclen) {
    8695        if (total_doclen == 0 || (doclen && doclen < doclen_lbound))
    8796            doclen_lbound = doclen;
  • xapian-core/backends/brass/brass_version.cc

    diff --git a/xapian-core/backends/brass/brass_version.cc b/xapian-core/backends/brass/brass_version.cc
    index b54fb4b..b0190a9 100644
    a b  
    22 * @brief BrassVersion class
    33 */
    44/* Copyright (C) 2006,2007,2008,2009,2010 Olly Betts
     5 * Copyright (C) 2011 Dan Colish
    56 *
    67 * This program is free software; you can redistribute it and/or modify
    78 * it under the terms of the GNU General Public License as published by
     
    4344using namespace std;
    4445
    4546// YYYYMMDDX where X allows multiple format revisions in a day
    46 #define BRASS_VERSION 200912150
     47#define BRASS_VERSION 201103110
     48// 201103110 1.2.5? Bump for new max changesets dbstats
    4749// 200912150 1.1.4 Brass debuts.
    4850
    4951#define MAGIC_STRING "IAmBrass"
  • 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 3cc6b56..b8e54a7 100644
    a b  
    77 * Copyright 2006,2008 Lemur Consulting Ltd
    88 * Copyright 2009,2010 Richard Boulton
    99 * Copyright 2009 Kan-Ru Chen
     10 * Copyright 2011 Dan Colish
    1011 *
    1112 * This program is free software; you can redistribute it and/or
    1213 * modify it under the terms of the GNU General Public License as
    ChertDatabase::set_revision_number(chert_revision_number_t new_revision)  
    465466
    466467        throw;
    467468    }
     469   
     470    if (changes_fd >= 0 && max_changesets < new_revision) {
     471        // While change sets less than N - max_changesets exist, delete them
     472        // 1 must be subtracted so we don't delete the changset we just wrote
     473        // when max_changesets = 1
     474        unsigned rev = new_revision - max_changesets - 1;
     475        while (io_unlink(db_dir + "/changes" + str(rev--))) { }
     476    }
    468477}
    469478
    470479void
  • xapian-core/backends/flint/flint_database.cc

    diff --git a/xapian-core/backends/flint/flint_database.cc b/xapian-core/backends/flint/flint_database.cc
    index d5eb8a1..4623d94 100644
    a b  
    77 * Copyright 2006,2008 Lemur Consulting Ltd
    88 * Copyright 2009,2010 Richard Boulton
    99 * Copyright 2009 Kan-Ru Chen
     10 * Copyright 2011 Dan Colish
    1011 *
    1112 * This program is free software; you can redistribute it and/or
    1213 * modify it under the terms of the GNU General Public License as
    FlintDatabase::set_revision_number(flint_revision_number_t new_revision)  
    497498
    498499        throw;
    499500    }
     501
     502    if (changes_fd >= 0 && max_changesets < new_revision) {
     503        // while change sets less than N - max_changesets exist, delete them
     504        // 1 must be subtracted so we don't delete the changset we just wrote
     505        // when max_changesets = 1
     506        unsigned rev = new_revision - max_changesets - 1;
     507        while (io_unlink(db_dir + "/changes" + str(rev--)))  { }
     508    }
    500509}
    501510
    502511void
  • xapian-core/tests/api_replicate.cc

    diff --git a/xapian-core/tests/api_replicate.cc b/xapian-core/tests/api_replicate.cc
    index fdd18f8..9e118e0 100644
    a b  
    33 * Copyright 2008 Lemur Consulting Ltd
    44 * Copyright 2009,2010 Olly Betts
    55 * Copyright 2010 Richard Boulton
     6 * Copyright 2011 Dan Colish
    67 *
    78 * This program is free software; you can redistribute it and/or
    89 * modify it under the terms of the GNU General Public License as
    DEFINE_TESTCASE(replicate3, replicas) {  
    512513    return true;
    513514}
    514515
    515 // Basic test of replication functionality.
     516// Tests for max_changesets
    516517DEFINE_TESTCASE(replicate4, replicas) {
    517518    string tempdir = ".replicatmp";
    518519    mktmpdir(tempdir);
    519520    string masterpath = get_named_writable_database_path("master");
    520521
    521     set_max_changesets(10);
     522    set_max_changesets(1);
    522523
    523524    Xapian::WritableDatabase orig(get_named_writable_database("master"));
    524525    Xapian::DatabaseMaster master(masterpath);
    DEFINE_TESTCASE(replicate4, replicas) {  
    555556    }
    556557    check_equal_dbs(masterpath, replicapath);
    557558
     559    // Add a document with no positions to the original database.
     560    Xapian::Document doc2;
     561    doc2.set_data(string("doc2"));
     562    doc2.add_term("nopos");
     563    orig.add_document(doc2);
     564    orig.commit();
     565
     566    // Replicate, and check that we have the positional information.
     567    count = replicate(master, replica, tempdir, 1, 0, 1);
     568    TEST_EQUAL(count, 2);
     569    {
     570        Xapian::Database dbcopy(replicapath);
     571        TEST_EQUAL(orig.get_uuid(), dbcopy.get_uuid());
     572    }
     573    check_equal_dbs(masterpath, replicapath);
     574
     575    int changes_fd = -1;
     576    string path = masterpath + "/changes1";
     577#ifdef __WIN32__
     578    changes_fd = msvc_posix_open(path.c_str(), O_RDONLY);
     579#else
     580    changes_fd = open(path.c_str(), O_RDONLY);
     581#endif
     582    fdcloser closer(changes_fd);
     583
     584    TEST_EQUAL(changes_fd, -1);
     585
    558586    // Need to close the replica before we remove the temporary directory on
    559587    // Windows.
    560588    replica.close();