Пример #1
0
SordIter*
sord_find(SordModel* sord, const SordQuad pat)
{
	if (!pat[0] && !pat[1] && !pat[2] && !pat[3])
		return sord_begin(sord);

	SearchMode      mode;
	int             n_prefix;
	const SordOrder index_order = sord_best_index(sord, pat, &mode, &n_prefix);

	SORD_FIND_LOG("Find " TUP_FMT "  index=%s  mode=%d  n_prefix=%d\n",
	              TUP_FMT_ARGS(pat), order_names[index_order], mode, n_prefix);

	if (pat[0] && pat[1] && pat[2] && pat[3])
		mode = SINGLE;  // No duplicate quads (Sord is a set)

	ZixBTree* const db  = sord->indices[index_order];
	ZixBTreeIter*   cur = NULL;
	zix_btree_lower_bound(db, pat, &cur);
	if (zix_btree_iter_is_end(cur)) {
		SORD_FIND_LOG("No match found\n");
		zix_btree_iter_free(cur);
		return NULL;
	}
	const SordNode** const key = (const SordNode**)zix_btree_get(cur);
	if (!key || ( (mode == RANGE || mode == SINGLE)
	              && !sord_quad_match_inline(pat, key) )) {
		SORD_FIND_LOG("No match found\n");
		zix_btree_iter_free(cur);
		return NULL;
	}

	return sord_iter_new(sord, cur, pat, index_order, mode, n_prefix);
}
Пример #2
0
static inline ZixTreeIter*
index_lower_bound(ZixTree* db, const SordQuad search_key)
{
	ZixTreeIter* iter = NULL;
	zix_tree_find(db, (const void*)search_key, &iter);
	if (!iter) {
		return NULL;
	}

	ZixTreeIter* prev = NULL;
	while ((prev = zix_tree_iter_prev(iter))) {
		if (!prev) {
			return iter;
		}

		const SordNode** const key = (const SordNode**)zix_tree_get(prev);
		if (!sord_quad_match_inline(key, search_key)) {
			return iter;
		}

		iter = prev;
	}

	return iter;
}
Пример #3
0
/**
   Seek forward as necessary until `iter` points at a match.
   @return true iff iterator reached end of valid range.
*/
static inline bool
sord_iter_seek_match(SordIter* iter)
{
	for (iter->end = true;
	     !zix_btree_iter_is_end(iter->cur);
	     sord_iter_forward(iter)) {
		const SordNode** const key = (const SordNode**)zix_btree_get(iter->cur);
		if (sord_quad_match_inline(key, iter->pat))
			return (iter->end = false);
	}
	return true;
}
Пример #4
0
static SordIter*
sord_iter_new(const SordModel* sord, ZixBTreeIter* cur, const SordQuad pat,
              SordOrder order, SearchMode mode, int n_prefix)
{
	SordIter* iter = (SordIter*)malloc(sizeof(SordIter));
	iter->sord        = sord;
	iter->cur         = cur;
	iter->order       = order;
	iter->mode        = mode;
	iter->n_prefix    = n_prefix;
	iter->end         = false;
	iter->skip_graphs = order < GSPO;
	for (int i = 0; i < TUP_LEN; ++i) {
		iter->pat[i] = pat[i];
	}

	switch (iter->mode) {
	case ALL:
	case SINGLE:
	case RANGE:
		assert(
			sord_quad_match_inline((const SordNode**)zix_btree_get(iter->cur),
			                       iter->pat));
		break;
	case FILTER_RANGE:
		sord_iter_seek_match_range(iter);
		break;
	case FILTER_ALL:
		sord_iter_seek_match(iter);
		break;
	}

#ifdef SORD_DEBUG_ITER
	SordQuad value;
	sord_iter_get(iter, value);
	SORD_ITER_LOG("New %p pat=" TUP_FMT " cur=" TUP_FMT " end=%d skip=%d\n",
	              (void*)iter, TUP_FMT_ARGS(pat), TUP_FMT_ARGS(value),
	              iter->end, iter->skip_graphs);
#endif

	++((SordModel*)sord)->n_iters;
	return iter;
}
Пример #5
0
/**
   Seek forward as necessary until `iter` points at a match, or the prefix
   no longer matches iter->pat.
   @return true iff iterator reached end of valid range.
*/
static inline bool
sord_iter_seek_match_range(SordIter* iter)
{
	if (iter->end)
		return true;

	do {
		const SordNode** key = (const SordNode**)zix_btree_get(iter->cur);

		if (sord_quad_match_inline(key, iter->pat))
			return false;  // Found match

		for (int i = 0; i < iter->n_prefix; ++i) {
			const int idx = orderings[iter->order][i];
			if (!sord_id_match(key[idx], iter->pat[idx])) {
				iter->end = true;  // Reached end of valid range
				return true;
			}
		}
	} while (!sord_iter_forward(iter));

	return (iter->end = true);  // Reached end
}
Пример #6
0
bool
sord_quad_match(const SordQuad x, const SordQuad y)
{
	return sord_quad_match_inline(x, y);
}