123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- /** @file store.h
- *
- * @brief Generic store dependency.
- *
- * This code allows to use the store interface with any supported back end
- * without any knowledge of the back end implementations. Code using the store
- * interface need only include this file.
- *
- * New store implementations should be added to this file as `#include`s as
- * well as entries in the `BACKEND_TBL` macro.
- */
- #ifndef _LSUP_STORE_H
- #define _LSUP_STORE_H
- /*
- * Add new back end headers here.
- */
- #include "lsup/store_htable.h"
- #include "lsup/store_mdb.h"
- /** @defgroup store Backend store module
- * @ingroup public
- * @{
- */
- /*
- * Define backend types.
- *
- * Add new store implementations to this table.
- */
- #define BACKEND_TBL \
- /* #enum suffix#store if */\
- ENTRY( HTABLE, htstore_int ) \
- ENTRY( MDB, mdbstore_int ) \
- /// Store types. All prefixed with `LSUP_STORE_`.
- typedef enum {
- #define ENTRY(a, b) \
- LSUP_STORE_##a,
- BACKEND_TBL
- #undef ENTRY
- } LSUP_StoreType;
- /** @brief Store structure.
- *
- * Code using the store interface should create an instance of this structure
- * with pointers to the store interface of their choice, and to an opaque
- * structure to hold the store state.
- *
- * Iterator state handles generated by lookup and add functions are kept
- * outside of this structure, but manipulated by the interface specified in
- * here.
- *
- * @sa #LSUP_graph_new()
- */
- typedef struct store_t {
- LSUP_StoreType type; ///< Store type.
- char * id; /**< Store ID.
- *
- * NOTE: This is
- * NULL for volatile stores.
- */
- const LSUP_StoreInt * sif; ///< Store interface.
- void * data; ///< Store back end data.
- } LSUP_Store;
- /** @brief Return store interface for a specific type.
- */
- const LSUP_StoreInt *
- LSUP_store_int (LSUP_StoreType type);
- /** @brief Return the store type label.
- *
- * @param type Store type enum.
- *
- * @return Store type label as `STORE_<type>`.
- */
- const char *
- LSUP_store_type_label (LSUP_StoreType type);
- /** @brief Create a new store.
- *
- * The life cycle of a store normally outspans the one of one or multiple
- * graphs with the same back end, hence it is managed independently.
- *
- * @param[in] store_type Type of store backing the graph. One of the values of
- * #LSUP_StoreType.
- *
- * @param[in] store_id Identifier for the store. This may be
- * interpreted differently by each store implementation. For the MDB store,
- * this is the file path where the store is located. It is ignored by volatile
- * stores (with LSUP_STORE_PERM feature flag set to false). If a store
- * does not exist for the given identifier, a new one is initialized. If this
- * parameter is NULL, the default store for the selected type is used.
- *
- * @param[in] size Initial size of the store. Only used for optimization
- * purposes. It may be ignored by some implementations and it is always safe
- * to set to 0.
- *
- * @param clear Flag that is passed to the `init_fn` function of the store
- * interface, if present, to clear an existing store with the same ID.
- *
- * @return Store handle. It must be freed with #LSUP_store_free().
- */
- LSUP_Store *
- LSUP_store_new (
- const LSUP_StoreType store_type, const char *store_id, size_t size,
- bool clear);
- /** @brief Free a store created with #LSUP_store_new().
- *
- * @param[in] store Store handle.
- */
- void
- LSUP_store_free (LSUP_Store *store);
- size_t
- LSUP_store_size (const LSUP_Store *store);
- /// Feature flags belonging to the store interface.
- const LSUP_StoreFeature
- LSUP_store_features (const LSUP_Store *store);
- /// Store identifier.
- char *
- LSUP_store_id (const LSUP_Store *store);
- /** @brief Begin a transaction.
- *
- * If the store supports it, begin a transaction. Only one transaction may be
- * opened at a time.
- *
- * The transaction must be either committed with #LSUP_store_commit() or
- * rolled back with #LSUP_store_abort().
- *
- * @param[in] store Store handle.
- *
- * @param[in] flags Unused for now, use 0. TODO
- *
- * @param[out] txn Address to be populated with the new transaction handle.
- *
- * @return LSUP_OK on success; LSUP_VALUE_ERR if the store does not
- * support transactions; LSUP_TXN_ERR if the store has already an uncommitted
- * transaction; <0 on other errors.
- */
- LSUP_rc
- LSUP_store_begin (LSUP_Store *store, int flags, void **txn);
- /** @brief Commit a transaction.
- *
- * If the store supports it, commit an open transaction. In case of
- * error, the transaction is left open and it is advisable to roll it back with
- * #LSUP_store_abort().
- *
- * @param[in] store Store handle.
- *
- * @param[in] txn transaction handle to commit.
- *
- * @return LSUP_OK if the transaction was committed successfully; LSUP_NOACTION
- * if NULL was passed; LSUP_TXN_ERR on error.
- */
- LSUP_rc
- LSUP_store_commit (LSUP_Store *store, void *txn);
- /** @brief Abort (roll back) a transaction.
- *
- * If the store supports it, abort an open transaction and abandon all changes.
- *
- * @param[in] store Store handle.
- *
- * @param[in] txn transaction handle to abort.
- */
- void
- LSUP_store_abort (LSUP_Store *store, void *txn);
- /** @brief Update the context of triples in a context-aware store.
- *
- * When a context URI is updated, all relationships of triples to that context
- * must be updated to reflect the new context.
- *
- * @param[in] store Store handle.
- *
- * @param[in] txn Transaction handle. If NULL, a new transaction is opened.
- * This is ignored by non-transactional back ends.
- *
- * @param[in] old_c Old context handle.
- *
- * @param[in] new_c New context handle.
- *
- * @return LSUP_OK on success; LSUP_NOACTION if no triples were found under the
- * given context; <0 on error.
- */
- LSUP_rc
- LSUP_store_update_ctx_txn (
- LSUP_Store *store, void *txn, const LSUP_Buffer *old_c,
- const LSUP_Buffer *new_c);
- #define LSUP_store_update_ctx(store, ...) \
- LSUP_store_update_txn (store, NULL, __VA_ARGS__)
- /** @brief Initialize bulk triple load.
- *
- * This is the first step of a bulk load. It is best used when the data at hand
- * need to be pre-processed, which can be done in the same loop as the next
- * step to keep memory usage low.
- *
- * @param[in] store The store to add to.
- *
- * @param[in] txn Transaction handle. If NULL, a new transaction is opened.
- * This is ignored by non-transactional back ends.
- *
- * @param[in] sc Context as a serialized term. If this is NULL, and the
- * default context is not NULL, triples will be added to the default context
- * for the store, If the default context for the store is NULL, regardless of
- * the value of sc, triples will be added with no context. Only meaningful
- * for stores with the LSUP_STORE_CTX feature.
- *
- * @return Iterator handle to be passed to the following load steps.
- */
- void *
- LSUP_store_add_init_txn (
- LSUP_Store *store, void *txn, const LSUP_Buffer *sc);
- /// Non-transactional version of #LSUP_store_add_init_txn().
- #define LSUP_store_add_init(store, ...) \
- LSUP_store_add_init_txn (store, NULL, __VA_ARGS__)
- /** @brief Add one triple into the store.
- *
- * This must be called after #store_add_init_fn_t, using the iterator
- * yielded by that function. It may be called multiple times and must be
- * followed by #store_add_done_fn_t or #store_add_abort_fn_t (if supported).
- *
- * @param[in] store Store handle.
- *
- * @param[in] it Iterator obtained by #LSUP_store_add_init().
- *
- * @param[in] sspo Serialized triple to be added.
- *
- * @return LSUP_OK if the triple was inserted; LSUP_NOACTION if the triple
- * already existed; LSUP_DB_ERR if an MDB error occurred.
- */
- LSUP_rc
- LSUP_store_add_iter (
- LSUP_Store *store, void *it, const LSUP_BufferTriple *sspo);
- /** @brief Abort an add loop and free iterator.
- *
- * Usually called on an irrecoverable error from #store_add_iter_fn_t. None of
- * the successful inserts in the same loop is retained.
- *
- * @param[in] store Store handle.
- *
- * @param[in] it Iterator obtained by #store_add_init_fn_t.
- */
- void
- LSUP_store_add_abort (LSUP_Store *store, void *it);
- /** @brief Finalize an add loop and free iterator.
- *
- * This must be called after #store_add_iter_fn_t.
- *
- * @param[in] store Store handle.
- *
- * @param[in] it Iterator obtained by #LSUP_store_add_init().
- *
- * @return LSUP_OK on success, <0 on failure. In the latter case, a transaction
- * may be aborted in a transactional back end.
- */
- LSUP_rc
- LSUP_store_add_done (LSUP_Store *store, void *it);
- /** @brief Add a single term to the store.
- *
- * @param[in] store Store handle.
- *
- * @param[in] txn Transaction handle. If NULL, a new transaction is opened.
- * This is ignored by non-transactional back ends.
- *
- * @param[in] sterm Serialized term to store.
- */
- LSUP_rc
- LSUP_store_add_term_txn (LSUP_Store *store, void *txn, LSUP_Buffer *sterm);
- /// Non-transactional version of #LSUP_store_add_term_txn().
- #define LSUP_store_add_term(store, ...) \
- LSUP_store_add_term_txn (store, NULL, __VA_ARGS__)
- /** @brief Look up triples by pattern matching.
- *
- * This function may return a count of matches and/or an iterator of results as
- * serialized triples.
- *
- * For stores with #LSUP_STORE_TXN, this opens a read-only transaction. The
- * transaction handle is held in the iterator structure and is closed when the
- * iterator is freed with #iter_free_fn_t().
- *
- * Any and all of the terms may be NULL, which indicates an unbound query
- * term. Stores witout context support will always ignore sc.
- *
- * @param[in] store The store to be queried.
- *
- * @param[in] txn Transaction handle. If NULL, a new transaction is opened.
- * This is ignored by non-transactional back ends.
- *
- * @param[in] ss Serialized s term.
- *
- * @param[in] sp Serialized p term.
- *
- * @param[in] so Serialized o term.
- *
- * @param[in] sc Serialized context to limit search to. It may be NULL, in
- * which case search is done in all contexts. Note that triples inserted
- * without context are assigned the *default* context for the store.
- *
- * @param[out] ct If not NULL, this will be populated with the number of
- * entries found. In some implementations, it is very inexpensive to set for
- * lookups without context, much less so for 1-bound and 2-bound context
- * lookups, in which cases it should be set only if needed.
- *
- * @return Iterator handle that will be populated with a result iterator. This
- * is always created even if no matches are found and must be freed with
- * #iter_free_fn_t() after use. If matches are found, the iterator points to
- * the first result which can be retrieved with #iter_next_fn_t.
- */
- void *
- LSUP_store_lookup_txn (
- const LSUP_Store *store, void *txn,
- const LSUP_Buffer *ss, const LSUP_Buffer *sp, const LSUP_Buffer *so,
- const LSUP_Buffer *sc, size_t *ct);
- /// Non-transactional version of #LSUP_store_lookup_txn().
- #define LSUP_store_lookup(store, ...) \
- LSUP_store_lookup_txn (store, NULL, __VA_ARGS__)
- /** @brief Yield the matching triples and advance the iterator.
- *
- * @note Iterators keep transactions open. Don't hold on to them longer than
- * necessary.
- *
- * @note If the store interface has the LSUP_STORE_COW feature, the memory
- * buffer referenced by the #LSUP_Buffer handle is owned by the database. It
- * must not be written to or freed. To modify the data or use them beyond the
- * caller's scope, this memory must be copied. Note that the #LSUP_Buffer
- * handle must still be freed (with a plain `free()`), but not the underlying
- * data buffer, since only the latter is owned by the back end. Implementations
- * with the `LSUP_STORE_COW` feature SHOULD create buffers with the
- * `LSUP_BUF_BORROWED` flag, so that they can be safely freed with
- * #LSUP_buffer_free() and #LSUP_btriple_free().
- *
- * @param[in] store Store handle.
- *
- * @param[in] it Opaque iterator handle obtained with #store_lookup_fn_t.
- *
- * @param[out] sspo #LSUP_BufferTriple to be populated with three serialized
- * terms if found. It may be NULL, in which case it is not populated.
- *
- * @param[out] ctx If not NULL, it is populated with a NULL-terminated array of
- * LSUP_Buffer structs, one for each context associated with the matching
- * triple. These contexts are the same regardless of the context filter used
- * in the lookup. The array is freed with a simple `free()`. This parameter
- * is ignored by implementations without the LSUP_STORE_CTX feature.
- *
- * To iterate over the context array, use this loop:
- *
- * size_t i = 0;
- * while (ctx[i].addr)
- * do_something(ctx + (i++));
- *
- * @return LSUP_OK if results were found; LSUP_END if no (more) results were
- * found; LSUP_DB_ERR if a backend error occurred.
- */
- LSUP_rc
- LSUP_store_iter_next (
- LSUP_Store *store, void *it, LSUP_BufferTriple *sspo,
- LSUP_Buffer **ctx);
- /** @brief Free an iterator allocated by a lookup.
- *
- * @param[in] store Store handle.
- *
- * @param[in] it Iterator pointer. It will be set to NULL after freeing.
- */
- void
- LSUP_store_iter_free (LSUP_Store *store, void *it);
- /** @brief Get iterator active transaction handle.
- *
- * This function is used to get an active transaction during an iteration loop
- * in order to perform an action using the store state within that loop. Some
- * stores (e.g. MDB) only support one R/W open transaction per thread, so this
- * is also the only way to perform anything else than iterating or committing
- * while a loop is open.
- *
- * @param[in] store Store handle.
- *
- * @param[in] it Iterator handle to get the transaction from.
- *
- * @return Transaction handle. DO NOT close this transaction directly.
- */
- void *
- LSUP_store_iter_txn (const LSUP_Store *store, void *it);
- /** @brief Delete triples by pattern matching.
- *
- * @param[in] store The store to be queried.
- *
- * @param[in] txn Transaction handle. If NULL, a new transaction is opened.
- * This is ignored by non-transactional back ends.
- *
- * @param[in] ss Serialized s term.
- *
- * @param[in] sp Serialized p term.
- *
- * @param[in] so Serialized o term.
- *
- * @param[in] sc Serialized context to limit search to. It may be NULL, in
- * which case search is done in all contexts. Note that triples inserted
- * without context are assigned the *default* context for the store.
- *
- * @param[out] ct If not NULL, this will be populated with the number of
- * triples actually deleted.
- *
- * @return LSUP_OK on success; LSUP_NOACTION if no triples were deleted;
- * <0 on error.
- *
- */
- LSUP_rc
- LSUP_store_remove_txn (
- LSUP_Store *store, void *txn,
- const LSUP_Buffer *ss, const LSUP_Buffer *sp, const LSUP_Buffer *so,
- const LSUP_Buffer *sc, size_t *ct);
- /// Non-transactional version of #LSUP_store_remove_txn().
- #define LSUP_store_remove(store, ...) \
- LSUP_store_remove_txn (store, NULL, __VA_ARGS__)
- /** @brief get index of all graph (context) URIs in a store.
- *
- * Only applicable to stores with the LSUP_STORE_CTX feature flag.
- *
- * @param[in] store Store handle.
- *
- * @param[in] txn Transaction handle. If NULL, a new transaction is opened.
- * This is ignored by non-transactional back ends.
- *
- * @return Set of all context URIs.
- */
- LSUP_Buffer **
- LSUP_store_ctx_list_txn (LSUP_Store *store, void *txn);
- /// Non-transactional version of #LSUP_store_ctx_list_txn().
- #define LSUP_store_ctx_list(store) \
- LSUP_store_ctx_list_txn (store, NULL)
- /// @} END store
- #endif /* LSUP_STORE_H */
|