[Xapian-devel] mutable Query objects

Olly Betts olly at survex.com
Thu Feb 24 16:54:51 GMT 2005


There's a bit of an API glitch with Query objects at present.  This code
shows it off:

	Xapian::Database("/path/to/db");
	Xapian::Enquire enquire(db);

	// make a simple query
	Xapian::Query myquery(Xapian::Query::OP_NEAR, phrase, phrase + 2);
	enquire.set_query(myquery);

	// Now change the query - this shouldn't affect the query enquire
	// will run, but it does.
	myquery.set_window(10);

The essential issue here is that queries are mutable, so
Enquire::set_query() needs to clone the Query object to stop it being
changed behind the scenes.

I can see two fixes for this:

(a) implement a "deep copy" clone for Query objects and use it in
Enquire::set_query()

(b) make Query object immutable by replacing these non-const public
methods with extra constructor parameters:

        void set_window(Xapian::termpos window);
	void set_cutoff(Xapian::weight cutoff);
	void set_elite_set_size(Xapian::termcount size);
	Xapian::termcount set_length(Xapian::termcount qlen);

The private non-const methods are only used during construction, so
they're not a problem.

I tend to favour (b).  The first three are tied to particular OPs
(OP_NEAR/OP_PHRASE, OP_WEIGHT_CUTOFF, and OP_ELITE_SET respectively)
so are perhaps cleaner that way anyway.  The last is more awkward
as a constructor parameter - it would perhaps be better replaced by
an optional parameter to Enquire::set_query().

This is an API change (unlike (a)), but not one which is hard to
update user code for.

I don't have strong objections to (a) - it just seems like overkill
in terms of the amount of coding work required.  But if anyone wants to
volunteer to do that work, you're welcome to...

Cheers,
    Olly




More information about the Xapian-devel mailing list