store.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /** @file store.h
  2. *
  3. * @brief Store back end interfaces.
  4. *
  5. * The basic interfaces for store and store iterator implementations are
  6. * defined here. New store implementations should include this header and
  7. * implement four basic elements:
  8. *
  9. * - A structure representing the store back end and one for the iterator.
  10. * These structures will be opaque to all external modules and their layouts
  11. * are entirely up to the implementer.
  12. *
  13. * - The LSUP_StoreInt and LSUP_StoreIteratorInt interfaces as well as the
  14. * functions defined in the interfaces necessary to interact with the store.
  15. *
  16. * See the `store_htable.{c,h}` and `store_mdb.{c,h}` files for examples of
  17. * fully functioning implementations.
  18. *
  19. * The #LSUP_Store structure defines a store back end for raw buffer triples.
  20. * Nothing in the store should hint at RDF triples—it should accept and output
  21. * exclusively raw byte buffers (LSUP_Buffer). A store may have any of the
  22. * `LSUP_STORE_*` faeture flags which should be reflected by how its members
  23. * are implemented.
  24. *
  25. * The #LSUP_StoreIterator structure defines a store iterator implementation
  26. * that is designed to work with the store implementation. It must define a
  27. * "next" function for retrieving a triple in a lookup and a "free" function
  28. * to deallocate the iterator after use. Functions for creating iterators for
  29. * lookup and incremental addition are defined in the associated store.
  30. */
  31. #ifndef _LSUP_STORE_H
  32. #define _LSUP_STORE_H
  33. #include "namespace.h"
  34. #include "data/bootstrap.h"
  35. /*
  36. * Store feature flags.
  37. *
  38. * NOTE: LSUP_STORE_PERM need only be set by an implementation based on whether
  39. * its path is on a default temporary dir (e.g. LSUP_MDB_RAMDISK_PATH). If this
  40. * flag is not set, it means the data will be cleared before the next execution
  41. * of the program. However, its being set does not guarantee the persistence of
  42. * the medium (i.e. a "permanent" store may have been created ad hoc on a
  43. * tempfs).
  44. */
  45. #define LSUP_STORE_PERM 1<<0 /// Store is on a permanent location.
  46. #define LSUP_STORE_CTX 1<<1 /// Store supports contexts (quads).
  47. #define LSUP_STORE_IDX 1<<2 /// Store is fully SPO(C)-indexed.
  48. #define LSUP_STORE_TXN 1<<3 /// Supports manual transaction handling.
  49. #define LSUP_STORE_NET 1<<4 /// Store is over a network protocol.
  50. /*
  51. * Iterator function types.
  52. */
  53. /** @brief Prototype: yield the matching triples and advance the iterator.
  54. *
  55. * NOTE: Iterators keep transactions open. Don't hold on to them longer than
  56. * necessary.
  57. *
  58. * NOTE: The memory pointed to by the individual LSUP_Buffer pointers is
  59. * owned by the database. It must not be written to or freed. To modify
  60. * the data or use them beyond the caller's scope, this memory must be copied.
  61. *
  62. * @param[in] it Opaque iterator handle obtained with the store's #lookup_fn.
  63. *
  64. * @param[out] sspo #LSUP_BufferTriple to be populated with three serialized
  65. * terms if found, NULL if not found. Internal callers (e.g. counters) may pass
  66. * NULL if they don't need the serialized triples.
  67. *
  68. * @param[out] ctx If not NULL, it is populated with a NULL-terminated array of
  69. * LSUP_Buffer structs, one for each context associated with the matching
  70. * triple. These contexts are the same regardless of the context filter used
  71. * in the lookup. The array is freed with a simple #free(). This parameter
  72. * is ignored by implementations without the LSUP_STORE_CTX feature.
  73. *
  74. * To iterate over the context array, use this loop:
  75. *
  76. * size_t i = 0;
  77. * while (ctx[i].addr)
  78. * do_something(ctx + i++); // Buffer data are RO.
  79. *
  80. * @return LSUP_OK if results were found; LSUP_END if no (more) results were
  81. * found; LSUP_DB_ERR if a backend error occurred.
  82. */
  83. typedef LSUP_rc (*iter_next_fn_t)(
  84. void *it, LSUP_BufferTriple *sspo, LSUP_Buffer **ctx);
  85. /** @brief Prototype: free an iterator allocated by a lookup.
  86. *
  87. * @param it[in] Iterator pointer. It will be set to NULL after freeing.
  88. */
  89. typedef void (*iter_free_fn_t)(void * it);
  90. /*
  91. * Store function types.
  92. */
  93. /** @brief Prototype: create any environment necessary for the store to work.
  94. *
  95. * @param[in] clear Whether to remove a previous environment at this location.
  96. *
  97. * @param[in,out] path Path of the suggested directory to use. It may be NULL,
  98. * in which case it will be set either to the environment variable
  99. * LSUP_STORE_PATH, or if that is not set, a default local path.
  100. */
  101. typedef LSUP_rc (*store_setup_fn_t)(const char *path, bool clear);
  102. /** @brief Prototype: create a new store.
  103. *
  104. * @param[in] Location for the new store. This depends on the implementation,
  105. * which may ignore it (e.g. an in-memory store). Implementations should
  106. * provide instructions on how to use and interpret this parameter.
  107. *
  108. * @param[in] default_ctx Default context IRI (serialized). It should only be
  109. * considered by implementations with the LSUP_STORE_CTX feature.
  110. *
  111. * @return New store handle.
  112. */
  113. typedef void * (*store_new_fn_t)(
  114. const char *location, const LSUP_Buffer *default_ctx);
  115. /** @brief Prototype: free store handle.
  116. *
  117. * @param[in] store Store handle.
  118. *
  119. */
  120. typedef void (*store_free_fn_t)(void *store);
  121. /** @brief Prototype: get store size.
  122. *
  123. * @param store[in] The store to calculate size of.
  124. *
  125. * @return Number of stored SPO triples (across all contexts if supported).
  126. */
  127. typedef size_t (*store_size_fn_t)(void *store);
  128. /** @brief Print stats about a store.
  129. *
  130. * TODO
  131. *
  132. * @param store[in] The store to get stats for.
  133. */
  134. /* TODO
  135. typedef LSUP_rc (*store_stat_fn_t)(void *store, void *stat);
  136. */
  137. /** @brief Initialize bulk triple load.
  138. *
  139. * This is the first step of a bulk load. It is best used when the data at hand
  140. * need to be pre-processed, which can be done in the same loop as the next
  141. * step to keep memory usage low.
  142. *
  143. * @param store[in] The store to add to.
  144. *
  145. * @param sc[in] Context as a serialized term. If this is NULL, and the
  146. * default context is not NULL, triples will be added to the default context
  147. * for the store, If the default context for the store is NULL, regardless of
  148. * the value of sc, triples will be added with no context. Only meaningful
  149. * for stores with the LSUP_STORE_CTX feature.
  150. *
  151. * @return Iterator handle to be passed to the following load steps.
  152. */
  153. typedef void * (*store_add_init_fn_t)(void *store, const LSUP_Buffer * sc);
  154. /** @brief Add one triple into the store.
  155. *
  156. * This must be called after #add_init_fn, using the iterator
  157. * yielded by that function. It may be called multiple times and must be
  158. * followed by #add_done_fn or #add_abort_fn (if supported).
  159. *
  160. * @param it[in] Iterator obtained by #LSUP_mdbstore_add_init.
  161. * The following members are of interest:
  162. * it->i stores the total number of records inserted.
  163. *
  164. * @param sspo[in] Serialized triple to be added.
  165. *
  166. * @return LSUP_OK if the triple was inserted; LSUP_NOACTION if the triple
  167. * already existed; LSUP_DB_ERR if an MDB error occurred.
  168. */
  169. typedef LSUP_rc (*store_add_iter_fn_t)(void *it, const LSUP_BufferTriple * sspo);
  170. /** @brief Abort an add loop and free iterator.
  171. *
  172. * Usually called on an irrecoverable error from #add_iter_fn. None of the
  173. * successful inserts in the same loop is retained.
  174. *
  175. * @param it[in] Iterator obtained by #LSUP_mdbstore_add_init.
  176. */
  177. typedef void (*store_add_abort_fn_t)(void *it);
  178. /** @brief Finalize an add loop and free iterator.
  179. *
  180. * This must be called after #add_iter_fn.
  181. *
  182. * @param it[in] Iterator obtained by #LSUP_mdbstore_add_init.
  183. */
  184. typedef LSUP_rc (*store_add_done_fn_t)(void *it);
  185. /** @brief Add a single term to the store.
  186. *
  187. * @param[in] store Store handle.
  188. *
  189. * @param[in] sterm Serialized term to store.
  190. */
  191. typedef LSUP_rc (*store_add_term_fn_t)(void *store, const LSUP_Buffer *sterm);
  192. /** @brief Prototype: look up triples by pattern matching.
  193. *
  194. * This function may return a count of matches and/or an iterator of results as
  195. * serialized triples.
  196. *
  197. * Any and all of the terms may be NULL, which indicates an unbound query
  198. * term. Stores with context not set or witout context support will always
  199. * ignore the fourth term.
  200. *
  201. * @param[in] store The store to be queried.
  202. *
  203. * @param[in] ss Buffer representing the serialized s term.
  204. *
  205. * @param[in] sp Buffer representing the serialized p term.
  206. *
  207. * @param[in] so Buffer representing the serialized o term.
  208. *
  209. * @param[in] sc Serialized context to limit search to. It may be NULL, in
  210. * which case search is done in all contexts. Note that triples inserted
  211. * without context are assigned the *default* context for the store.
  212. *
  213. * @param[out] ct If not NULL, this will be populated with the number of
  214. * entries found. It is very inexpensive to set for lookups without context,
  215. * much less so for 1-bound and 2-bound context lookups, in which cases it
  216. * should be set only if needed.
  217. *
  218. * @return Iterator handle that will be populated with a result iterator. This
  219. * is always created even if no matches are found and must be freed with
  220. * #LSUP_mdbiter_free() after use. If matches are found, the iterator points to
  221. * the first result which can be retrieved with #iter_next_fn().
  222. */
  223. typedef void * (*store_lookup_fn_t)(
  224. void *store,
  225. const LSUP_Buffer *ss, const LSUP_Buffer *sp, const LSUP_Buffer *so,
  226. const LSUP_Buffer *sc, size_t *ct);
  227. /** @brief Prototype: delete triples by pattern matching.
  228. *
  229. * The ss, sp, so, sc terms act as a matching pattern as documented in
  230. * #store_lookup_fn. if not NULL, ct yields the number of triples actually
  231. * deleted.
  232. */
  233. typedef LSUP_rc (*store_remove_fn_t)(
  234. void *store,
  235. const LSUP_Buffer *ss, const LSUP_Buffer *sp, const LSUP_Buffer *so,
  236. const LSUP_Buffer *sc, size_t *ct);
  237. /** @brief Put an in-memory namespace map into a permanent back end.
  238. *
  239. * This is only available in stores with the LSUP_STORE_PERM feature.
  240. *
  241. * Existing prefixes and namespaces are not updated. Thus, if the following are
  242. * already stored:
  243. *
  244. * ns1: <urn:ns:a#>
  245. * ns2: <urn:ns:b#>
  246. *
  247. * Neither of the following will be inserted:
  248. *
  249. * ns3: <urn:ns:a#>
  250. * ns2: <urn:ns:c#>
  251. *
  252. * @param[in] store MDB store to update.
  253. *
  254. * @param[out] nsm Namespace map handle to store.
  255. *
  256. * @return LSUP_OK if all terms were updated; LSUP_CONFLICT if one or more
  257. * namespaces or terms were not updated because they already existed; <0 if
  258. * an error occurred.
  259. */
  260. typedef LSUP_rc (*store_nsm_put_fn_t)(void *store, const LSUP_NSMap * nsm);
  261. /** @brief Get the store's namespace prefix map.
  262. *
  263. * @param[in] store MDB store to query.
  264. *
  265. * @return NS map or NULL on error.
  266. */
  267. typedef LSUP_NSMap * (*store_nsm_get_fn_t)(void *store);
  268. /*
  269. * Iterface type definitions.
  270. */
  271. /** @brief Store interface.
  272. */
  273. typedef struct store_t {
  274. // Basic properties.
  275. char name[16]; ///> Store type name.
  276. int features; ///> Feature flags.
  277. // Allocation, setup and deallocation.
  278. store_setup_fn_t setup_fn; ///> Optional function called before
  279. ///> new_fn.
  280. store_new_fn_t new_fn; ///> Create a new store instance.
  281. store_free_fn_t free_fn; ///> Free the store.
  282. // Metadata.
  283. store_size_fn_t size_fn; ///> Number of triples in the store.
  284. //store_stat_fn stat_fn; ///> Store statistics. Optional.
  285. // Addition.
  286. store_add_init_fn_t add_init_fn; ///> Initialize add iteration.
  287. store_add_iter_fn_t add_iter_fn; ///> Add one triple.
  288. store_add_abort_fn_t add_abort_fn; ///> Abort (roll back) the add process.
  289. ///> Only available in stores with
  290. ///> LSUP_STORE_TXN feature.
  291. ///> Optional.
  292. store_add_done_fn_t add_done_fn; ///> Complete the add process.
  293. store_add_term_fn_t add_term_fn; ///> Add (index) a term to the store.
  294. ///> Only available in stores with
  295. ///> LSUP_STORE_IDX feature.
  296. ///> Optional.
  297. // Look up.
  298. store_lookup_fn_t lookup_fn; ///> Look up triples by pattern.
  299. // Removal.
  300. store_remove_fn_t remove_fn; ///> Remove triples by pattern.
  301. // Namespace prefix mapping.
  302. store_nsm_put_fn_t nsm_put_fn; ///> Add a namespace/prefix pair to
  303. ///> the prefix map.
  304. ///> Only available (and mandatory)
  305. ///> in stores with the
  306. ///> LSUP_STORE_IDX feature.
  307. store_nsm_get_fn_t nsm_get_fn; ///> Get a namespace/prefix from
  308. ///> the prefix map.
  309. ///> Only available (and mandatory)
  310. ///> in stores with the
  311. ///> LSUP_STORE_IDX feature.
  312. } LSUP_StoreInt;
  313. /** @brief Store iterator interface.
  314. */
  315. typedef struct store_it_t {
  316. char name[16]; ///> Iterator type name.
  317. iter_next_fn_t iter_fn; ///> Advance to next step and yield
  318. ///> one triple key if found.
  319. iter_free_fn_t free_fn; ///> Free the iterator.
  320. } LSUP_StoreIteratorInt;
  321. /*
  322. * Template for a new store and iterator implementation.
  323. * These should be placed in the .c file where the interface functions are
  324. * defined, and declared as `extern` in the related .h file.
  325. const LSUP_StoreInt my_store_int = {
  326. .name = "My Store", // Truncated to 15 chars.
  327. .features = LSUP_STORE_PERM | LSUP_STORE_IDX,
  328. .setup_fn = my_setup_fn,
  329. .new_fn = my_new_fn,
  330. .free_fn = my_free_fn,
  331. .size_fn = my_size_fn,
  332. .add_init_fn = my_init_fn,
  333. .add_iter_fn = my_iter_fn,
  334. .add_abort_fn = my_add_abort_fn,
  335. .add_done_fn = my_add_done_fn,
  336. .add_term_fn = my_add_term_fn,
  337. .lookup_fn = my_lookup_fn,
  338. .remove_fn = my_remove_fn,
  339. .nsm_put_fn = my_nsm_put_fn,
  340. .nsm_get_fn = my_nsm_get_fn,
  341. };
  342. const LSUP_StoreIteratorInt my_it_int = {
  343. .name = "My Iterator",
  344. .iter_next_fn_t = my_iter_next_fn,
  345. .iter_free_fn_t = my_iter_free_fn,
  346. };
  347. */
  348. #endif /* _LSUP_STORE_H */