From 98ea88b5fd404ff4ba43709f731ba074f291eb5b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 19 Apr 2007 16:49:25 +0000 Subject: Added Redland dependency, using in-memory RDF models. Numerous significant performance improvements. git-svn-id: http://svn.drobilla.net/lad/slv2@457 a436a847-0d15-0410-975c-d299462d15a1 --- src/plugin.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 198 insertions(+), 44 deletions(-) (limited to 'src/plugin.c') diff --git a/src/plugin.c b/src/plugin.c index abb577b..ab36caf 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -29,8 +29,54 @@ #include "private_types.h" +/* private */ +SLV2Plugin +slv2_plugin_new(SLV2Model model, librdf_uri* uri, const char* binary_uri) +{ + struct _Plugin* plugin = malloc(sizeof(struct _Plugin)); + plugin->model = model; + plugin->plugin_uri = librdf_new_uri_from_uri(uri); + plugin->binary_uri = strdup(binary_uri); + plugin->data_uris = raptor_new_sequence((void (*)(void*))&raptor_free_uri, NULL); + plugin->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL); + plugin->storage = NULL; + plugin->rdf = NULL; + + return plugin; +} + + +/* private */ +void +slv2_plugin_free(SLV2Plugin p) +{ + librdf_free_uri(p->plugin_uri); + p->plugin_uri = NULL; + + //free(p->bundle_url); + free(p->binary_uri); + + raptor_free_sequence(p->ports); + p->ports = NULL; + + if (p->rdf) { + librdf_free_model(p->rdf); + p->rdf = NULL; + } + + if (p->storage) { + librdf_free_storage(p->storage); + p->storage = NULL; + } + + raptor_free_sequence(p->data_uris); + + free(p); +} + + // FIXME: ew -rasqal_query_results* +librdf_query_results* slv2_plugin_query(SLV2Plugin plugin, const char* sparql_str); @@ -38,42 +84,127 @@ slv2_plugin_query(SLV2Plugin plugin, SLV2Plugin slv2_plugin_duplicate(SLV2Plugin p) { + fprintf(stderr, "FIXME: duplicate\n"); + assert(p); struct _Plugin* result = malloc(sizeof(struct _Plugin)); - result->plugin_uri = strdup(p->plugin_uri); - result->bundle_url = strdup(p->bundle_url); - result->lib_uri = strdup(p->lib_uri); + result->model = p->model; + result->plugin_uri = librdf_new_uri_from_uri(p->plugin_uri); + + //result->bundle_url = strdup(p->bundle_url); + result->binary_uri = strdup(p->binary_uri); result->data_uris = slv2_strings_new(); for (unsigned i=0; i < slv2_strings_size(p->data_uris); ++i) raptor_sequence_push(result->data_uris, strdup(slv2_strings_get_at(p->data_uris, i))); + + result->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL); + for (int i=0; i < raptor_sequence_size(p->ports); ++i) + raptor_sequence_push(result->ports, slv2_port_duplicate(raptor_sequence_get_at(p->ports, i))); + + result->ports = NULL; + result->storage = NULL; + result->rdf = NULL; + return result; } +/** comparator for sorting */ +int +slv2_port_compare_by_index(const void* a, const void* b) +{ + SLV2Port port_a = *(SLV2Port*)a; + SLV2Port port_b = *(SLV2Port*)b; + + if (port_a->index < port_b->index) + return -1; + else if (port_a->index == port_b->index) + return 0; + else //if (port_a->index > port_b->index) + return 1; +} + + void -slv2_plugin_free(SLV2Plugin p) +slv2_plugin_load(SLV2Plugin p) { - free(p->plugin_uri); - free(p->bundle_url); - free(p->lib_uri); - slv2_strings_free(p->data_uris); - free(p); + //printf("Loading cache for %s\n", (const char*)librdf_uri_as_string(p->plugin_uri)); + + if (!p->storage) { + assert(!p->rdf); + p->storage = librdf_new_storage(p->model->world, "hashes", NULL, + "hash-type='memory'"); + p->rdf = librdf_new_model(p->model->world, p->storage, NULL); + } + + // Parse all the plugin's data files into RDF model + for (int i=0; i < raptor_sequence_size(p->data_uris); ++i) { + librdf_uri* data_uri = raptor_sequence_get_at(p->data_uris, i); + librdf_parser_parse_into_model(p->model->parser, data_uri, NULL, p->rdf); + } + + // Load ports + const unsigned char* query = (const unsigned char*) + "PREFIX : \n" + "SELECT DISTINCT ?port ?symbol ?index WHERE {\n" + "<> :port ?port .\n" + "?port :symbol ?symbol ;\n" + " :index ?index .\n" + "}"; + + librdf_query* q = librdf_new_query(p->model->world, "sparql", + NULL, query, p->plugin_uri); + + librdf_query_results* results = librdf_query_execute(q, p->rdf); + + while (!librdf_query_results_finished(results)) { + + //librdf_node* port_node = librdf_query_results_get_binding_value(results, 0); + librdf_node* symbol_node = librdf_query_results_get_binding_value(results, 1); + librdf_node* index_node = librdf_query_results_get_binding_value(results, 2); + + //assert(librdf_node_is_blank(port_node)); + assert(librdf_node_is_literal(symbol_node)); + assert(librdf_node_is_literal(index_node)); + + //const char* id = (const char*)librdf_node_get_blank_identifier(port_node); + const char* symbol = (const char*)librdf_node_get_literal_value(symbol_node); + const char* index = (const char*)librdf_node_get_literal_value(index_node); + + //printf("%s: PORT: %s %s\n", p->plugin_uri, index, symbol); + + // Create a new SLV2Port + SLV2Port port = slv2_port_new((unsigned)atoi(index), symbol); + raptor_sequence_push(p->ports, port); + + librdf_free_node(symbol_node); + librdf_free_node(index_node); + + librdf_query_results_next(results); + } + + raptor_sequence_sort(p->ports, slv2_port_compare_by_index); + + if (results) + librdf_free_query_results(results); + + librdf_free_query(q); + + //printf("%p %s: NUM PORTS: %d\n", (void*)p, p->plugin_uri, slv2_plugin_get_num_ports(p)); } const char* slv2_plugin_get_uri(SLV2Plugin p) { - assert(p); - return p->plugin_uri; + return (const char*)librdf_uri_as_string(p->plugin_uri); } SLV2Strings slv2_plugin_get_data_uris(SLV2Plugin p) { - assert(p); return p->data_uris; } @@ -81,8 +212,7 @@ slv2_plugin_get_data_uris(SLV2Plugin p) const char* slv2_plugin_get_library_uri(SLV2Plugin p) { - assert(p); - return p->lib_uri; + return p->binary_uri; } @@ -91,42 +221,47 @@ slv2_plugin_verify(SLV2Plugin plugin) { char* query_str = "SELECT DISTINCT ?type ?name ?license ?port WHERE {\n" - "plugin: a ?type ;\n" + "<> a ?type ;\n" "doap:name ?name ;\n" "doap:license ?license ;\n" "lv2:port [ lv2:index ?port ] .\n}"; - rasqal_query_results* results = slv2_plugin_query(plugin, query_str); + librdf_query_results* results = slv2_plugin_query(plugin, query_str); bool has_type = false; bool has_name = false; bool has_license = false; bool has_port = false; - while (!rasqal_query_results_finished(results)) { - rasqal_literal* literal = rasqal_query_results_get_binding_value(results, 0); - const char* const type = (const char*)rasqal_literal_as_string(literal); - literal = rasqal_query_results_get_binding_value(results, 1); - const char* const name = (const char*)rasqal_literal_as_string(literal); - rasqal_literal* license = rasqal_query_results_get_binding_value(results, 2); - rasqal_literal* port = rasqal_query_results_get_binding_value(results, 3); + while (!librdf_query_results_finished(results)) { + librdf_node* type_node = librdf_query_results_get_binding_value(results, 0); + const char* const type_str = (const char*)librdf_node_get_literal_value(type_node); + librdf_node* name_node = librdf_query_results_get_binding_value(results, 1); + //const char* const name = (const char*)librdf_node_get_literal_value(name_node); + librdf_node* license_node = librdf_query_results_get_binding_value(results, 2); + librdf_node* port_node = librdf_query_results_get_binding_value(results, 3); - if (!strcmp(type, "http://lv2plug.in/ontology#Plugin")) + if (!strcmp(type_str, "http://lv2plug.in/ontology#Plugin")) has_type = true; - if (name) + if (name_node) has_name = true; - if (license) + if (license_node) has_license = true; - if (port) + if (port_node) has_port = true; - rasqal_query_results_next(results); + librdf_free_node(type_node); + librdf_free_node(name_node); + librdf_free_node(license_node); + librdf_free_node(port_node); + + librdf_query_results_next(results); } - rasqal_free_query_results(results); + librdf_free_query_results(results); if ( ! (has_type && has_name && has_license && has_port) ) { fprintf(stderr, "Invalid LV2 Plugin %s\n", slv2_plugin_get_uri(plugin)); @@ -161,8 +296,8 @@ slv2_plugin_get_value(SLV2Plugin p, assert(predicate); char* query = slv2_strjoin( - "SELECT DISTINCT ?value WHERE {\n" - "plugin: ", predicate, " ?value .\n" + "SELECT DISTINCT ?value WHERE {" + "<> ", predicate, " ?value .\n" "}\n", NULL); SLV2Strings result = slv2_plugin_simple_query(p, query, "value"); @@ -210,11 +345,7 @@ slv2_plugin_get_hints(SLV2Plugin p) uint32_t slv2_plugin_get_num_ports(SLV2Plugin p) { - const char* const query = - "SELECT DISTINCT ?port\n" - "WHERE { plugin: lv2:port ?port }\n"; - - return (uint32_t)slv2_plugin_query_count(p, query); + return raptor_sequence_size(p->ports); } @@ -223,7 +354,7 @@ slv2_plugin_has_latency(SLV2Plugin p) { const char* const query = "SELECT DISTINCT ?port WHERE {\n" - " plugin: lv2:port ?port .\n" + " <> lv2:port ?port .\n" " ?port lv2:portHint lv2:reportsLatency .\n" "}\n"; @@ -242,7 +373,7 @@ slv2_plugin_get_latency_port(SLV2Plugin p) { const char* const query = "SELECT DISTINCT ?value WHERE {\n" - " plugin: lv2:port ?port .\n" + " <> lv2:port ?port .\n" " ?port lv2:portHint lv2:reportsLatency ;\n" " lv2:index ?index .\n" "}\n"; @@ -264,9 +395,9 @@ slv2_plugin_get_supported_features(SLV2Plugin p) { const char* const query = "SELECT DISTINCT ?feature WHERE {\n" - " { plugin: lv2:optionalHostFeature ?feature }\n" + " { <> lv2:optionalHostFeature ?feature }\n" " UNION\n" - " { plugin: lv2:requiredHostFeature ?feature }\n" + " { <> lv2:requiredHostFeature ?feature }\n" "}\n"; SLV2Strings result = slv2_plugin_simple_query(p, query, "feature"); @@ -280,7 +411,7 @@ slv2_plugin_get_optional_features(SLV2Plugin p) { const char* const query = "SELECT DISTINCT ?feature WHERE {\n" - " plugin: lv2:optionalHostFeature ?feature .\n" + " <> lv2:optionalHostFeature ?feature .\n" "}\n"; SLV2Strings result = slv2_plugin_simple_query(p, query, "feature"); @@ -294,7 +425,7 @@ slv2_plugin_get_required_features(SLV2Plugin p) { const char* const query = "SELECT DISTINCT ?feature WHERE {\n" - " plugin: lv2:requiredHostFeature ?feature .\n" + " <> lv2:requiredHostFeature ?feature .\n" "}\n"; SLV2Strings result = slv2_plugin_simple_query(p, query, "feature"); @@ -302,3 +433,26 @@ slv2_plugin_get_required_features(SLV2Plugin p) return result; } + +SLV2Port +slv2_plugin_get_port_by_index(SLV2Plugin p, + uint32_t index) +{ + return raptor_sequence_get_at(p->ports, (int)index); +} + + +SLV2Port +slv2_plugin_get_port_by_symbol(SLV2Plugin p, + const char* symbol) +{ + // FIXME: sort plugins and do a binary search + for (int i=0; i < raptor_sequence_size(p->ports); ++i) { + SLV2Port port = raptor_sequence_get_at(p->ports, i); + if (!strcmp(port->symbol, symbol)) + return port; + } + + return NULL; +} + -- cgit v1.2.1