From 95dd37f9ce4dd49b539d64db40c8477a6a1e3db7 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 3 Jun 2009 19:38:56 +0000 Subject: 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 --- src/world.c | 71 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 20 deletions(-) (limited to 'src') 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 : \n" "PREFIX rdfs: \n" "PREFIX 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); -- cgit v1.2.1