Browse Source

Move boolean operations from keyset to graph.

Stefano Cossu 4 years ago
parent
commit
2c32f4ae91
6 changed files with 146 additions and 138 deletions
  1. 3 0
      .gitmodules
  2. 1 0
      ext/uuid4
  3. 29 0
      include/graph.h
  4. 8 37
      include/keyset.h
  5. 91 2
      src/graph.c
  6. 14 99
      src/keyset.c

+ 3 - 0
.gitmodules

@@ -1,3 +1,6 @@
 [submodule "ext/xxHash"]
 	path = ext/xxHash
 	url = https://github.com/Cyan4973/xxHash.git
+[submodule "ext/uuid4"]
+	path = ext/uuid4
+	url = https://github.com/rxi/uuid4.git

+ 1 - 0
ext/uuid4

@@ -0,0 +1 @@
+Subproject commit 14186f90f74138f6260b43c1b4a3a3b55b2aeaa8

+ 29 - 0
include/graph.h

@@ -41,6 +41,35 @@ LSUP_graph_contains(const LSUP_Graph *gr, const LSUP_Triple *t);
 int
 LSUP_graph_add(LSUP_Graph *gr, LSUP_Triple data[], size_t data_size);
 
+/**
+ * Set-theoretical union (gr1 ∪ gr2).
+ *
+ * The resulting Keyset is initialized beforehand and is not compacted.
+ */
+int LSUP_graph_join(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res);
+
+/**
+ * Set-theoretical complement (gr1 \ gr2).
+ *
+ * The resulting Keyset is initialized beforehand and is not compacted.
+ */
+int LSUP_graph_subtract(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res);
+
+/**
+ * Set-theoretical intersection (gr1 ∩ gr2).
+ *
+ * The resulting Keyset is initialized beforehand and is not compacted.
+ */
+int LSUP_graph_intersect(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res);
+
+/**
+ * Disjunctive union (XOR) (gr1 ⊕ gr2).
+ *
+ * The resulting Keyset is initialized beforehand and is not compacted.
+ */
+int LSUP_graph_xor(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res);
+
+
 void
 LSUP_graph_free(LSUP_Graph *gr);
 

+ 8 - 37
include/keyset.h

@@ -4,8 +4,9 @@
 #include "core.h"
 
 typedef enum LSUP_KSFlag {
-    LSUP_KS_CHECK_CAP = 1 << 0,
-    LSUP_KS_CHECK_DUP = 1 << 1
+    LSUP_KS_NONE        = 0,
+    LSUP_KS_CHECK_CAP   = 1 << 0,
+    LSUP_KS_CHECK_DUP   = 1 << 1
 } LSUP_KSFlag;
 
 typedef struct keyset {
@@ -13,13 +14,12 @@ typedef struct keyset {
     size_t          capacity;
     size_t          cur;
     size_t          free_i;
-    float           expand_ratio;
 } LSUP_Keyset;
 
 
-int LSUP_keyset_init(LSUP_Keyset *ks, size_t capacity, float expand_ratio);
+int LSUP_keyset_init(LSUP_Keyset *ks, size_t capacity);
 
-LSUP_Keyset *LSUP_keyset_new(size_t capacity, float expand_ratio);
+LSUP_Keyset *LSUP_keyset_new(size_t capacity);
 
 
 /**
@@ -47,8 +47,8 @@ inline size_t LSUP_keyset_tell(LSUP_Keyset* ks)
 }
 
 
-inline const LSUP_TripleKey *LSUP_keyset_peek(LSUP_Keyset *ks) {
-    return (const LSUP_TripleKey *)(ks->data + ks->cur);
+inline LSUP_TripleKey *LSUP_keyset_peek(LSUP_Keyset *ks) {
+    return ks->data + ks->cur;
 }
 
 
@@ -90,7 +90,7 @@ int LSUP_keyset_resize(LSUP_Keyset *ks, size_t new_size);
  * Add a single key.
  */
 int LSUP_keyset_add(
-        LSUP_Keyset *ks, const LSUP_TripleKey *val, LSUP_KSFlag flags);
+        LSUP_Keyset *ks, const LSUP_TripleKey *val, const LSUP_KSFlag flags);
 
 int LSUP_keyset_remove(LSUP_Keyset *ks, const LSUP_TripleKey *val);
 
