He's not dead, he's resting
New Paludis Query Interface
Paludis trunk will be getting a new query interface shortly. This will replace the old interface (we’re not keeping API stability until 1.0), so you’ll need to change your code — fortunately, the compiler will tell you where.
Code that used to look like this:
env.package_database()->query( query::Matches(blah) & query::SupportsAction<InstallAction>(), qo_order_by_version);
will now look like:
env[selection::AllVersionsSorted( generator::Matches(blah) | filter::SupportsAction<InstallAction>())];
- Querying is now done by
PackageDatabase. This makes trickery with
QueryOrderenum is gone, replaced with
Queryclass is gone, replaced by
Selection subclasses substantially reduce the amount of work done to get a result in certain circumstances. Previously, a full set of results would be generated, and then that set would be sorted and reduced as specified. But in certain fairly common situations, this is overkill. Consider this old snippet:
if (env.package_database()->query(query::Matches(spec), qo_whatever)->empty()) /* ... */
This will return an entire set of
PackageID instances, but all we really care about is whether at least one match was found. If spec is something simple, the overhead is minimal. But if spec contains slot dependencies, it means loading or generating metadata for every single matching ID, which is either slow (a metadata load is a filesystem access) or really really slow (a metadata generation is a bash invocation).
Now we do this instead:
if (env[selection::SomeArbitraryVersion(generator::Matches(spec))]->empty()) /* ... */
selection::SomeArbitraryVersion is smart enough to stop trying the match as soon as it finds at least one match. (In future, we might even let IDs state the relative cost of doing such a metadata query, so we can try matching IDs whose metadata is already loaded first.)
Filter split enables a related optimisation. Given the following (which is slightly unrealistic, because there should really be an ‘installable’ check in there too):
env.package_database()->query( query::Matches(blah) & query::NotMasked(), qo_order_by_version);
query::NotMasked() would get called for all IDs whose name could potentially match the
query::Matches(blah) spec. So if you asked for
>=app-misc/foo-3, all versions of
app-misc/foo would be checked for whether they’re masked — and a mask check requires metadata.
But with the new code:
env[selection::AllVersionsSorted( generator::Matches(blah) | filter::NotMasked()];
only those IDs that really do match will be queried for maskedness. And if that’s combined with a smarter selection:
env[selection::BestVersionOnly( generator::Matches(blah) | filter::NotMasked()];
then Paludis is now smart enough to start with the best version matching blah and work downwards until it finds a not masked version.
In Part II, we discuss available components and how they can be combined.