|
@@ -9,10 +9,6 @@
|
|
#include "buffer.h"
|
|
#include "buffer.h"
|
|
#include "namespace.h"
|
|
#include "namespace.h"
|
|
|
|
|
|
-// "NULL" triple, a value that is never user-provided. Used to fill deleted
|
|
|
|
-// triples in a keyset.
|
|
|
|
-#define NULL_TRP {NULL_KEY, NULL_KEY, NULL_KEY}
|
|
|
|
-
|
|
|
|
#define UUID4_URN_SIZE UUIDSTR_SIZE + 10
|
|
#define UUID4_URN_SIZE UUIDSTR_SIZE + 10
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -31,18 +27,6 @@
|
|
/* Blank node. */
|
|
/* Blank node. */
|
|
#define LSUP_TERM_BNODE 5
|
|
#define LSUP_TERM_BNODE 5
|
|
|
|
|
|
-/*
|
|
|
|
- * In-term identifier types.
|
|
|
|
- */
|
|
|
|
-/* Namespace prefix string. */
|
|
|
|
-#define LSUP_ID_NS 10
|
|
|
|
-/* Data type IRI. */
|
|
|
|
-#define LSUP_ID_DATATYPE 11
|
|
|
|
-/* Language tag string. */
|
|
|
|
-#define LSUP_ID_LANG 12
|
|
|
|
-/* Temporary blank node ID. TODO implement. */
|
|
|
|
-#define LSUP_ID_BNODE 13
|
|
|
|
-
|
|
|
|
/** @brief Default data type for untyped literals (prefixed IRI).
|
|
/** @brief Default data type for untyped literals (prefixed IRI).
|
|
*/
|
|
*/
|
|
#define DEFAULT_DTYPE "http://www.w3.org/2001/XMLSchema#string"
|
|
#define DEFAULT_DTYPE "http://www.w3.org/2001/XMLSchema#string"
|
|
@@ -59,39 +43,46 @@
|
|
|
|
|
|
typedef XXH64_hash_t LSUP_Hash64;
|
|
typedef XXH64_hash_t LSUP_Hash64;
|
|
typedef char LSUP_TermType;
|
|
typedef char LSUP_TermType;
|
|
|
|
+typedef char LSUP_LangTag[8];
|
|
|
|
|
|
|
|
|
|
typedef struct term_t {
|
|
typedef struct term_t {
|
|
char * data; // URI, literal value, or BNode label.
|
|
char * data; // URI, literal value, or BNode label.
|
|
union {
|
|
union {
|
|
- uint32_t datatype; // Data type hash for LSUP_TERM_LITERAL.
|
|
|
|
- uint32_t lang; // Lang tag hash for LSUP_TERM_LT_LITERAL.
|
|
|
|
- uint32_t bnode_id; // Blank node ID. TODO implement.
|
|
|
|
|
|
+ LSUP_Key datatype; // Data type key for LSUP_TERM_LITERAL.
|
|
|
|
+ LSUP_LangTag lang; // Lang tag for LSUP_TERM_LT_LITERAL.
|
|
|
|
+ LSUP_Key bnode_id; // BNode ID for comparison & skolemization.
|
|
LSUP_NSMap * nsm; // NSM handle for prefixed IRI.
|
|
LSUP_NSMap * nsm; // NSM handle for prefixed IRI.
|
|
};
|
|
};
|
|
LSUP_TermType type; // Term type.
|
|
LSUP_TermType type; // Term type.
|
|
} LSUP_Term;
|
|
} LSUP_Term;
|
|
|
|
|
|
|
|
|
|
-/** @brief Hash cache for lang tags and data types.
|
|
|
|
|
|
+/** @brief Hash cache for data types.
|
|
*/
|
|
*/
|
|
-typedef struct id_cache_t {
|
|
|
|
- uint32_t key;
|
|
|
|
- char * data;
|
|
|
|
|
|
+struct term_cache_t {
|
|
|
|
+ LSUP_Key key;
|
|
|
|
+ LSUP_Term * term;
|
|
UT_hash_handle hh;
|
|
UT_hash_handle hh;
|
|
-} IDCache;
|
|
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+typedef struct triple_t {
|
|
|
|
+ LSUP_Term *s;
|
|
|
|
+ LSUP_Term *p;
|
|
|
|
+ LSUP_Term *o;
|
|
|
|
+} LSUP_Triple;
|
|
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Extern variables.
|
|
* Extern variables.
|
|
*/
|
|
*/
|
|
|
|
|
|
-/** @brief Global ID cache.
|
|
|
|
|
|
+/** @brief Global term cache.
|
|
*
|
|
*
|
|
- * Map of internal term identifiers, such as literal data types, language tags
|
|
|
|
- * and BNode identifiers.
|
|
|
|
|
|
+ * Stores frequently used terms, e.g. data type URIs.
|
|
*/
|
|
*/
|
|
-extern IDCache *LSUP_id_cache;
|
|
|
|
|
|
+extern struct term_cache_t *LSUP_term_cache;
|
|
|
|
|
|
/** @brief Compiled hash of default literal data type.
|
|
/** @brief Compiled hash of default literal data type.
|
|
*/
|
|
*/
|
|
@@ -101,6 +92,12 @@ extern uint32_t LSUP_default_dtype_key;
|
|
*/
|
|
*/
|
|
extern regex_t *LSUP_uri_ptn;
|
|
extern regex_t *LSUP_uri_ptn;
|
|
|
|
|
|
|
|
+/** @brief Default literal data type URI.
|
|
|
|
+ *
|
|
|
|
+ * Literal terms created with undefined data type will have it set to this
|
|
|
|
+ * URI implicitly.
|
|
|
|
+ */
|
|
|
|
+extern LSUP_Term *LSUP_default_datatype;
|
|
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -114,16 +111,14 @@ extern regex_t *LSUP_uri_ptn;
|
|
* @param data[in] Term data: textual URI, literal value without data type
|
|
* @param data[in] Term data: textual URI, literal value without data type
|
|
* or langtag, etc.
|
|
* or langtag, etc.
|
|
*
|
|
*
|
|
- * @param metadata[in]: language tag for language-tagged literals or data type
|
|
|
|
- * for other literals.
|
|
|
|
|
|
+ * @param metadata[in]: language tag (LSUP_LangTag) for language-tagged
|
|
|
|
+ * literals; or data type (LSUP_Term *) for other literals. It may be NULL.
|
|
*
|
|
*
|
|
- * @param term[out] Pointer to a new term, which must be freed with
|
|
|
|
- * #LSUP_term_free after use.
|
|
|
|
- *
|
|
|
|
- * @return LSUP_OK if successful, LSUP_VALUE_ERR if validation fails.
|
|
|
|
|
|
+ * @return New term, which must be freed with #LSUP_term_free after use; or
|
|
|
|
+ * NULL on error.
|
|
*/
|
|
*/
|
|
LSUP_Term *
|
|
LSUP_Term *
|
|
-LSUP_term_new (LSUP_TermType type, const char *data, const char *metadata);
|
|
|
|
|
|
+LSUP_term_new (LSUP_TermType type, const char *data, void *metadata);
|
|
|
|
|
|
|
|
|
|
/** @brief Placeholder term to use with LSUP_term_reset.
|
|
/** @brief Placeholder term to use with LSUP_term_reset.
|
|
@@ -170,15 +165,28 @@ LSUP_uri_new (const char *data)
|
|
LSUP_rc
|
|
LSUP_rc
|
|
LSUP_term_init(
|
|
LSUP_term_init(
|
|
LSUP_Term *term, LSUP_TermType type,
|
|
LSUP_Term *term, LSUP_TermType type,
|
|
- const char *data, const char *metadata);
|
|
|
|
|
|
+ const char *data, void *metadata);
|
|
|
|
|
|
|
|
|
|
|
|
+/** @brief Deserialize a buffer into a term.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] sterm Buffer to convert into a term. It must be a valid
|
|
|
|
+ * serialized term from store or obtained with #LSUP_term_serialize().
|
|
|
|
+ *
|
|
|
|
+ * @return New term handle. It must be freed with #LSUP_term_free().
|
|
|
|
+ */
|
|
LSUP_Term *
|
|
LSUP_Term *
|
|
LSUP_term_new_from_buffer (const LSUP_Buffer *sterm);
|
|
LSUP_term_new_from_buffer (const LSUP_Buffer *sterm);
|
|
|
|
|
|
|
|
|
|
|
|
+/** @brief Serialize a term into a buffer.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] sterm Term to convert into a buffer.
|
|
|
|
+ *
|
|
|
|
+ * @return New buffer handle. It must be freed with #LSUP_buffer_free().
|
|
|
|
+ */
|
|
LSUP_Buffer *
|
|
LSUP_Buffer *
|
|
-LSUP_buffer_new_from_term (const LSUP_Term *term);
|
|
|
|
|
|
+LSUP_term_serialize (const LSUP_Term *term);
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -190,20 +198,8 @@ LSUP_uri_init (LSUP_Term *term, const char *data);
|
|
|
|
|
|
/** @brief Hash a buffer.
|
|
/** @brief Hash a buffer.
|
|
*/
|
|
*/
|
|
-inline LSUP_Key
|
|
|
|
-LSUP_term_hash (const LSUP_Term *term)
|
|
|
|
-{
|
|
|
|
- LSUP_Buffer *buf;
|
|
|
|
-
|
|
|
|
- if (UNLIKELY (!term)) buf = BUF_DUMMY;
|
|
|
|
- else buf = LSUP_buffer_new_from_term (term);
|
|
|
|
-
|
|
|
|
- LSUP_Key key = LSUP_buffer_hash (buf);
|
|
|
|
-
|
|
|
|
- LSUP_buffer_free (buf);
|
|
|
|
-
|
|
|
|
- return key;
|
|
|
|
-}
|
|
|
|
|
|
+LSUP_Key
|
|
|
|
+LSUP_term_hash (const LSUP_Term *term);
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -218,15 +214,107 @@ void
|
|
LSUP_term_free (LSUP_Term *term);
|
|
LSUP_term_free (LSUP_Term *term);
|
|
|
|
|
|
|
|
|
|
-/** @brief Add an identifier to the term cache.
|
|
|
|
|
|
+/** @brief Create a new triple from three terms.
|
|
|
|
+ *
|
|
|
|
+ * TODO Term types are not validated at the moment.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] s Triple subject. It must be an IRIRef or BNode.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] p Triple predicate. It must be an IRIRef.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] o Triple object.
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+LSUP_Triple *
|
|
|
|
+LSUP_triple_new(LSUP_Term *s, LSUP_Term *p, LSUP_Term *o);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** @brief Dummy triple with NULL slots. It is not a valid triple.
|
|
|
|
+ */
|
|
|
|
+#define TRP_DUMMY LSUP_triple_new (NULL, NULL, NULL)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+LSUP_Triple *
|
|
|
|
+LSUP_triple_new_from_btriple (const LSUP_BufferTriple *sspo);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+LSUP_BufferTriple *
|
|
|
|
+LSUP_triple_serialize (const LSUP_Triple *spo);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** @brief Initialize internal term pointers in a heap-allocated triple.
|
|
*
|
|
*
|
|
- * @param[in] key 32-bit hash of the inserted term.
|
|
|
|
|
|
+ * NOTE: the term structures are not copied. If the triple is freed with
|
|
|
|
+ * #LSUP_triple_free(), the originally provided terms are freed too.
|
|
*
|
|
*
|
|
- * @param[in] data Term to insert.
|
|
|
|
|
|
+ * @param spo[in] Triple pointer to initialize.
|
|
*/
|
|
*/
|
|
LSUP_rc
|
|
LSUP_rc
|
|
-LSUP_tcache_add_id (const uint32_t key, const char *data);
|
|
|
|
|
|
+LSUP_triple_init (LSUP_Triple *spo, LSUP_Term *s, LSUP_Term *p, LSUP_Term *o);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** @brief Free the internal pointers of a triple.
|
|
|
|
+ *
|
|
|
|
+ * @param spo[in] Triple to be freed.
|
|
|
|
+ */
|
|
|
|
+void
|
|
|
|
+LSUP_triple_done (LSUP_Triple *spo);
|
|
|
|
+
|
|
|
|
|
|
|
|
+/** @brief Free a triple and all its internal pointers.
|
|
|
|
+ *
|
|
|
|
+ * NOTE: If the term pointers are not to be freed (e.g. they are owned by a
|
|
|
|
+ * back end), use a simple free(spo) instead of this.
|
|
|
|
+ *
|
|
|
|
+ * @param spo[in] Triple to be freed.
|
|
|
|
+ */
|
|
|
|
+void
|
|
|
|
+LSUP_triple_free (LSUP_Triple *spo);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** @brief Get triple by term position.
|
|
|
|
+ *
|
|
|
|
+ * Useful for looping over all terms.
|
|
|
|
+ *
|
|
|
|
+ * @param trp[in] Triple pointer.
|
|
|
|
+ *
|
|
|
|
+ * @param n[in] A number between 0÷2.
|
|
|
|
+ *
|
|
|
|
+ * @return Corresponding triple term or NULL if n is out of range.
|
|
|
|
+ */
|
|
|
|
+inline LSUP_Term *
|
|
|
|
+LSUP_triple_pos (const LSUP_Triple *trp, LSUP_TriplePos n)
|
|
|
|
+{
|
|
|
|
+ if (n == TRP_POS_S) return trp->s;
|
|
|
|
+ if (n == TRP_POS_P) return trp->p;
|
|
|
|
+ if (n == TRP_POS_O) return trp->o;
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** @brief Hash a triple.
|
|
|
|
+ *
|
|
|
|
+ * TODO This doesn't handle blank nodes correctly.
|
|
|
|
+ */
|
|
|
|
+inline LSUP_Key
|
|
|
|
+LSUP_triple_hash (const LSUP_Triple *trp)
|
|
|
|
+{
|
|
|
|
+ LSUP_BufferTriple *strp = LSUP_triple_serialize (trp);
|
|
|
|
+ LSUP_Key hash = LSUP_btriple_hash (strp);
|
|
|
|
+ LSUP_btriple_free (strp);
|
|
|
|
+
|
|
|
|
+ return hash;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/** @brief Add an identifier to the term cache.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] key Hash of the inserted term.
|
|
|
|
+ *
|
|
|
|
+ * @param[in] term Term to insert.
|
|
|
|
+ */
|
|
|
|
+LSUP_rc
|
|
|
|
+LSUP_tcache_add (const LSUP_Key key, LSUP_Term *term);
|
|
|
|
|
|
/** @brief Get an identifier from the cache.
|
|
/** @brief Get an identifier from the cache.
|
|
*
|
|
*
|
|
@@ -235,7 +323,7 @@ LSUP_tcache_add_id (const uint32_t key, const char *data);
|
|
* @return The retrieved term if found, or NULL. The string must not be
|
|
* @return The retrieved term if found, or NULL. The string must not be
|
|
* modified or freed.
|
|
* modified or freed.
|
|
*/
|
|
*/
|
|
-const char *
|
|
|
|
-LSUP_tcache_get_id (const uint32_t key);
|
|
|
|
|
|
+const LSUP_Term *
|
|
|
|
+LSUP_tcache_get (const LSUP_Key key);
|
|
|
|
|
|
#endif
|
|
#endif
|