Exemplo n.º 1
0
SerdStatus
sord_erase(SordModel* sord, SordIter* iter)
{
	if (sord->n_iters > 1) {
		error(sord->world, SERD_ERR_BAD_ARG, "erased with many iterators\n");
	}

	SordQuad tup;
	sord_iter_get(iter, tup);

	SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup));

	SordNode* quad = NULL;
	for (unsigned i = 0; i < NUM_ORDERS; ++i) {
		if (sord->indices[i]) {
			if (zix_btree_remove(sord->indices[i], tup, (void**)&quad,
			                     i == iter->order ? &iter->cur : NULL)) {
				return (i == 0) ? SERD_ERR_NOT_FOUND : SERD_ERR_INTERNAL;
			}
		}
	}
	iter->end = zix_btree_iter_is_end(iter->cur);

	free(quad);

	for (int i = 0; i < TUP_LEN; ++i)
		sord_drop_quad_ref(sord, tup[i], (SordQuadIndex)i);

	--sord->n_quads;
	return SERD_SUCCESS;
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
void
sord_remove(SordModel* sord, const SordQuad tup)
{
	SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup));
	if (sord->n_iters > 0) {
		error(sord->world, SERD_ERR_BAD_ARG, "remove with iterator\n");
	}

	SordNode* quad = NULL;
	for (unsigned i = 0; i < NUM_ORDERS; ++i) {
		if (sord->indices[i]) {
			if (zix_btree_remove(sord->indices[i], tup, (void**)&quad, NULL)) {
				assert(i == 0);  // Assuming index coherency
				return;  // Quad not found, do nothing
			}
		}
	}

	free(quad);

	for (int i = 0; i < TUP_LEN; ++i)
		sord_drop_quad_ref(sord, tup[i], (SordQuadIndex)i);

	--sord->n_quads;
}
Exemplo n.º 4
0
bool
sord_add(SordModel* sord, const SordQuad tup)
{
	SORD_WRITE_LOG("Add " TUP_FMT "\n", TUP_FMT_ARGS(tup));
	if (!tup[0] || !tup[1] || !tup[2]) {
		error(sord->world, SERD_ERR_BAD_ARG,
		      "attempt to add quad with NULL field\n");
		return false;
	} else if (sord->n_iters > 0) {
		error(sord->world, SERD_ERR_BAD_ARG, "added tuple during iteration\n");
	}

	const SordNode** quad = (const SordNode**)malloc(sizeof(SordQuad));
	memcpy(quad, tup, sizeof(SordQuad));

	for (unsigned i = 0; i < NUM_ORDERS; ++i) {
		if (sord->indices[i]) {
			if (!sord_add_to_index(sord, quad, (SordOrder)i)) {
				assert(i == 0);  // Assuming index coherency
				free(quad);
				return false;  // Quad already stored, do nothing
			}
		}
	}

	for (int i = 0; i < TUP_LEN; ++i)
		sord_add_quad_ref(sord, tup[i], (SordQuadIndex)i);

	++sord->n_quads;
	return true;
}
Exemplo n.º 5
0
void
sord_remove(SordModel* sord, const SordQuad tup)
{
	SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup));

	SordNode** quad = NULL;
	for (unsigned i = 0; i < NUM_ORDERS; ++i) {
		if (sord->indices[i]) {
			ZixTreeIter* const cur = index_search(sord->indices[i], tup);
			if (!zix_tree_iter_is_end(cur)) {
				if (!quad) {
					quad = (SordNode**)zix_tree_get(cur);
				}
				zix_tree_remove(sord->indices[i], cur);
			} else {
				assert(i == 0);  // Assuming index coherency
				return;  // Quad not found, do nothing
			}
		}
	}

	free(quad);

	for (int i = 0; i < TUP_LEN; ++i)
		sord_drop_quad_ref(sord, tup[i], (SordQuadIndex)i);

	--sord->n_quads;
}
Exemplo n.º 6
0
bool
sord_iter_next(SordIter* iter)
{
	if (iter->end)
		return true;

	const SordNode** key;
	iter->end = sord_iter_forward(iter);
	if (!iter->end) {
		switch (iter->mode) {
		case ALL:
			// At the end if the cursor is (assigned above)
			break;
		case SINGLE:
			iter->end = true;
			SORD_ITER_LOG("%p reached single end\n", (void*)iter);
			break;
		case RANGE:
			SORD_ITER_LOG("%p range next\n", (void*)iter);
			// At the end if the MSNs no longer match
			key = (const SordNode**)zix_btree_get(iter->cur);
			assert(key);
			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;
					SORD_ITER_LOG("%p reached non-match end\n", (void*)iter);
					break;
				}
			}
			break;
		case FILTER_RANGE:
			// Seek forward to next match, stopping if prefix changes
			sord_iter_seek_match_range(iter);
			break;
		case FILTER_ALL:
			// Seek forward to next match
			sord_iter_seek_match(iter);
			break;
		}
	} else {
		SORD_ITER_LOG("%p reached index end\n", (void*)iter);
	}

	if (iter->end) {
		SORD_ITER_LOG("%p Reached end\n", (void*)iter);
		return true;
	} else {
#ifdef SORD_DEBUG_ITER
		SordQuad tup;
		sord_iter_get(iter, tup);
		SORD_ITER_LOG("%p Increment to " TUP_FMT "\n",
		              (void*)iter, TUP_FMT_ARGS(tup));
#endif
		return false;
	}
}
Exemplo n.º 7
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;
}