Skip to content

Instantly share code, notes, and snippets.

@dcolish
Created July 25, 2012 06:13
Show Gist options
  • Select an option

  • Save dcolish/3174694 to your computer and use it in GitHub Desktop.

Select an option

Save dcolish/3174694 to your computer and use it in GitHub Desktop.
diff --git a/xapian-core/api/omdatabase.cc b/xapian-core/api/omdatabase.cc
index 8953cb6..211ed04 100644
--- a/xapian-core/api/omdatabase.cc
+++ b/xapian-core/api/omdatabase.cc
@@ -740,6 +740,17 @@ Database::get_uuid() const
RETURN(uuid);
}
+void
+Database::set_error_handler(ErrorHandler* error_handler_)
+{
+ LOGCALL(API, std::string, "Database::set_error_handler", error_handler_);
+ vector<intrusive_ptr<Database::Internal> >::const_iterator i;
+ for (i = internal.begin(); i != internal.end(); ++i) {
+ (*i)->error_handler = error_handler_;
+ }
+}
+
+
///////////////////////////////////////////////////////////////////////////
WritableDatabase::WritableDatabase() : Database()
diff --git a/xapian-core/api/omenquire.cc b/xapian-core/api/omenquire.cc
index 33da93b..75264d6 100644
--- a/xapian-core/api/omenquire.cc
+++ b/xapian-core/api/omenquire.cc
@@ -680,7 +680,7 @@ Enquire::Internal::get_mset(Xapian::doccount first, Xapian::doccount maxitems,
collapse_max, collapse_key,
percent_cutoff, weight_cutoff,
order, sort_key, sort_by, sort_value_forward,
- errorhandler, stats, weight, spies,
+ stats, weight, spies,
(sorter != NULL),
(mdecider != NULL));
// Run query and put results into supplied Xapian::MSet object.
@@ -829,15 +829,16 @@ Enquire::Internal::get_description() const
void
Enquire::Internal::request_doc(const Xapian::Internal::MSetItem &item) const
{
- try {
- unsigned int multiplier = db.internal.size();
+ unsigned int multiplier = db.internal.size();
- Xapian::docid realdid = (item.did - 1) / multiplier + 1;
- Xapian::doccount dbnumber = (item.did - 1) % multiplier;
+ Xapian::docid realdid = (item.did - 1) / multiplier + 1;
+ Xapian::doccount dbnumber = (item.did - 1) % multiplier;
+ try {
db.internal[dbnumber]->request_document(realdid);
} catch (Error & e) {
- if (errorhandler) (*errorhandler)(e);
+ ErrorHandler* error_handler = db.internal[dbnumber]->error_handler;
+ if (error_handler) (*error_handler)(e);
throw;
}
}
@@ -845,17 +846,18 @@ Enquire::Internal::request_doc(const Xapian::Internal::MSetItem &item) const
Document
Enquire::Internal::read_doc(const Xapian::Internal::MSetItem &item) const
{
- try {
- unsigned int multiplier = db.internal.size();
+ unsigned int multiplier = db.internal.size();
- Xapian::docid realdid = (item.did - 1) / multiplier + 1;
- Xapian::doccount dbnumber = (item.did - 1) % multiplier;
+ Xapian::docid realdid = (item.did - 1) / multiplier + 1;
+ Xapian::doccount dbnumber = (item.did - 1) % multiplier;
+ try {
Xapian::Document::Internal *doc;
doc = db.internal[dbnumber]->collect_document(realdid);
return Document(doc);
} catch (Error & e) {
- if (errorhandler) (*errorhandler)(e);
+ ErrorHandler* error_handler = db.internal[dbnumber]->error_handler;
+ if (error_handler) (*error_handler)(e);
throw;
}
}
@@ -902,12 +904,7 @@ const Query &
Enquire::get_query() const
{
LOGCALL(API, const Xapian::Query &, "Xapian::Enquire::get_query", NO_ARGS);
- try {
- RETURN(internal->get_query());
- } catch (Error & e) {
- if (internal->errorhandler) (*internal->errorhandler)(e);
- throw;
- }
+ RETURN(internal->get_query());
}
void
diff --git a/xapian-core/backends/database.cc b/xapian-core/backends/database.cc
index 53dc6d74..6c10eeb 100644
--- a/xapian-core/backends/database.cc
+++ b/xapian-core/backends/database.cc
@@ -49,7 +49,6 @@ Database::Internal::keep_alive()
// For the normal case of local databases, nothing needs to be done.
}
-
Xapian::doccount
Database::Internal::get_value_freq(Xapian::valueno) const
{
diff --git a/xapian-core/backends/database.h b/xapian-core/backends/database.h
index 3d95921..8595945 100644
--- a/xapian-core/backends/database.h
+++ b/xapian-core/backends/database.h
@@ -33,6 +33,7 @@
#include <xapian/types.h>
#include <xapian/database.h>
#include <xapian/document.h>
+#include <xapian/errorhandler.h>
#include <xapian/positioniterator.h>
#include <xapian/termiterator.h>
#include <xapian/valueiterator.h>
@@ -75,7 +76,7 @@ class Database::Internal : public Xapian::Internal::intrusive_base {
bool transaction_active() const { return int(transaction_state) > 0; }
/** Create a database - called only by derived classes. */
- Internal() : transaction_state(TRANSACTION_NONE) { }
+ Internal() : transaction_state(TRANSACTION_NONE), error_handler(NULL) { }
/** Internal method to perform cleanup when a writable database is
* destroyed with uncommitted changes.
@@ -108,6 +109,10 @@ class Database::Internal : public Xapian::Internal::intrusive_base {
*/
virtual void keep_alive();
+ /** Internal pointer to the database's ErrorHandler
+ */
+ ErrorHandler* error_handler;
+
//////////////////////////////////////////////////////////////////
// Database statistics:
// ====================
diff --git a/xapian-core/include/xapian/database.h b/xapian-core/include/xapian/database.h
index 243bf6d..7719577 100644
--- a/xapian-core/include/xapian/database.h
+++ b/xapian-core/include/xapian/database.h
@@ -30,6 +30,7 @@
#include <vector>
#include <xapian/attributes.h>
+#include <xapian/errorhandler.h>
#include <xapian/intrusive_ptr.h>
#include <xapian/types.h>
#include <xapian/positioniterator.h>
@@ -508,6 +509,14 @@ class XAPIAN_VISIBILITY_DEFAULT Database {
* @param opts Options to use for check
*/
static size_t check(const std::string & path, int opts);
+
+ /** Set an ErrorHandler for database. This will be applied to all
+ * databases in internal.
+ *
+ * @param error_handler_ ErrorHandler* to use
+ */
+ void set_error_handler(ErrorHandler* error_handler_);
+
};
/** This class provides read/write access to a database.
diff --git a/xapian-core/include/xapian/enquire.h b/xapian-core/include/xapian/enquire.h
index 41ad693..d7f0cd4 100644
--- a/xapian-core/include/xapian/enquire.h
+++ b/xapian-core/include/xapian/enquire.h
@@ -711,9 +711,6 @@ class XAPIAN_VISIBILITY_DEFAULT Enquire {
/** Get the query which has been set.
* This is only valid after set_query() has been called.
- *
- * @exception Xapian::InvalidArgumentError will be thrown if query has
- * not yet been set.
*/
const Xapian::Query & get_query() const;
diff --git a/xapian-core/matcher/mergepostlist.cc b/xapian-core/matcher/mergepostlist.cc
index b32f632..9e9b48d 100644
--- a/xapian-core/matcher/mergepostlist.cc
+++ b/xapian-core/matcher/mergepostlist.cc
@@ -30,7 +30,6 @@
#include "debuglog.h"
#include "omassert.h"
#include "valuestreamdocument.h"
-#include "xapian/errorhandler.h"
// NB don't prune - even with one sublist we still translate docids...
@@ -59,6 +58,7 @@ MergePostList::next(double w_min)
if (unsigned(current) >= plists.size()) break;
vsdoc.new_subdb(current);
} catch (Xapian::Error & e) {
+ Xapian::ErrorHandler* errorhandler = handlers[current];
if (errorhandler) {
LOGLINE(EXCEPTION, "Calling error handler in MergePostList::next().");
(*errorhandler)(e);
@@ -176,9 +176,10 @@ MergePostList::recalc_maxweight()
double w = (*i)->recalc_maxweight();
if (w > w_max) w_max = w;
} catch (Xapian::Error & e) {
- if (errorhandler) {
+ Xapian::ErrorHandler* errorhandler_ = handlers[current];
+ if (errorhandler_) {
LOGLINE(EXCEPTION, "Calling error handler in MergePostList::recalc_maxweight().");
- (*errorhandler)(e);
+ (*errorhandler_)(e);
if (current == i - plists.begin()) {
// Fatal error
diff --git a/xapian-core/matcher/mergepostlist.h b/xapian-core/matcher/mergepostlist.h
index f222fa2..f520445 100644
--- a/xapian-core/matcher/mergepostlist.h
+++ b/xapian-core/matcher/mergepostlist.h
@@ -26,6 +26,7 @@
#define OM_HGUARD_MERGEPOSTLIST_H
#include "api/postlist.h"
+#include "xapian/errorhandler.h"
class MultiMatch;
class ValueStreamDocument;
@@ -59,7 +60,11 @@ class MergePostList : public PostList {
*/
ValueStreamDocument & vsdoc;
- Xapian::ErrorHandler * errorhandler;
+ /**
+ *
+ */
+ std::vector<Xapian::ErrorHandler *> handlers;
+
public:
Xapian::termcount get_wdf() const;
Xapian::doccount get_termfreq_max() const;
@@ -90,9 +95,10 @@ class MergePostList : public PostList {
MergePostList(const std::vector<PostList *> & plists_,
MultiMatch *matcher_,
ValueStreamDocument & vsdoc_,
- Xapian::ErrorHandler * errorhandler_)
+ std::vector<Xapian::ErrorHandler *> & handlers_)
: plists(plists_), current(-1), matcher(matcher_), vsdoc(vsdoc_),
- errorhandler(errorhandler_) { }
+ handlers(handlers_)
+ { }
~MergePostList();
};
diff --git a/xapian-core/matcher/multimatch.cc b/xapian-core/matcher/multimatch.cc
index 654908a..bf72d95 100644
--- a/xapian-core/matcher/multimatch.cc
+++ b/xapian-core/matcher/multimatch.cc
@@ -136,10 +136,10 @@ split_rset_by_db(const Xapian::RSet * rset,
*/
static void
prepare_sub_matches(vector<intrusive_ptr<SubMatch> > & leaves,
- Xapian::ErrorHandler * errorhandler,
- Xapian::Weight::Internal & stats)
+ Xapian::Weight::Internal & stats,
+ const Xapian::Database & db)
{
- LOGCALL_STATIC_VOID(MATCH, "prepare_sub_matches", leaves | errorhandler | stats);
+ LOGCALL_STATIC_VOID(MATCH, "prepare_sub_matches", leaves | stats);
// We use a vector<bool> to track which SubMatches we're already prepared.
vector<bool> prepared;
prepared.resize(leaves.size(), false);
@@ -155,10 +155,11 @@ prepare_sub_matches(vector<intrusive_ptr<SubMatch> > & leaves,
--unprepared;
}
} catch (Xapian::Error & e) {
- if (!errorhandler) throw;
+ Xapian::ErrorHandler* errorhandler_ = db.internal[leaf]->error_handler;
+ if (!errorhandler_) throw;
LOGLINE(EXCEPTION, "Calling error handler for prepare_match() on a SubMatch.");
- (*errorhandler)(e);
+ (*errorhandler_)(e);
// Continue match without this sub-match.
leaves[leaf] = NULL;
prepared[leaf] = true;
@@ -211,7 +212,6 @@ MultiMatch::MultiMatch(const Xapian::Database &db_,
Xapian::valueno sort_key_,
Xapian::Enquire::Internal::sort_setting sort_by_,
bool sort_value_forward_,
- Xapian::ErrorHandler * errorhandler_,
Xapian::Weight::Internal & stats,
const Xapian::Weight * weight_,
const vector<Xapian::MatchSpy *> & matchspies_,
@@ -222,11 +222,11 @@ MultiMatch::MultiMatch(const Xapian::Database &db_,
order(order_),
sort_key(sort_key_), sort_by(sort_by_),
sort_value_forward(sort_value_forward_),
- errorhandler(errorhandler_), weight(weight_),
+ weight(weight_),
is_remote(db.internal.size()),
matchspies(matchspies_)
{
- LOGCALL_CTOR(MATCH, "MultiMatch", db_ | query_ | qlen | omrset | collapse_max_ | collapse_key_ | percent_cutoff_ | weight_cutoff_ | int(order_) | sort_key_ | int(sort_by_) | sort_value_forward_ | errorhandler_ | stats | weight_ | matchspies_ | have_sorter | have_mdecider);
+ LOGCALL_CTOR(MATCH, "MultiMatch", db_ | query_ | qlen | omrset | collapse_max_ | collapse_key_ | percent_cutoff_ | weight_cutoff_ | int(order_) | sort_key_ | int(sort_by_) | sort_value_forward_ | stats | weight_ | matchspies_ | have_sorter | have_mdecider);
if (query.empty()) return;
@@ -267,9 +267,10 @@ MultiMatch::MultiMatch(const Xapian::Database &db_,
smatch = new LocalSubMatch(subdb, query, qlen, subrsets[i], weight);
#endif /* XAPIAN_HAS_REMOTE_BACKEND */
} catch (Xapian::Error & e) {
- if (!errorhandler) throw;
+ Xapian::ErrorHandler* errorhandler_ = subdb->error_handler;
+ if (!errorhandler_) throw;
LOGLINE(EXCEPTION, "Calling error handler for creation of a SubMatch from a database and query.");
- (*errorhandler)(e);
+ (*errorhandler_)(e);
// Continue match without this sub-postlist.
smatch = NULL;
}
@@ -277,7 +278,7 @@ MultiMatch::MultiMatch(const Xapian::Database &db_,
}
stats.mark_wanted_terms(query);
- prepare_sub_matches(leaves, errorhandler, stats);
+ prepare_sub_matches(leaves, stats, db);
stats.set_bounds_from_db(db);
}
@@ -333,18 +334,20 @@ MultiMatch::get_mset(Xapian::doccount first, Xapian::doccount maxitems,
// Start matchers.
{
vector<intrusive_ptr<SubMatch> >::iterator leaf;
- for (leaf = leaves.begin(); leaf != leaves.end(); ++leaf) {
- if (!(*leaf).get()) continue;
+ for (size_t i = 0; i < leaves.size(); ++i) {
+ if (!(leaves[i]).get()) continue;
try {
- (*leaf)->start_match(0, first + maxitems,
+ (leaves[i])->start_match(0, first + maxitems,
first + check_at_least, stats);
} catch (Xapian::Error & e) {
- if (!errorhandler) throw;
+ // We can only see the parent database
+ Xapian::ErrorHandler* errorhandler_ = db.internal[i]->error_handler;
+ if (!errorhandler_) throw;
LOGLINE(EXCEPTION, "Calling error handler for "
"start_match() on a SubMatch.");
- (*errorhandler)(e);
+ (*errorhandler_)(e);
// Continue match without this sub-match.
- *leaf = NULL;
+ leaves[i] = NULL;
}
}
}
@@ -380,10 +383,11 @@ MultiMatch::get_mset(Xapian::doccount first, Xapian::doccount maxitems,
}
}
} catch (Xapian::Error & e) {
- if (!errorhandler) throw;
+ Xapian::ErrorHandler* errorhandler_ = db.internal[i]->error_handler;
+ if (!errorhandler_) throw;
LOGLINE(EXCEPTION, "Calling error handler for "
"get_term_info() on a SubMatch.");
- (*errorhandler)(e);
+ (*errorhandler_)(e);
// FIXME: check if *ALL* the remote servers have failed!
// Continue match without this sub-match.
leaves[i] = NULL;
@@ -396,13 +400,20 @@ MultiMatch::get_mset(Xapian::doccount first, Xapian::doccount maxitems,
ValueStreamDocument vsdoc(db);
++vsdoc._refs;
Xapian::Document doc(&vsdoc);
+ vector<Xapian::ErrorHandler*>handlers;
+ Xapian::doccount number_of_subdbs = db.internal.size();
+ for (size_t i = 0; i != number_of_subdbs; ++i) {
+ Xapian::Database::Internal *subdb = db.internal[i].get();
+ Assert(subdb);
+ handlers.push_back(subdb->error_handler);
+ }
// Get a single combined postlist
AutoPtr<PostList> pl;
if (postlists.size() == 1) {
pl.reset(postlists.front());
} else {
- pl.reset(new MergePostList(postlists, this, vsdoc, errorhandler));
+ pl.reset(new MergePostList(postlists, this, vsdoc, handlers));
}
LOGLINE(MATCH, "pl = (" << pl->get_description() << ")");
diff --git a/xapian-core/matcher/multimatch.h b/xapian-core/matcher/multimatch.h
index d2ec377..6a9facc 100644
--- a/xapian-core/matcher/multimatch.h
+++ b/xapian-core/matcher/multimatch.h
@@ -57,9 +57,6 @@ class MultiMatch
bool sort_value_forward;
- /// ErrorHandler
- Xapian::ErrorHandler * errorhandler;
-
/// Weighting scheme
const Xapian::Weight * weight;
@@ -93,7 +90,6 @@ class MultiMatch
* @param query The query
* @param qlen The query length
* @param omrset The relevance set (or NULL for no RSet)
- * @param errorhandler Errorhandler object
* @param stats The stats object to add our stats to.
* @param wtscheme Weighting scheme
* @param matchspies_ Any the MatchSpy objects in use.
@@ -112,7 +108,6 @@ class MultiMatch
Xapian::valueno sort_key_,
Xapian::Enquire::Internal::sort_setting sort_by_,
bool sort_value_forward_,
- Xapian::ErrorHandler * errorhandler,
Xapian::Weight::Internal & stats,
const Xapian::Weight *wtscheme,
const vector<Xapian::MatchSpy *> & matchspies_,
diff --git a/xapian-core/net/remoteserver.cc b/xapian-core/net/remoteserver.cc
index b741fc6..f283727 100644
--- a/xapian-core/net/remoteserver.cc
+++ b/xapian-core/net/remoteserver.cc
@@ -459,7 +459,7 @@ RemoteServer::msg_query(const string &message_in)
Xapian::Weight::Internal local_stats;
MultiMatch match(*db, query, qlen, &rset, collapse_max, collapse_key,
percent_cutoff, weight_cutoff, order,
- sort_key, sort_by, sort_value_forward, NULL,
+ sort_key, sort_by, sort_value_forward,
local_stats, wt.get(), matchspies.spies, false, false);
send_message(REPLY_STATS, serialise_stats(local_stats));
diff --git a/xapian-core/tests/api_db.cc b/xapian-core/tests/api_db.cc
index 0fd1e70..7657cf0 100644
--- a/xapian-core/tests/api_db.cc
+++ b/xapian-core/tests/api_db.cc
@@ -241,12 +241,25 @@ class MyErrorHandler : public Xapian::ErrorHandler {
MyErrorHandler() : count (0) {}
};
+DEFINE_TESTCASE(errorhandlerset, backend) {
+ MyErrorHandler myhandler;
+
+ Xapian::Database mydb2(get_database("apitest_simpledata"));
+ Xapian::Database mydb3(get_database("apitest_simpledata2"));
+ Xapian::Database dbs;
+ dbs.add_database(mydb2);
+ dbs.add_database(mydb3);
+
+ dbs.set_error_handler(myhandler);
+}
+
// tests error handler in multimatch().
DEFINE_TESTCASE(multierrhandler1, backend) {
MyErrorHandler myhandler;
Xapian::Database mydb2(get_database("apitest_simpledata"));
Xapian::Database mydb3(get_database("apitest_simpledata2"));
+
int errcount = 1;
for (int testcount = 0; testcount < 14; testcount ++) {
tout << "testcount=" << testcount << "\n";
@@ -332,7 +345,8 @@ DEFINE_TESTCASE(multierrhandler1, backend) {
break;
}
tout << "db=" << dbs << "\n";
- Xapian::Enquire enquire(dbs, &myhandler);
+ dbs.set_error_handler(myhandler);
+ Xapian::Enquire enquire(dbs);
// make a query
Xapian::Query myquery = query(Xapian::Query::OP_OR, "inmemory", "word");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment