Skip to content

Instantly share code, notes, and snippets.

@dcolish
Created July 26, 2012 15:28
Show Gist options
  • Select an option

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

Select an option

Save dcolish/3182713 to your computer and use it in GitHub Desktop.
diff --git a/xapian-core/matcher/multimatch.cc b/xapian-core/matcher/multimatch.cc
index 654908a..f3acb28 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,19 @@ 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;
+ 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;
}
}
}
@@ -364,6 +366,7 @@ MultiMatch::get_mset(Xapian::doccount first, Xapian::doccount maxitems,
for (size_t i = 0; i != leaves.size(); ++i) {
PostList *pl;
try {
+ if (!leaves[i].get()) throw Xapian::UnimplementedError("Cannot match on NULL leaf");
pl = leaves[i]->get_postlist_and_term_info(this,
termfreqandwts_ptr,
&total_subqs);
@@ -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() << ")");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment