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)) {
186 log_error (
"Unsupported term type: %d", src->
type);
200 void *metadata = NULL;
203 size_t cplen =
sizeof (type);
204 char *cpcur = (
char *)sterm->
addr;
205 memcpy (&type, cpcur, cplen);
209 cplen = strlen (cpcur) + 1;
210 data = malloc (cplen);
212 memcpy (data, cpcur, cplen);
217 if (strlen(cpcur) > 0)
221 metadata = malloc (cplen);
223 memcpy (metadata, cpcur, cplen);
239 log_error (
"Provided path is not an IRI.");
243 log_error (
"Provided root is not an IRI.");
251 if (strlen (pfx) > 0) data = iri->
data;
253 else if (iri->
data[0] ==
'/') {
257 data = malloc (strlen (iri->
data) + strlen (pfx) + 1);
258 if (!data)
return NULL;
260 sprintf (data,
"%s%s", pfx, iri->
data);
263 data = malloc (strlen (iri->
data) + strlen (root->
data) + 1);
264 if (!data)
return NULL;
266 sprintf (data,
"%s%s", root->
data, iri->
data);
271 if (data != iri->
data) free (data);
281 log_error (
"Provided path is not an IRI.");
285 log_error (
"Provided root is not an IRI.");
291 strlen (root->
data) : 0);
338 size_t cplen =
sizeof(term->
type);
339 memcpy (sterm->
addr, &term->
type, cplen);
343 cplen = strlen (term->
data) + 1;
344 memcpy (sterm->
addr + offset, term->
data, cplen);
354 sterm->
addr[offset] =
'\0';
357 cplen = strlen (term->
datatype->data) + 1;
358 sterm->
size += cplen;
366 sterm->
size += cplen;
405 log_error (
"Term is not a IRI ref type.");
422 log_error (
"Term is not a IRI ref type.");
438 log_error (
"Term is not a IRI ref type.");
458 if (!spo)
return NULL;
473 if (!spo)
return NULL;
487 if (!sspo)
return NULL;
553 tset_hash_fn, tset_cmp_fn, tset_free_fn, NULL);
554 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 (ins) *ins = ex->
term;
574 hashmap_set (ts, &entry_s);
575 if (hashmap_oom (ts)) {
580 if (ins) *ins = term;
590 else log_trace (
"No ID found for key %lx.", key);
592 return (entry) ? entry->
term : NULL;
600 if (!hashmap_iter (ts, i, (
void **)&kt))
return VOLK_END;
602 if (term) *term = kt->
term;
621 const KeyedTerm *res = hashmap_delete (ts, &kt_s);
637 if (!hashmap_iter (ts, &i, (
void **)&kt))
return NULL;
639 kt = hashmap_delete (ts, kt);
647{
return hashmap_count (ts); }
656 lm->
links = hashmap_new (
658 link_map_hash_fn, link_map_cmp_fn, link_map_free_fn, NULL);
660 log_error (
"term must not be NULL.");
673 hashmap_free (lm->
links);
692 const Link *ex = hashmap_get (lmap->
links, &(
Link){.term=&entry_s});
696 "Linking term %s exists. Adding individual terms.",
700 while (hashmap_iter (tset, &i, (
void **)&kt)) {
702 "Adding term %s to link %s",
704 if (hashmap_get (ex->
tset, kt))
709 hashmap_set (ex->
tset, kt);
719 memcpy (ins, &entry_s,
sizeof (entry_s));
720 Link link = {.term=ins, .tset=tset};
721 hashmap_set (lmap->
links, &link);
728VOLK_LinkMapIterator *
731 VOLK_LinkMapIterator *it;
748 if (!hashmap_iter (it->map->links, &it->i, (
void **)&it->link))
751 *lt = it->link->term->term;
752 *ts = it->link->tset;
765 spo->
o = it->map->linked_t;
767 spo->
s = it->map->linked_t;
768 else spo->
p = it->map->linked_t;
773 if (it->link)
goto int_loop;
777 if (!hashmap_iter (it->map->links, &it->i, (
void **)&it->link))
781 if (!hashmap_iter (it->link->tset, &it->j, (
void **)&kt))
goto ext_loop;
786 else spo->
p = it->link->term->term;
790 else spo->
o = kt->
term;
803 const char *data,
void *metadata)
814 term->
data = malloc (strlen (data) + 1);
816 strcpy (term->
data, data);
821 if (type < MIN_VALID_TYPE || type > MAX_VALID_TYPE) {
822 log_error (
"%d is not a valid term type.", type);
831 if (strpbrk (data, invalid_uri_chars) != NULL) {
833 "Characters %s are not valid in a URI. Got: %s\n",
834 invalid_uri_chars, data);
847 uuid_generate_random (uuid);
850 uuid_unparse_lower (uuid, uuid_str);
858 log_error (
"No data provided for term.");
865 log_warn (
"Lang tag is NULL. Creating a non-tagged literal.");
869 char *lang_str = (
char *) metadata;
870 log_trace (
"Lang string: '%s'", lang_str);
872 strncpy(term->
lang, lang_str, sizeof (term->
lang) - 1);
873 if (strlen (term->
lang) < 1) {
874 log_error (
"Lang tag cannot be an empty string.");
877 term->
lang[7] =
'\0';
887 "Literal data type is not an IRI: %s",
909 size_t iri_len = strlen (iri_str);
912 memset (iri_info, 0,
sizeof (*iri_info));
916 *cur !=
':' && *cur !=
'/' && *cur !=
'?'
917 && *cur !=
'#' && *cur !=
'\0') {
923 if (tmp.
size > 0 && *cur ==
':') {
929 }
else cur = iri_str;
932 if (*cur ==
'/' && *(cur + 1) ==
'/') {
934 tmp.
offset = cur - iri_str;
938 while (*cur !=
'/' && *cur !=
'?' && *cur !=
'#' && *cur !=
'\0') {
952 tmp.
offset = cur - iri_str;
960 while (*cur !=
'?' && *cur !=
'#' && *cur !=
'\0') {
968 tmp.
offset = ++cur - iri_str;
970 while (*cur !=
'#' && *cur !=
'\0') {
987 iri_info->
frag.
size = iri_str + iri_len - cur;
#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.
#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.
#define PRCCK(exp)
Return exp return value if it is of VOLK_rc type and negative (=error).
char * strdup(const char *src)
Replacement for GNU strdup.
char * strndup(const char *src, size_t max)
Replacement for GNU strndup.
#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_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_rc VOLK_term_set_remove(VOLK_TermSet *ts, VOLK_Term *term)
Remove a specific term from 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_Term * VOLK_term_set_pop(VOLK_TermSet *ts)
Pop a term from a term set.
VOLK_rc VOLK_term_set_add(VOLK_TermSet *ts, VOLK_Term *term, VOLK_Term **ins)
Add term to a term set.
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.
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.
size_t VOLK_Key
Term key, i.e., hash of a serialized term.
char uuid_str_t[37]
UUID string tpe.
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.
void * metadata
Generic metadata pointer.
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.