@@ -102,35 +102,6 @@ int LSUP_keyset_lookup(
         LSUP_Keyset *ks, LSUP_Keyset *res,
         const LSUP_Key sk, const LSUP_Key pk, const LSUP_Key ok);
 
-/**
- * Set-theoretical union (ks1 ∪ ks2).
- *
- * The resulting Keyset is initialized beforehand and is not compacted.
- */
-int LSUP_keyset_join(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
-
-/**
- * Set-theoretical complement (ks1 \ ks2).
- *
- * The resulting Keyset is initialized beforehand and is not compacted.
- */
-int LSUP_keyset_subtract(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
-
-/**
- * Set-theoretical intersection (ks1 ∩ ks2).
- *
- * The resulting Keyset is initialized beforehand and is not compacted.
- */
-int LSUP_keyset_intersect(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
-
-/**
- * Disjunctive union (XOR) (ks1 ⊕ ks2).
- *
- * The resulting Keyset is initialized beforehand and is not compacted.
- */
-int LSUP_keyset_xor(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
-
-
 void LSUP_keyset_done(LSUP_Keyset *ks);
 
 void LSUP_keyset_free(LSUP_Keyset *ks);

+ 91 - 2
src/graph.c

@@ -1,5 +1,10 @@
 #include "graph.h"
 
+// Max size of random graph name.
+#define RANDOM_NAME_SIZE 64
+// Initial size of lookup graph. It will double each time capacity is reached.
+#define LOOKUP_GR_INIT_SIZE 64
+
 /**
  * Extern inline functions.
  */
@@ -13,9 +18,15 @@ LSUP_graph_init(
         LSUP_Graph *gr, size_t capacity, char *uri_str,
         LSUP_store_type store_type)
 {
-    gr->uri = LSUP_term_new(LSUP_TERM_URI, uri_str, NULL, NULL);
+    if (uri_str == NULL) {
+        char gr_name[RANDOM_NAME_SIZE];
+        sprintf(gr_name, "urn:tmp:%d", rand());
+        gr->uri = LSUP_term_new(LSUP_TERM_URI, gr_name, NULL, NULL);
+    } else {
+        gr->uri = LSUP_term_new(LSUP_TERM_URI, uri_str, NULL, NULL);
+    }
 
-    gr->keys = LSUP_keyset_new(capacity, .75);
+    gr->keys = LSUP_keyset_new(capacity);
 
     switch (store_type ) {
         case LSUP_STORE_MEM:
@@ -98,6 +109,84 @@ LSUP_graph_contains(const LSUP_Graph *gr, const LSUP_Triple *spo)
 }
 
 
+int LSUP_graph_join(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res)
+{
+    LSUP_keyset_sparse_copy(ks1, res);
+
+    if (LSUP_keyset_seek(ks2, 0)) {
+        do {
+            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks2);
+            if (!is_null_trp(spok)) {
+                LSUP_keyset_add(
+                        res, spok, LSUP_KS_CHECK_DUP | LSUP_KS_CHECK_CAP);
+            }
+        } while (LSUP_keyset_next(ks2));
+    }
+
+    return 0;
+}
+
+
+int LSUP_graph_subtract(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res)
+{
+    LSUP_graph_init(res, gr1->keys->capacity, NULL, LSUP_STORE_MEM);
+
+    if (LSUP_keyset_seek(ks1, 0)) {
+        do {
+            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks1);
+            if (!is_null_trp(spok) && !LSUP_keyset_contains(ks2, spok)) {
+                LSUP_keyset_add(res, spok, 0);
+            }
+        } while (LSUP_keyset_next(ks1));
+    }
+
+    return 0;
+}
+
+
+int LSUP_graph_intersect(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res)
+{
+    LSUP_graph_init(res, gr1->keys->capacity, NULL, LSUP_STORE_MEM);
+
+    if (LSUP_keyset_seek(ks1, 0)) {
+        do {
+            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks1);
+            if (!is_null_trp(spok) && LSUP_keyset_contains(ks2, spok)) {
+                LSUP_keyset_add(res, spok, 0);
+            }
+        } while (LSUP_keyset_next(ks1));
+    }
+
+    return 0;
+}
+
+
+int LSUP_graph_xor(LSUP_Graph *gr1, LSUP_Graph *gr2, LSUP_Graph *res)
+{
+    LSUP_graph_init(res, gr1->keys->capacity, NULL, LSUP_STORE_MEM);
+
+    if (LSUP_keyset_seek(ks1, 0)) {
+        do {
+            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks1);
+            if (!is_null_trp(spok) && !LSUP_keyset_contains(ks2, spok)) {
+                LSUP_keyset_add(res, spok, 0);
+            }
+        } while (LSUP_keyset_next(ks1));
+    }
+
+    if (LSUP_keyset_seek(ks2, 0)) {
+        do {
+            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks2);
+            if (!is_null_trp(spok) && !LSUP_keyset_contains(ks1, spok)) {
+                LSUP_keyset_add(res, spok, 0);
+            }
+        } while (LSUP_keyset_next(ks2));
+    }
+
+    return 0;
+}
+
+
 void
 LSUP_graph_free(LSUP_Graph *gr)
 {

+ 14 - 99
src/keyset.c

@@ -10,24 +10,24 @@
 
 LSUP_TripleKey NULL_TRP = {NULL_KEY, NULL_KEY, NULL_KEY};
 
+
 /**
- * CALLBACKS
+ * Callback type for key comparison.
  */
-
 typedef bool (*LSUP_key_cmp_fn_t)(
         const LSUP_TripleKey* spok, const LSUP_Key k1, const LSUP_Key k2);
 
-//  Keyset lookup for S LSUP_Key.
+//  Keyset lookup for S key.
 static inline bool lookup_sk_cmp_fn(
         const LSUP_TripleKey* spok, const LSUP_Key k1, const LSUP_Key k2)
 { return spok[0][0] == k1; }
 
-//  Keyset lookup for P LSUP_Key.
+//  Keyset lookup for P key.
 static inline bool lookup_pk_cmp_fn(
         const LSUP_TripleKey* spok, const LSUP_Key k1, const LSUP_Key k2)
 { return spok[0][1] == k1; }
 
-//  Keyset lookup for O LSUP_Key.
+//  Keyset lookup for O key.
 static inline bool lookup_ok_cmp_fn(
         const LSUP_TripleKey* spok, const LSUP_Key k1, const LSUP_Key k2)
 { return spok[0][2] == k1; }
@@ -58,7 +58,7 @@ static inline bool lookup_none_cmp_fn(
 bool LSUP_keyset_seek(LSUP_Keyset* ks, size_t idx);
 size_t LSUP_keyset_size(LSUP_Keyset* ks);
 size_t LSUP_keyset_tell(LSUP_Keyset* ks);
-const LSUP_TripleKey *LSUP_keyset_peek(LSUP_Keyset *ks);
+LSUP_TripleKey *LSUP_keyset_peek(LSUP_Keyset *ks);
 bool LSUP_keyset_contains(
         const LSUP_Keyset *ks, const LSUP_TripleKey *val);
 bool LSUP_keyset_next(LSUP_Keyset *ks);
@@ -75,22 +75,21 @@ static inline bool is_null_trp(const LSUP_TripleKey *trp)
 }
 
 
-int LSUP_keyset_init(LSUP_Keyset *ks, size_t capacity, float expand_ratio)
+int LSUP_keyset_init(LSUP_Keyset *ks, size_t capacity)
 {
     CRITICAL (ks->data = malloc(capacity * TRP_KLEN));
     ks->capacity = capacity;
     ks->cur = 0;
     ks->free_i = 0;
-    ks->expand_ratio = expand_ratio;
 
     return 0;
 }
 
 
-LSUP_Keyset *LSUP_keyset_new(size_t capacity, float expand_ratio) {
+LSUP_Keyset *LSUP_keyset_new(size_t capacity) {
     LSUP_Keyset *ks = malloc(sizeof(LSUP_Keyset));
 
-    LSUP_keyset_init(ks, capacity, expand_ratio);
+    LSUP_keyset_init(ks, capacity);
 
     return(ks);
 }
@@ -127,19 +126,13 @@ int LSUP_keyset_resize(LSUP_Keyset *ks, size_t new_size) {
 
 
 int LSUP_keyset_add(
-        LSUP_Keyset *ks, const LSUP_TripleKey *val, LSUP_KSFlag flags)
+        LSUP_Keyset *ks, const LSUP_TripleKey *val, const LSUP_KSFlag flags)
 {
     if((flags & LSUP_KS_CHECK_DUP) && LSUP_keyset_contains(ks, val))
         return 1;
 
-    if((flags & LSUP_KS_CHECK_CAP) && ks->free_i >= ks->capacity) {
-        if(ks->expand_ratio > 0) {
-            LSUP_keyset_resize(
-                    ks, 1 + (size_t)(ks->capacity * (1 + ks->expand_ratio)));
-        } else {
-            return -2; // TODO: ENOMEM
-        }
-    }
+    if((flags & LSUP_KS_CHECK_CAP) && ks->free_i >= ks->capacity)
+            LSUP_keyset_resize(ks, ks->capacity * 2);
 
     memcpy(ks->data + ks->free_i, val, TRP_KLEN);
 
@@ -168,7 +161,7 @@ int LSUP_keyset_remove(LSUP_Keyset *ks, const LSUP_TripleKey *val) {
 
 int LSUP_keyset_copy(const LSUP_Keyset *src, LSUP_Keyset *dest) {
 
-    LSUP_keyset_init(dest, src->capacity, src->expand_ratio);
+    LSUP_keyset_init(dest, src->capacity);
 
     memcpy(dest->data, src->data, src->capacity * TRP_KLEN);
 
@@ -181,7 +174,7 @@ int LSUP_keyset_copy(const LSUP_Keyset *src, LSUP_Keyset *dest) {
 
 int LSUP_keyset_sparse_copy(LSUP_Keyset *src, LSUP_Keyset *dest) {
 
-    LSUP_keyset_init(dest, src->capacity, src->expand_ratio);
+    LSUP_keyset_init(dest, src->capacity);
 
     if (LSUP_keyset_seek(src, 0)) {
         do {
@@ -268,84 +261,6 @@ int LSUP_keyset_lookup(
 }
 
 
-int LSUP_keyset_join(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res)
-{
-    LSUP_keyset_sparse_copy(ks1, res);
-
-    if (LSUP_keyset_seek(ks2, 0)) {
-        do {
-            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks2);
-            if (!is_null_trp(spok)) {
-                LSUP_keyset_add(
-                        res, spok, LSUP_KS_CHECK_DUP | LSUP_KS_CHECK_CAP);
-            }
-        } while (LSUP_keyset_next(ks2));
-    }
-
-    return 0;
-}
-
-
-int LSUP_keyset_subtract(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res)
-{
-    LSUP_keyset_init(res, ks1->capacity, ks1->expand_ratio);
-
-    if (LSUP_keyset_seek(ks1, 0)) {
-        do {
-            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks1);
-            if (!is_null_trp(spok) && !LSUP_keyset_contains(ks2, spok)) {
-                LSUP_keyset_add(res, spok, 0);
-            }
-        } while (LSUP_keyset_next(ks1));
-    }
-
-    return 0;
-}
-
-
-int LSUP_keyset_intersect(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res)
-{
-    LSUP_keyset_init(res, ks1->capacity, ks1->expand_ratio);
-
-    if (LSUP_keyset_seek(ks1, 0)) {
-        do {
-            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks1);
-            if (!is_null_trp(spok) && LSUP_keyset_contains(ks2, spok)) {
-                LSUP_keyset_add(res, spok, 0);
-            }
-        } while (LSUP_keyset_next(ks1));
-    }
-
-    return 0;
-}
-
-
-int LSUP_keyset_xor(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res)
-{
-    LSUP_keyset_init(res, ks1->capacity + ks2->capacity, ks1->expand_ratio);
-
-    if (LSUP_keyset_seek(ks1, 0)) {
-        do {
-            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks1);
-            if (!is_null_trp(spok) && !LSUP_keyset_contains(ks2, spok)) {
-                LSUP_keyset_add(res, spok, 0);
-            }
-        } while (LSUP_keyset_next(ks1));
-    }
-
-    if (LSUP_keyset_seek(ks2, 0)) {
-        do {
-            const LSUP_TripleKey *spok = LSUP_keyset_peek(ks2);
-            if (!is_null_trp(spok) && !LSUP_keyset_contains(ks1, spok)) {
-                LSUP_keyset_add(res, spok, 0);
-            }
-        } while (LSUP_keyset_next(ks2));
-    }
-
-    return 0;
-}
-
-
 void LSUP_keyset_done(LSUP_Keyset *ks)
 {
     if(LIKELY(ks->data != NULL))