summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-06-03 19:38:56 +0000
committerDavid Robillard <d@drobilla.net>2009-06-03 19:38:56 +0000
commit95dd37f9ce4dd49b539d64db40c8477a6a1e3db7 (patch)
treec18f41ed3e1f10fc455975a5b7cbab96ac282bca /src
parent836e92e1202857cc7b42bbbee8dea68cb40131ed (diff)
downloadlilv-95dd37f9ce4dd49b539d64db40c8477a6a1e3db7.tar.gz
lilv-95dd37f9ce4dd49b539d64db40c8477a6a1e3db7.tar.bz2
lilv-95dd37f9ce4dd49b539d64db40c8477a6a1e3db7.zip
Avoid sorting/searching during plugin discovery if results happen to be in order (without actually requesting this with ORDER BY, which can be slower).
This should perform relatively well with any RDF backend, which tend to return sorted results anyway as an implementation detail (and redland with trees does). git-svn-id: http://svn.drobilla.net/lad/trunk/slv2@2081 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/world.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/src/world.c b/src/world.c
index 76751ee..ae9d57f 100644
--- a/src/world.c
+++ b/src/world.c
@@ -517,13 +517,12 @@ slv2_world_load_all(SLV2World world)
slv2_world_load_plugin_classes(world);
// Find all plugins and associated data files
- unsigned char* query_string = (unsigned char*)
+ const unsigned char* query_string = (unsigned char*)
"PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
"PREFIX slv2: <http://drobilla.net/ns/slv2#>\n"
"SELECT DISTINCT ?plugin ?data ?bundle\n"
"WHERE { ?plugin a :Plugin; slv2:bundleURI ?bundle; rdfs:seeAlso ?data }\n";
- //"ORDER BY ?plugin\n";
librdf_query* q = librdf_new_query(world->world, "sparql",
NULL, query_string, NULL);
@@ -531,7 +530,6 @@ slv2_world_load_all(SLV2World world)
librdf_query_results* results = librdf_query_execute(q, world->model);
while (!librdf_query_results_finished(results)) {
-
librdf_node* plugin_node = librdf_query_results_get_binding_value(results, 0);
librdf_uri* plugin_uri = librdf_node_get_uri(plugin_node);
librdf_node* data_node = librdf_query_results_get_binding_value(results, 1);
@@ -539,27 +537,60 @@ slv2_world_load_all(SLV2World world)
librdf_node* bundle_node = librdf_query_results_get_binding_value(results, 2);
librdf_uri* bundle_uri = librdf_node_get_uri(bundle_node);
- assert(plugin_uri);
- assert(data_uri);
+ if (plugin_uri && data_uri) {
+ SLV2Plugin plugin = NULL;
- SLV2Value uri = slv2_value_new_librdf_uri(world, plugin_uri);
- SLV2Plugin plugin = slv2_plugins_get_by_uri(world->plugins, uri);
+ // Check if this is another match for the last plugin (avoid search)
+ const unsigned n_plugins = raptor_sequence_size(world->plugins);
+ if (n_plugins >= 1) {
+ SLV2Plugin prev = raptor_sequence_get_at(world->plugins, n_plugins - 1);
+ if (librdf_uri_equals(plugin_uri, prev->plugin_uri->val.uri_val))
+ plugin = prev;
+ }
- // Create a new SLV2Plugin
- if (!plugin) {
- plugin = slv2_plugin_new(world, uri, bundle_uri);
- raptor_sequence_push(world->plugins, plugin);
- // FIXME: Slow! ORDER BY broken in certain versions of redland?
- raptor_sequence_sort(world->plugins, slv2_plugin_compare_by_uri);
- } else {
- slv2_value_free(uri);
- }
+ SLV2Value uri = slv2_value_new_librdf_uri(world, plugin_uri);
+
+ // If this plugin differs from the last, append a new SLV2Plugin
+ if (!plugin) {
+ if (n_plugins == 0) {
+ plugin = slv2_plugin_new(world, uri, bundle_uri);
+ raptor_sequence_push(world->plugins, plugin);
+ } else {
+ SLV2Plugin first = raptor_sequence_get_at(world->plugins, 0);
+ SLV2Plugin prev = raptor_sequence_get_at(world->plugins, n_plugins - 1);
+
+ // If the URI is > the last in the list, just append (avoid sort)
+ if (strcmp(
+ slv2_value_as_string(slv2_plugin_get_uri(prev)),
+ librdf_uri_as_string(plugin_uri)) < 0) {
+ plugin = slv2_plugin_new(world, uri, bundle_uri);
+ raptor_sequence_push(world->plugins, plugin);
+
+ // If the URI is < the first in the list, just prepend (avoid sort)
+ } else if (strcmp(
+ slv2_value_as_string(slv2_plugin_get_uri(first)),
+ librdf_uri_as_string(plugin_uri)) > 0) {
+ plugin = slv2_plugin_new(world, uri, bundle_uri);
+ raptor_sequence_shift(world->plugins, plugin);
+
+ // Otherwise the query engine is giving us unsorted results :/
+ } else {
+ plugin = slv2_plugins_get_by_uri(world->plugins, uri);
+ if (!plugin) {
+ plugin = slv2_plugin_new(world, uri, bundle_uri);
+ raptor_sequence_push(world->plugins, plugin);
+ raptor_sequence_sort(world->plugins, slv2_plugin_compare_by_uri);
+ }
+ }
+ }
+ }
- plugin->world = world;
+ plugin->world = world;
- // FIXME: check for duplicates
- raptor_sequence_push(plugin->data_uris,
- slv2_value_new_librdf_uri(plugin->world, data_uri));
+ // FIXME: check for duplicates
+ raptor_sequence_push(plugin->data_uris,
+ slv2_value_new_librdf_uri(plugin->world, data_uri));
+ }
librdf_free_node(plugin_node);
librdf_free_node(data_node);