3#define MAX_VALID_TERM_TYPE VOLK_TERM_BNODE
11typedef struct keyed_term {
47typedef struct link_map {
69static const char *invalid_uri_chars =
"<>\" {}|\\^`";
91 const void *item, uint64_t _unused, uint64_t _unused2)
101tset_cmp_fn (
const void *a,
const void *b,
void *_unused)
112tset_free_fn (
void *item)
122 const void *item, uint64_t _unused, uint64_t _unused2)
127 return ((
const Link *)item)->term->key;
132link_map_cmp_fn (
const void *a,
const void *b,
void *_unused)
137 ((
const Link *)a)->term->key -
138 ((
const Link *)b)->term->key;
143link_map_free_fn (
void *item)
164 term, type, data, metadata) !=
VOLK_OK)) {
176 void *metadata = NULL;
181 metadata = (
void *) src->
lang;
195 void *metadata = NULL;
198 size_t cplen =
sizeof (type);
199 char *cpcur = (
char *)sterm->
addr;
200 memcpy (&type, cpcur, cplen);
204 cplen = strlen (cpcur) + 1;
205 data = malloc (cplen);
207 memcpy (data, cpcur, cplen);
212 if (strlen(cpcur) > 0)
216 metadata = malloc (cplen);
218 memcpy (metadata, cpcur, cplen);
234 log_error (
"Provided path is not an IRI.");
238 log_error (
"Provided root is not an IRI.");
246 if (strlen (pfx) > 0) data = iri->
data;
248 else if (iri->
data[0] ==
'/') {
252 data = malloc (strlen (iri->
data) + strlen (pfx) + 1);
253 if (!data)
return NULL;
255 sprintf (data,
"%s%s", pfx, iri->
data);
258 data = malloc (strlen (iri->
data) + strlen (root->
data) + 1);
259 if (!data)
return NULL;
261 sprintf (data,
"%s%s", root->
data, iri->
data);
266 if (data != iri->
data) free (data);
276 log_error (
"Provided path is not an IRI.");
280 log_error (
"Provided root is not an IRI.");
286 strlen (root->
data) : 0);
333 size_t cplen =
sizeof(term->
type);
334 memcpy (sterm->
addr, &term->
type, cplen);
338 cplen = strlen (term->
data) + 1;
339 memcpy (sterm->
addr + offset, term->
data, cplen);
349 sterm->
addr[offset] =
'\0';
352 cplen = strlen (term->
datatype->data) + 1;
353 sterm->
size += cplen;
361 sterm->
size += cplen;
406 log_error (
"Term is not a IRI ref type.");
423 log_error (
"Term is not a IRI ref type.");
439 log_error (
"Term is not a IRI ref type.");
459 if (!spo)
return NULL;
474 if (!spo)
return NULL;
488 if (!sspo)
return NULL;
554 tset_hash_fn, tset_cmp_fn, tset_free_fn, NULL);
555 if (
UNLIKELY (hashmap_oom (ts)))
return NULL;
565 KeyedTerm entry_s = {.key=key, .term=term};
567 const KeyedTerm *ex = hashmap_get (ts, &entry_s);
569 if (existing) *existing = ex->
term;
573 hashmap_set (ts, &entry_s);
585 else {
LOG_TRACE(
"No ID found for key %lx.", key);}
587 return (entry) ? entry->
term : NULL;
595 if (!hashmap_iter (ts, i, (
void **)&kt))
return VOLK_END;
597 if (term) *term = kt->
term;
613{
return hashmap_count (ts); }
622 lm->
links = hashmap_new (
624 link_map_hash_fn, link_map_cmp_fn, link_map_free_fn, NULL);
626 log_error (
"term must not be NULL.");
639 hashmap_free (lm->
links);
658 const Link *ex = hashmap_get (lmap->
links, &(
Link){.term=&entry_s});
662 "Linking term %s exists. Adding individual terms.",
666 while (hashmap_iter (tset, &i, (
void **)&kt)) {
668 "Adding term %s to link %s",
670 if (hashmap_get (ex->
tset, kt))
675 hashmap_set (ex->
tset, kt);
685 memcpy (ins, &entry_s,
sizeof (entry_s));
686 Link link = {.term=ins, .tset=tset};
687 hashmap_set (lmap->
links, &link);
694VOLK_LinkMapIterator *
697 VOLK_LinkMapIterator *it;
714 if (!hashmap_iter (it->map->links, &it->i, (
void **)&it->link))
717 *lt = it->link->term->term;
718 *ts = it->link->tset;
731 spo->
o = it->map->linked_t;
733 spo->
s = it->map->linked_t;
734 else spo->
p = it->map->linked_t;
739 if (it->link)
goto int_loop;
743 if (!hashmap_iter (it->map->links, &it->i, (
void **)&it->link))
747 if (!hashmap_iter (it->link->tset, &it->j, (
void **)&kt))
goto ext_loop;
752 else spo->
p = it->link->term->term;
756 else spo->
o = kt->
term;
769 const char *data,
void *metadata)
780 term->
data = malloc (strlen (data) + 1);
782 strcpy (term->
data, data);
787 if (type < MIN_VALID_TYPE || type > MAX_VALID_TYPE) {
788 log_error (
"%d is not a valid term type.", type);
797 char *fquri = (
char *) data;
799 if (strpbrk (fquri, invalid_uri_chars) != NULL) {
801 "Characters %s are not valid in a URI. Got: %s\n",
802 invalid_uri_chars, fquri);
816 uuid_generate_random (uuid);
819 uuid_unparse_lower (uuid, uuid_str);
827 log_error (
"No data provided for term.");
834 log_warn (
"Lang tag is NULL. Creating a non-tagged literal.");
838 char *lang_str = (
char *) metadata;
839 LOG_TRACE(
"Lang string: '%s'", lang_str);
841 strncpy(term->
lang, lang_str, sizeof (term->
lang) - 1);
842 if (strlen (term->
lang) < 1) {
843 log_error (
"Lang tag cannot be an empty string.");
846 term->
lang[7] =
'\0';
857 "Literal data type is not an IRI: %s",
889 size_t iri_len = strlen (iri_str);
892 memset (iri_info, 0,
sizeof (*iri_info));
896 *cur !=
':' && *cur !=
'/' && *cur !=
'?'
897 && *cur !=
'#' && *cur !=
'\0') {
903 if (tmp.
size > 0 && *cur ==
':') {
909 }
else cur = iri_str;
912 if (*cur ==
'/' && *(cur + 1) ==
'/') {
914 tmp.
offset = cur - iri_str;
918 while (*cur !=
'/' && *cur !=
'?' && *cur !=
'#' && *cur !=
'\0') {
932 tmp.
offset = cur - iri_str;
940 while (*cur !=
'?' && *cur !=
'#' && *cur !=
'\0') {
948 tmp.
offset = ++cur - iri_str;
950 while (*cur !=
'#' && *cur !=
'\0') {
967 iri_info->
frag.
size = iri_str + iri_len - cur;
VOLK_Key VOLK_buffer_hash(const VOLK_Buffer *buf)
Hash a buffer.
VOLK_TriplePos
Triple position of s, p, o.
#define BUF_DUMMY
Dummy buffer to be used with VOLK_buffer_init.
void VOLK_buffer_free(VOLK_Buffer *buf)
Free a buffer.
#define VOLK_HASH_SEED
Seed used for all hashing. Compile-time configurable.
VOLK_Hash64 VOLK_Hash
Default hash data type.
bool VOLK_env_is_init
Whether the environment is initialized.
#define VOLK_HASH(...)
Default hashing function. Depends on architecture.
#define MALLOC_GUARD(var, rc)
Allocate one pointer with malloc and return rc if it fails.
#define RCNL(exp)
Return NULL if exp returns a nonzero value.
char * strdup(const char *src)
Replacement for GNU strdup.
#define NLNL(exp)
Log error and return NULL if exp is NULL.
#define CALLOC_GUARD(var, rc)
Allocate one pointer with calloc and return rc if it fails.
char * strndup(const char *src, size_t max)
Replacement for GNU strndup.
size_t VOLK_Key
Term key, i.e., hash of a serialized term.
char uuid_str_t[UUIDSTR_SIZE]
UUID string tpe.
#define VOLK_VALUE_ERR
An invalid input value was provided.
#define VOLK_MEM_ERR
Memory allocation error.
#define VOLK_END
Loop end.
#define VOLK_OK
Generic success return code.
#define VOLK_NOACTION
No action taken.
#define VOLK_ENV_ERR
Error while handling environment setup; or environment not initialized.
VOLK_Key VOLK_triple_hash(const VOLK_Triple *trp)
Hash a triple.
VOLK_Term * VOLK_lt_literal_new(const char *data, char *lang)
Shortcut to create a language-tagged literal term.
VOLK_rc VOLK_term_set_add(VOLK_TermSet *ts, VOLK_Term *term, VOLK_Term **existing)
Add term to a term set.
VOLK_Triple * VOLK_triple_new_from_btriple(const VOLK_BufferTriple *sspo)
struct hashmap VOLK_TermSet
a set of unique terms.
VOLK_rc VOLK_term_set_next(VOLK_TermSet *ts, size_t *i, VOLK_Term **term)
Iterate trough a term set.
VOLK_Triple * VOLK_triple_new(VOLK_Term *s, VOLK_Term *p, VOLK_Term *o)
Create a new triple from three terms.
char * VOLK_iriref_frag(const VOLK_Term *iri)
Get the fragment portion of a IRI ref.
VOLK_Term * VOLK_iriref_new_rel(const VOLK_Term *root, const VOLK_Term *iri)
Create a new relative IRI from an absolute IRI and a web root IRI.
VOLK_rc VOLK_parse_iri(char *iri_str, VOLK_IRIInfo *iri_info)
scan an IRI string and parse IRI parts.
void VOLK_link_map_iter_free(VOLK_LinkMapIterator *it)
Free a link map iterator.
VOLK_Term * VOLK_iriref_new(const char *data)
Create an IRI reference.
bool VOLK_term_equals(const VOLK_Term *term1, const VOLK_Term *term2)
Compare two terms.
size_t VOLK_term_set_size(VOLK_TermSet *ts)
Size of a term set.
VOLK_Term * VOLK_iriref_new_abs(const VOLK_Term *root, const VOLK_Term *iri)
Create a new absolute IRI from a path relative to a root IRI.
VOLK_Term * VOLK_literal_new(const char *data, VOLK_Term *datatype)
Shortcut to create a literal term.
VOLK_LinkMapIterator * VOLK_link_map_iter_new(const VOLK_LinkMap *lmap)
Create a new iterator to loop through a link map.
char * VOLK_iriref_prefix(const VOLK_Term *iri)
Get the prefix portion of a IRI ref.
VOLK_LinkMap * VOLK_link_map_new(const VOLK_Term *linked_term, VOLK_LinkType type)
New link map.
VOLK_Term * VOLK_default_datatype
Default literal data type URI.
VOLK_rc VOLK_link_map_triples(VOLK_LinkMapIterator *it, VOLK_Triple *spo)
Iterate over a link map and generate triples.
void VOLK_triple_done(VOLK_Triple *spo)
Free the internal pointers of a triple.
VOLK_rc VOLK_triple_init(VOLK_Triple *spo, VOLK_Term *s, VOLK_Term *p, VOLK_Term *o)
Initialize internal term pointers in a heap-allocated triple.
const VOLK_Term * VOLK_term_set_get(VOLK_TermSet *ts, VOLK_Key key)
Get a term from a term set.
VOLK_Term * VOLK_bnode_new(const char *data)
Shortcut to create a blank node.
VOLK_TermSet * VOLK_term_set_new()
Create a new term set.
uint32_t VOLK_default_dtype_key
Compiled hash of default literal data type.
void VOLK_term_set_free(VOLK_TermSet *ts)
Free a term set.
VOLK_Key VOLK_term_hash(const VOLK_Term *term)
Hash a buffer.
VOLK_rc VOLK_link_map_next(VOLK_LinkMapIterator *it, VOLK_Term **lt, VOLK_TermSet **ts)
Iterate through a link map.
void VOLK_link_map_free(VOLK_LinkMap *lm)
Free a link map.
VOLK_Term * VOLK_iriref_new_ns(const char *data)
Create an IRI reference from a namespace-prefixed string.
char * VOLK_iriref_path(const VOLK_Term *iri)
Get the path portion of a IRI ref.
char VOLK_LangTag[8]
Language tag, currently restricted to 7 characters.
void VOLK_term_free(VOLK_Term *term)
VOLK_Term * VOLK_triple_pos(const VOLK_Triple *trp, VOLK_TriplePos n)
Get triple by term position.
VOLK_Buffer * VOLK_term_serialize(const VOLK_Term *term)
Serialize a term into a buffer.
VOLK_Term * VOLK_default_ctx
Default context.
VOLK_Term * VOLK_term_new_from_buffer(const VOLK_Buffer *sterm)
See notes in VOLK_term_serialize function body for format info.
VOLK_rc VOLK_link_map_add(VOLK_LinkMap *lmap, VOLK_Term *term, VOLK_TermSet *tset)
Add a term - term set pair to a link map.
VOLK_LinkType VOLK_link_map_type(const VOLK_LinkMap *map)
Return the link map type.
VOLK_BufferTriple * VOLK_triple_serialize(const VOLK_Triple *spo)
VOLK_Term * VOLK_term_new(VOLK_TermType type, const char *data, void *metadata)
Create a new term.
VOLK_TermSet * VOLK_term_cache
Global term cache.
void VOLK_triple_free(VOLK_Triple *spo)
Free a triple and all its internal pointers.
VOLK_Term * VOLK_term_copy(const VOLK_Term *src)
Copy a term.
@ VOLK_LINK_EDGE
Edge link (so).
@ VOLK_LINK_INBOUND
Inbound link (sp).
@ VOLK_LINK_OUTBOUND
Outbound link (po).
@ VOLK_TERM_IRIREF
IRI reference.
@ VOLK_TERM_LT_LITERAL
Language-tagged string literal.
@ VOLK_TERM_LITERAL
Literal without language tag.
@ VOLK_TERM_BNODE
Blank node.
Key-term pair in term set.
VOLK_Term * term
Term handle.
VOLK_Key key
Key (hash) of the term.
Single link between a term and a term set.
KeyedTerm * term
Linked term.
VOLK_TermSet * tset
Term set linked to the term.
Match coordinates in IRI parsing results.
unsigned int size
Length of match.
unsigned int offset
Offset of match from start of string.
General-purpose data buffer.
Matching sub-patterns for IRI parts.
MatchCoord frag
Fragment (frag).
MatchCoord auth
Authority (example.org).
MatchCoord query
Query (query=blah).
MatchCoord prefix
Prefix (http://example.org).
MatchCoord scheme
Scheme (http).
VOLK_Term * linked_t
Linked term.
VOLK_LinkType type
Link type.
struct hashmap * links
Map of Link instances.
VOLK_Key bnode_id
BN ID for comparison & skolemization.
char * data
URI, literal value, or BNode label.
struct term_t * datatype
Data type IRI for VOLK_TERM_LITERAL.
VOLK_TermType type
Term type.
VOLK_LangTag lang
Lang tag for VOLK_TERM_LT_LITERAL.
Opaque link map iterator.
size_t i
Linking term loop cursor.
const VOLK_LinkMap * map
Link map to iterate.
const Link * link
Current link being retrieved.
size_t j
Term set loop cursor.