|
@@ -16,22 +16,16 @@ typedef struct Keyset {
|
|
|
size_t free_i;
|
|
|
} Keyset;
|
|
|
|
|
|
-struct IndexEntry {
|
|
|
+typedef struct IndexEntry {
|
|
|
LSUP_Key key;
|
|
|
LSUP_SerTerm *val;
|
|
|
-};
|
|
|
-
|
|
|
-typedef struct Index {
|
|
|
- size_t free_i;
|
|
|
- size_t capacity;
|
|
|
- struct IndexEntry *entries;
|
|
|
-} Index;
|
|
|
+} IndexEntry;
|
|
|
|
|
|
typedef struct Graph {
|
|
|
LSUP_store_type store_type;
|
|
|
Keyset *keys;
|
|
|
LSUP_Term *uri;
|
|
|
- Index *idx;
|
|
|
+ struct Index *idx;
|
|
|
} Graph;
|
|
|
|
|
|
|
|
@@ -252,92 +246,6 @@ static void keyset_free(Keyset *ks)
|
|
|
}
|
|
|
|
|
|
|
|
|
-/* * * INDEX * * */
|
|
|
-
|
|
|
-static Index *index_new(size_t capacity)
|
|
|
-{
|
|
|
- Index *idx = malloc(sizeof(struct Index));
|
|
|
-
|
|
|
- if (capacity == 0) return NULL;
|
|
|
-
|
|
|
- CRITICAL (idx->entries = malloc(sizeof(struct IndexEntry) * capacity));
|
|
|
-
|
|
|
- idx->free_i = 0;
|
|
|
- idx->capacity = capacity;
|
|
|
-
|
|
|
- return idx;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void index_resize(Index *idx, size_t capacity)
|
|
|
-{
|
|
|
- CRITICAL (idx->entries = (struct IndexEntry*)realloc(
|
|
|
- idx->entries,
|
|
|
- sizeof(struct IndexEntry) * capacity));
|
|
|
-
|
|
|
- idx->capacity = capacity;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static LSUP_SerTerm *index_lookup(Index *idx, LSUP_Key key)
|
|
|
-{
|
|
|
- LSUP_SerTerm *match = NULL;
|
|
|
-
|
|
|
- for (size_t i = 0; i < idx->free_i; i++) {
|
|
|
- if (idx->entries[i].key == key) {
|
|
|
- match = idx->entries[i].val;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return match;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int index_add_pair(Index *idx, LSUP_Key key, LSUP_SerTerm *sterm)
|
|
|
-{
|
|
|
- // Fail quietly if key exists already.
|
|
|
- if (index_lookup(idx, key) == NULL) {
|
|
|
- if (idx->free_i >= idx->capacity) {
|
|
|
- index_resize(idx, idx->capacity * 1.5);
|
|
|
- TRACE("Capacity now at %lu\n", idx->capacity);
|
|
|
- }
|
|
|
-
|
|
|
- struct IndexEntry *entry = idx->entries + idx->free_i;
|
|
|
-
|
|
|
- entry->key = key;
|
|
|
- entry->val = LSUP_buffer_new(sterm->size);
|
|
|
- memcpy(entry->val->addr, sterm->addr, sterm->size);
|
|
|
-
|
|
|
- idx->free_i ++;
|
|
|
- // TRACE("Size now at %lu\n", idx->free_i);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return LSUP_OK;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int index_add(Index *idx, LSUP_SerTerm *sterm)
|
|
|
-{
|
|
|
- LSUP_Key key = LSUP_sterm_to_key(sterm);
|
|
|
-
|
|
|
- return index_add_pair(idx, key, sterm);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void index_free(Index *idx)
|
|
|
-{
|
|
|
- for (size_t i = 0; i < idx->free_i; i++) {
|
|
|
- LSUP_buffer_done(idx->entries[i].val);
|
|
|
- free(idx->entries[i].val);
|
|
|
- }
|
|
|
-
|
|
|
- free(idx->entries);
|
|
|
- free(idx);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
/* * * GRAPH * * */
|
|
|
|
|
|
int
|
|
@@ -357,7 +265,7 @@ LSUP_graph_init(
|
|
|
|
|
|
switch (store_type ) {
|
|
|
case LSUP_STORE_MEM:
|
|
|
- gr->idx = index_new(gr->keys->capacity);
|
|
|
+ gr->idx = idx_new(gr->keys->capacity, 0.8, &idx_fkey, &idx_fval);
|
|
|
break;
|
|
|
|
|
|
case LSUP_STORE_MDB:
|
|
@@ -421,6 +329,38 @@ size_t
|
|
|
LSUP_graph_size(LSUP_Graph *gr) { return gr->keys->free_i; }
|
|
|
|
|
|
|
|
|
+int
|
|
|
+LSUP_graph_add_triple(LSUP_Graph *gr, const LSUP_Triple *spo)
|
|
|
+{
|
|
|
+ LSUP_SerTerm sspo[3];
|
|
|
+
|
|
|
+ LSUP_term_serialize(spo->s, sspo);
|
|
|
+ LSUP_term_serialize(spo->p, sspo + 1);
|
|
|
+ LSUP_term_serialize(spo->o, sspo + 2);
|
|
|
+
|
|
|
+ LSUP_Key sk = LSUP_sterm_to_key(sspo);
|
|
|
+ LSUP_Key pk = LSUP_sterm_to_key(sspo + 1);
|
|
|
+ LSUP_Key ok = LSUP_sterm_to_key(sspo + 2);
|
|
|
+
|
|
|
+ // Add terms to index.
|
|
|
+ // TODO Optimize. This copies sterm data twice: once to serialize,
|
|
|
+ // once to add to index.
|
|
|
+ idx_insert(gr->idx, sk, sspo);
|
|
|
+ idx_insert(gr->idx, pk, sspo + 1);
|
|
|
+ idx_insert(gr->idx, ok, sspo + 2);
|
|
|
+
|
|
|
+ LSUP_buffer_done(sspo);
|
|
|
+ LSUP_buffer_done(sspo + 1);
|
|
|
+ LSUP_buffer_done(sspo + 2);
|
|
|
+
|
|
|
+ // Add triple.
|
|
|
+ LSUP_TripleKey spok = {sk, pk, ok};
|
|
|
+ keyset_add(gr->keys, &spok, LSUP_KS_CHECK_DUP);
|
|
|
+
|
|
|
+ return LSUP_OK;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
int
|
|
|
LSUP_graph_add(LSUP_Graph *gr, const LSUP_Triple data[], size_t data_size)
|
|
|
{
|
|
@@ -431,30 +371,7 @@ LSUP_graph_add(LSUP_Graph *gr, const LSUP_Triple data[], size_t data_size)
|
|
|
keyset_resize(gr->keys, gr->keys->free_i + data_size);
|
|
|
|
|
|
for (size_t i = 0; i < data_size; i++) {
|
|
|
- LSUP_SerTerm sspo[3];
|
|
|
-
|
|
|
- LSUP_term_serialize(data[i].s, sspo);
|
|
|
- LSUP_term_serialize(data[i].p, sspo + 1);
|
|
|
- LSUP_term_serialize(data[i].o, sspo + 2);
|
|
|
-
|
|
|
- LSUP_Key sk = LSUP_sterm_to_key(sspo);
|
|
|
- LSUP_Key pk = LSUP_sterm_to_key(sspo + 1);
|
|
|
- LSUP_Key ok = LSUP_sterm_to_key(sspo + 2);
|
|
|
-
|
|
|
- // Add terms to index.
|
|
|
- // TODO Optimize. This copies sterm data twice: once to serialize,
|
|
|
- // once to add to index.
|
|
|
- index_add_pair(gr->idx, sk, sspo);
|
|
|
- index_add_pair(gr->idx, pk, sspo + 1);
|
|
|
- index_add_pair(gr->idx, ok, sspo + 2);
|
|
|
-
|
|
|
- LSUP_buffer_done(sspo);
|
|
|
- LSUP_buffer_done(sspo + 1);
|
|
|
- LSUP_buffer_done(sspo + 2);
|
|
|
-
|
|
|
- // Add triple.
|
|
|
- LSUP_TripleKey trp = {sk, pk, ok};
|
|
|
- keyset_add(gr->keys, &trp, LSUP_KS_CHECK_DUP);
|
|
|
+ LSUP_graph_add_triple(gr, data + i);
|
|
|
}
|
|
|
|
|
|
return LSUP_OK;
|
|
@@ -653,7 +570,7 @@ LSUP_graph_free(LSUP_Graph *gr)
|
|
|
if (LIKELY(gr != NULL)) {
|
|
|
LSUP_term_free(gr->uri);
|
|
|
keyset_free(gr->keys);
|
|
|
- index_free(gr->idx);
|
|
|
+ idx_free(gr->idx);
|
|
|
free(gr);
|
|
|
}
|
|
|
}
|
|
@@ -677,12 +594,9 @@ int match_add_fn(LSUP_Graph *src, LSUP_Graph *dest, void *ctx)
|
|
|
|
|
|
memcpy(dest->keys->data + dest->keys->free_i, spok, TRP_KLEN);
|
|
|
|
|
|
- index_add_pair(
|
|
|
- src->idx, *spok[0], index_lookup(src->idx, *spok[0]));
|
|
|
- index_add_pair(
|
|
|
- src->idx, *spok[1], index_lookup(src->idx, *spok[1]));
|
|
|
- index_add_pair(
|
|
|
- src->idx, *spok[2], index_lookup(src->idx, *spok[2]));
|
|
|
+ idx_insert(dest->idx, *spok[0], idx_get(src->idx, *spok[0]));
|
|
|
+ idx_insert(dest->idx, *spok[1], idx_get(src->idx, *spok[1]));
|
|
|
+ idx_insert(dest->idx, *spok[2], idx_get(src->idx, *spok[2]));
|
|
|
|
|
|
dest->keys->cur = dest->keys->free_i;
|
|
|
dest->keys->free_i ++;
|