/* Copyright 2011-2020 David Robillard Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef SERD_CURSOR_H #define SERD_CURSOR_H #include "statement.h" #include "serd/serd.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 SerdQuad pattern, ScanStrategy strategy); SerdStatus serd_cursor_scan_next(SerdCursor* cursor); bool serd_iter_in_range(ZixBTreeIter iter, const SerdQuad pattern, ScanStrategy strategy); #endif // SERD_CURSOR_H