Created
July 19, 2012 17:01
-
-
Save dcolish/3145318 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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.h b/xapian-core/backends/database.h | |
| index 3d95921..d064816 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> | |
| @@ -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..4b22f36 100644 | |
| --- a/xapian-core/tests/api_db.cc | |
| +++ b/xapian-core/tests/api_db.cc | |
| @@ -247,6 +247,7 @@ DEFINE_TESTCASE(multierrhandler1, backend) { | |
| 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 +333,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"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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.h b/xapian-core/backends/database.h | |
| index 3d95921..d064816 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> | |
| @@ -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..4b22f36 100644 | |
| --- a/xapian-core/tests/api_db.cc | |
| +++ b/xapian-core/tests/api_db.cc | |
| @@ -247,6 +247,7 @@ DEFINE_TESTCASE(multierrhandler1, backend) { | |
| 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 +333,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