|
@@ -35,14 +35,14 @@ typedef struct ht_iterator_t {
|
|
LSUP_Key luk[3]; // 0÷3 lookup keys.
|
|
LSUP_Key luk[3]; // 0÷3 lookup keys.
|
|
LSUP_key_eq_fn_t eq_fn; // Equality function to test triples.
|
|
LSUP_key_eq_fn_t eq_fn; // Equality function to test triples.
|
|
int rc; // Return code for *next* result.
|
|
int rc; // Return code for *next* result.
|
|
- TripleEntry * bucket; // Retrieved SPO key bucket.
|
|
|
|
|
|
+ TripleEntry * entry; // Retrieved SPO key.
|
|
} HTIterator;
|
|
} HTIterator;
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* Identity hashing function.
|
|
* Identity hashing function.
|
|
*
|
|
*
|
|
- * Since the key is already a strong hash, reuse it for bucket allocation.
|
|
|
|
|
|
+ * Since the key is already a strong hash, reuse it for entry allocation.
|
|
*/
|
|
*/
|
|
//#define HASH_FUNCTION (s,len,hashv) (hashv) = (unsigned)(s)
|
|
//#define HASH_FUNCTION (s,len,hashv) (hashv) = (unsigned)(s)
|
|
|
|
|
|
@@ -97,6 +97,13 @@ static bool lookup_pok_eq_fn(
|
|
const LSUP_Key spok[], const LSUP_Key luk[])
|
|
const LSUP_Key spok[], const LSUP_Key luk[])
|
|
{ return spok[1] == luk[0] && spok[2] == luk[1]; }
|
|
{ return spok[1] == luk[0] && spok[2] == luk[1]; }
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Keyset lookup for S, P and O keys.
|
|
|
|
+ */
|
|
|
|
+static bool lookup_spok_eq_fn(
|
|
|
|
+ const LSUP_Key spok[], const LSUP_Key luk[])
|
|
|
|
+{ return spok[0] == luk[0] && spok[1] == luk[1] && spok[2] == luk[2]; }
|
|
|
|
+
|
|
|
|
|
|
/* * * Other prototypes. * * */
|
|
/* * * Other prototypes. * * */
|
|
|
|
|
|
@@ -109,8 +116,8 @@ static inline LSUP_rc tkey_to_strp (
|
|
HTStore *
|
|
HTStore *
|
|
LSUP_htstore_new (void)
|
|
LSUP_htstore_new (void)
|
|
{
|
|
{
|
|
- HTStore *ht = malloc (sizeof (*ht));
|
|
|
|
- if (UNLIKELY (!ht)) return NULL;
|
|
|
|
|
|
+ HTStore *ht;
|
|
|
|
+ MALLOC_GUARD (ht, NULL);
|
|
|
|
|
|
ht->keys = NULL;
|
|
ht->keys = NULL;
|
|
ht->idx = NULL;
|
|
ht->idx = NULL;
|
|
@@ -251,9 +258,12 @@ void
|
|
LSUP_htstore_free (HTStore *ht)
|
|
LSUP_htstore_free (HTStore *ht)
|
|
{
|
|
{
|
|
IndexEntry *idx_entry, *idx_tmp;
|
|
IndexEntry *idx_entry, *idx_tmp;
|
|
|
|
+ size_t ct = 0;
|
|
HASH_ITER (hh, ht->idx, idx_entry, idx_tmp) {
|
|
HASH_ITER (hh, ht->idx, idx_entry, idx_tmp) {
|
|
HASH_DEL (ht->idx, idx_entry);
|
|
HASH_DEL (ht->idx, idx_entry);
|
|
|
|
+ LSUP_buffer_free (idx_entry->sterm);
|
|
free (idx_entry);
|
|
free (idx_entry);
|
|
|
|
+ ct++;
|
|
}
|
|
}
|
|
|
|
|
|
TripleEntry *trp_entry, *trp_tmp;
|
|
TripleEntry *trp_entry, *trp_tmp;
|
|
@@ -274,8 +284,8 @@ LSUP_htstore_size (LSUP_HTStore *ht)
|
|
LSUP_HTIterator *
|
|
LSUP_HTIterator *
|
|
LSUP_htstore_add_init (HTStore *store)
|
|
LSUP_htstore_add_init (HTStore *store)
|
|
{
|
|
{
|
|
- HTIterator *it = malloc (sizeof (HTIterator));
|
|
|
|
- if (UNLIKELY (!it)) return NULL;
|
|
|
|
|
|
+ HTIterator *it;
|
|
|
|
+ MALLOC_GUARD (it, NULL);
|
|
|
|
|
|
it->store = store;
|
|
it->store = store;
|
|
it->i = 0;
|
|
it->i = 0;
|
|
@@ -299,31 +309,31 @@ LSUP_htstore_add_iter (HTIterator *it, const LSUP_SerTriple *sspo)
|
|
TripleEntry *k_ins = NULL;
|
|
TripleEntry *k_ins = NULL;
|
|
HASH_FIND (hh, it->store->keys, spok, TRP_KLEN, k_ins);
|
|
HASH_FIND (hh, it->store->keys, spok, TRP_KLEN, k_ins);
|
|
if (k_ins == NULL) {
|
|
if (k_ins == NULL) {
|
|
- TRACE (STR, "Triple not found, inserting.\n");
|
|
|
|
- k_ins = malloc (sizeof (*k_ins));
|
|
|
|
- if (UNLIKELY (!k_ins)) return LSUP_MEM_ERR;
|
|
|
|
|
|
+ TRACE (STR, "Triple not found, inserting.");
|
|
|
|
+ MALLOC_GUARD (k_ins, LSUP_MEM_ERR);
|
|
|
|
|
|
memcpy (k_ins->key, spok, TRP_KLEN);
|
|
memcpy (k_ins->key, spok, TRP_KLEN);
|
|
HASH_ADD (hh, it->store->keys, key, TRP_KLEN, k_ins);
|
|
HASH_ADD (hh, it->store->keys, key, TRP_KLEN, k_ins);
|
|
|
|
|
|
it->i++;
|
|
it->i++;
|
|
} else {
|
|
} else {
|
|
- TRACE (STR, "Triple found. Skipping.\n");
|
|
|
|
|
|
+ TRACE (STR, "Triple found. Skipping.");
|
|
return LSUP_NOACTION;
|
|
return LSUP_NOACTION;
|
|
}
|
|
}
|
|
|
|
|
|
// Add terms to index.
|
|
// Add terms to index.
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int i = 0; i < 3; i++) {
|
|
spok[i] = LSUP_buffer_hash (LSUP_striple_pos (sspo, i));
|
|
spok[i] = LSUP_buffer_hash (LSUP_striple_pos (sspo, i));
|
|
- TRACE ("Indexing term key %lx\n", spok[i]);
|
|
|
|
|
|
+ //TRACE ("Indexing term key %lx\n", spok[i]);
|
|
|
|
|
|
IndexEntry *ins = NULL;
|
|
IndexEntry *ins = NULL;
|
|
HASH_FIND (hh, it->store->idx, spok + i, KLEN, ins);
|
|
HASH_FIND (hh, it->store->idx, spok + i, KLEN, ins);
|
|
if (ins == NULL) {
|
|
if (ins == NULL) {
|
|
- ins = malloc (sizeof (*ins));
|
|
|
|
- if (UNLIKELY (!ins)) return LSUP_MEM_ERR;
|
|
|
|
|
|
+ MALLOC_GUARD (ins, LSUP_MEM_ERR);
|
|
ins->key = spok[i];
|
|
ins->key = spok[i];
|
|
- ins->sterm = LSUP_striple_pos (sspo, i);
|
|
|
|
|
|
+ ins->sterm = LSUP_buffer_new (
|
|
|
|
+ (LSUP_striple_pos (sspo, i))->size,
|
|
|
|
+ (LSUP_striple_pos (sspo, i))->addr);
|
|
HASH_ADD (hh, it->store->idx, key, KLEN, ins);
|
|
HASH_ADD (hh, it->store->idx, key, KLEN, ins);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -334,7 +344,7 @@ LSUP_htstore_add_iter (HTIterator *it, const LSUP_SerTriple *sspo)
|
|
|
|
|
|
void
|
|
void
|
|
LSUP_htstore_add_done (HTIterator *it)
|
|
LSUP_htstore_add_done (HTIterator *it)
|
|
-{ free (it); }
|
|
|
|
|
|
+{ LSUP_htiter_free (it); }
|
|
|
|
|
|
|
|
|
|
LSUP_rc
|
|
LSUP_rc
|
|
@@ -347,10 +357,10 @@ LSUP_htstore_remove(
|
|
*ct = 0;
|
|
*ct = 0;
|
|
|
|
|
|
TripleEntry *tmp = malloc (sizeof (*tmp));
|
|
TripleEntry *tmp = malloc (sizeof (*tmp));
|
|
- HASH_ITER (hh, store->keys, it->bucket, tmp) {
|
|
|
|
- if (it->eq_fn (it->bucket->key, it->luk)) {
|
|
|
|
- HASH_DEL (store->keys, it->bucket);
|
|
|
|
- free (it->bucket);
|
|
|
|
|
|
+ HASH_ITER (hh, store->keys, it->entry, tmp) {
|
|
|
|
+ if (it->eq_fn (it->entry->key, it->luk)) {
|
|
|
|
+ HASH_DEL (store->keys, it->entry);
|
|
|
|
+ free (it->entry);
|
|
|
|
|
|
(*ct)++;
|
|
(*ct)++;
|
|
}
|
|
}
|
|
@@ -365,8 +375,8 @@ LSUP_htstore_remove(
|
|
HTIterator *
|
|
HTIterator *
|
|
LSUP_htstore_lookup (HTStore *store, const LSUP_SerTriple *sspo)
|
|
LSUP_htstore_lookup (HTStore *store, const LSUP_SerTriple *sspo)
|
|
{
|
|
{
|
|
- HTIterator *it = malloc (sizeof (*it));
|
|
|
|
- if (UNLIKELY (!it)) return NULL;
|
|
|
|
|
|
+ HTIterator *it;
|
|
|
|
+ MALLOC_GUARD (it, NULL);
|
|
|
|
|
|
it->store = store;
|
|
it->store = store;
|
|
//it->cur = 0;
|
|
//it->cur = 0;
|
|
@@ -383,7 +393,7 @@ LSUP_htstore_lookup (HTStore *store, const LSUP_SerTriple *sspo)
|
|
// s p o
|
|
// s p o
|
|
if (spok[0] != NULL_KEY && spok[1] != NULL_KEY && spok[2] != NULL_KEY) {
|
|
if (spok[0] != NULL_KEY && spok[1] != NULL_KEY && spok[2] != NULL_KEY) {
|
|
memcpy (it->luk, spok, sizeof (LSUP_TripleKey));
|
|
memcpy (it->luk, spok, sizeof (LSUP_TripleKey));
|
|
- it->eq_fn = NULL;
|
|
|
|
|
|
+ it->eq_fn = lookup_spok_eq_fn;
|
|
|
|
|
|
} else if (spok[0] != NULL_KEY) {
|
|
} else if (spok[0] != NULL_KEY) {
|
|
it->luk[0] = spok[0];
|
|
it->luk[0] = spok[0];
|
|
@@ -423,8 +433,8 @@ LSUP_htstore_lookup (HTStore *store, const LSUP_SerTriple *sspo)
|
|
// ? ? ?
|
|
// ? ? ?
|
|
} else it->eq_fn = lookup_none_eq_fn;
|
|
} else it->eq_fn = lookup_none_eq_fn;
|
|
|
|
|
|
- it->bucket = it->store->keys; // First record in hash table.
|
|
|
|
- it->rc = it->bucket == NULL ? LSUP_END : LSUP_OK;
|
|
|
|
|
|
+ it->entry = it->store->keys; // First record in hash table.
|
|
|
|
+ it->rc = it->entry == NULL ? LSUP_END : LSUP_OK;
|
|
it->i = 0;
|
|
it->i = 0;
|
|
|
|
|
|
return it;
|
|
return it;
|
|
@@ -450,23 +460,23 @@ LSUP_htiter_next (HTIterator *it, LSUP_SerTriple *sspo)
|
|
it->rc = LSUP_NORESULT;
|
|
it->rc = LSUP_NORESULT;
|
|
|
|
|
|
while (it->rc == LSUP_NORESULT) {
|
|
while (it->rc == LSUP_NORESULT) {
|
|
- if (!it->bucket) it->rc = LSUP_END;
|
|
|
|
|
|
+ if (!it->entry) it->rc = LSUP_END;
|
|
|
|
|
|
else {
|
|
else {
|
|
- if (it->eq_fn (it->bucket->key, it->luk)) {
|
|
|
|
- tkey_to_strp (it->store, it->bucket->key, sspo);
|
|
|
|
|
|
+ if (it->eq_fn (it->entry->key, it->luk)) {
|
|
|
|
+ tkey_to_strp (it->store, it->entry->key, sspo);
|
|
if (!sspo->s || !sspo->p || !sspo->o) return LSUP_DB_ERR;
|
|
if (!sspo->s || !sspo->p || !sspo->o) return LSUP_DB_ERR;
|
|
|
|
|
|
TRACE (
|
|
TRACE (
|
|
"Found spok: {%lx, %lx, %lx}",
|
|
"Found spok: {%lx, %lx, %lx}",
|
|
- it->bucket->key[0], it->bucket->key[1], it->bucket->key[2]
|
|
|
|
|
|
+ it->entry->key[0], it->entry->key[1], it->entry->key[2]
|
|
);
|
|
);
|
|
|
|
|
|
it->rc = LSUP_OK;
|
|
it->rc = LSUP_OK;
|
|
it->i++;
|
|
it->i++;
|
|
}
|
|
}
|
|
|
|
|
|
- it->bucket = it->bucket->hh.next;
|
|
|
|
|
|
+ it->entry = it->entry->hh.next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return it->rc;
|
|
return it->rc;
|
|
@@ -479,13 +489,20 @@ inline static LSUP_rc
|
|
tkey_to_strp (
|
|
tkey_to_strp (
|
|
const HTStore *store, const LSUP_Key spok[], LSUP_SerTriple *sspo)
|
|
const HTStore *store, const LSUP_Key spok[], LSUP_SerTriple *sspo)
|
|
{
|
|
{
|
|
- for (unsigned i = 0; i < 3; i++) {
|
|
|
|
- IndexEntry *cur = NULL;
|
|
|
|
- HASH_FIND (hh, store->idx, spok + i, KLEN, cur);
|
|
|
|
- if (!UNLIKELY (cur)) return LSUP_ERROR;
|
|
|
|
|
|
+ // owned by the store.
|
|
|
|
+ IndexEntry *tmp = NULL;
|
|
|
|
|
|
- memcpy (LSUP_striple_pos (sspo, i), cur->sterm, sizeof (*cur->sterm));
|
|
|
|
- };
|
|
|
|
|
|
+ HASH_FIND (hh, store->idx, spok + 0, KLEN, tmp);
|
|
|
|
+ sspo->s = tmp->sterm;
|
|
|
|
+ sspo->s->size = tmp->sterm->size;
|
|
|
|
+
|
|
|
|
+ HASH_FIND (hh, store->idx, spok + 1, KLEN, tmp);
|
|
|
|
+ sspo->p = tmp->sterm;
|
|
|
|
+ sspo->s->size = tmp->sterm->size;
|
|
|
|
+
|
|
|
|
+ HASH_FIND (hh, store->idx, spok + 2, KLEN, tmp);
|
|
|
|
+ if (UNLIKELY (!tmp)) return LSUP_ERROR;
|
|
|
|
+ sspo->o = tmp->sterm;
|
|
|
|
|
|
return LSUP_OK;
|
|
return LSUP_OK;
|
|
}
|
|
}
|