summaryrefslogtreecommitdiffstats
path: root/src/plugin.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-04-19 16:49:25 +0000
committerDavid Robillard <d@drobilla.net>2007-04-19 16:49:25 +0000
commit98ea88b5fd404ff4ba43709f731ba074f291eb5b (patch)
tree1318604ebfedd677ac8f6cbad3f9d58e5922a1c4 /src/plugin.c
parent6626f77037747855e7dcec64697d436c4300d7c2 (diff)
downloadlilv-98ea88b5fd404ff4ba43709f731ba074f291eb5b.tar.gz
lilv-98ea88b5fd404ff4ba43709f731ba074f291eb5b.tar.bz2
lilv-98ea88b5fd404ff4ba43709f731ba074f291eb5b.zip
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
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c242
1 files changed, 198 insertions, 44 deletions
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 <string.h>
#include <stdlib.h>
#include <assert.h>
-#include <rasqal.h>
+#include <librdf.h>
#include <slv2/plugin.h>
#include <slv2/types.h>
#include <slv2/util.h>
@@ -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 : <http://lv2plug.in/ontology#>\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;
+}
+