// Copyright 2011-2020 David Robillard // SPDX-License-Identifier: ISC #ifndef SERD_SRC_CURSOR_H #define SERD_SRC_CURSOR_H #include "serd/cursor.h" #include "serd/model.h" #include "serd/node.h" #include "serd/status.h" #include "zix/btree.h" #include #include #define N_STATEMENT_ORDERS 12u /// An iteration mode that determines what to skip and when to end typedef enum { SCAN_EVERYTHING, ///< Iterate over entire store SCAN_RANGE, ///< Iterate over range with equal prefix FILTER_EVERYTHING, ///< Iterate to end of store, filtering FILTER_RANGE, ///< Iterate over range with equal prefix, filtering } ScanMode; /// A strategy for searching and iterating over a statement index typedef struct { ScanMode mode; ///< Iteration mode unsigned n_prefix; ///< Number of prefix nodes that match the index SerdStatementOrder order; ///< Order of index to scan } ScanStrategy; struct SerdCursorImpl { const SerdModel* model; ///< Model being iterated over const SerdNode* pattern[4]; ///< Search pattern (nodes in model or null) size_t version; ///< Model version when iterator was created ZixBTreeIter iter; ///< Current position in index ScanStrategy strategy; ///< Index scanning strategy }; /// Lookup table of ordered indices for each SerdStatementOrder static const unsigned orderings[N_STATEMENT_ORDERS][4] = { {0U, 1U, 2U, 3U}, // SPOG {0U, 2U, 1U, 3U}, // SOPG {2U, 1U, 0U, 3U}, // OPSG {2U, 0U, 1U, 3U}, // OPSG {1U, 0U, 2U, 3U}, // PSOG {1U, 2U, 0U, 3U}, // PSOG {3U, 0U, 1U, 2U}, // GSPO {3U, 0U, 2U, 1U}, // GSPO {3U, 2U, 1U, 0U}, // GOPS {3U, 2U, 0U, 1U}, // GOPS {3U, 1U, 0U, 2U}, // GPSO {3U, 1U, 2U, 0U} // GPSO }; SerdCursor serd_cursor_make(const SerdModel* model, ZixBTreeIter iter, const SerdNode* const pattern[4], ScanStrategy strategy); SerdStatus serd_cursor_scan_next(SerdCursor* cursor); bool serd_iter_in_range(ZixBTreeIter iter, const SerdNode* const pattern[4], ScanStrategy strategy); #endif // SERD_SRC_CURSOR_H