Example #1
0
/*
 * __cursor_truncate_fix --
 *	Discard a cursor range from fixed-width column-store tree.
 */
static int
__cursor_truncate_fix(WT_SESSION_IMPL *session,
    WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop,
    int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, int))
{
	WT_DECL_RET;
	uint8_t *value;

	/*
	 * Handle fixed-length column-store objects separately: for row-store
	 * and variable-length column-store objects we have "deleted" values
	 * and so returned objects actually exist: fixed-length column-store
	 * objects are filled-in if they don't exist, that is, if you create
	 * record 37, records 1-36 magically appear.  Those records can't be
	 * deleted, which means we have to ignore already "deleted" records.
	 *
	 * First, call the standard cursor remove method to do a full search and
	 * re-position the cursor because we don't have a saved copy of the
	 * page's write generation information, which we need to remove records.
	 * Once that's done, we can delete records without a full search, unless
	 * we encounter a restart error because the page was modified by some
	 * other thread of control; in that case, repeat the full search to
	 * refresh the page's modification information.
	 */
	if (start == NULL) {
		do {
			WT_RET(__wt_btcur_remove(stop));
			for (;;) {
				if ((ret = __wt_btcur_prev(stop, 1)) != 0)
					break;
				stop->compare = 0;	/* Exact match */
				value = (uint8_t *)stop->iface.value.data;
				if (*value != 0 &&
				    (ret = rmfunc(session, stop, 1)) != 0)
					break;
			}
		} while (ret == WT_RESTART);
	} else {
		do {
			WT_RET(__wt_btcur_remove(start));
			for (;;) {
				if (stop != NULL &&
				    __cursor_equals(start, stop))
					break;
				if ((ret = __wt_btcur_next(start, 1)) != 0)
					break;
				start->compare = 0;	/* Exact match */
				value = (uint8_t *)start->iface.value.data;
				if (*value != 0 &&
				    (ret = rmfunc(session, start, 1)) != 0)
					break;
			}
		} while (ret == WT_RESTART);
	}

	WT_RET_NOTFOUND_OK(ret);
	return (0);
}
Example #2
0
/*
 * __cursor_truncate --
 *	Discard a cursor range from row-store or variable-width column-store
 * tree.
 */
static int
__cursor_truncate(WT_SESSION_IMPL *session,
    WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop,
    int (*rmfunc)(WT_SESSION_IMPL *, WT_CURSOR_BTREE *, int))
{
	WT_DECL_RET;

	/*
	 * First, call the standard cursor remove method to do a full search and
	 * re-position the cursor because we don't have a saved copy of the
	 * page's write generation information, which we need to remove records.
	 * Once that's done, we can delete records without a full search, unless
	 * we encounter a restart error because the page was modified by some
	 * other thread of control; in that case, repeat the full search to
	 * refresh the page's modification information.
	 *
	 * If this is a row-store, we delete leaf pages having no overflow items
	 * without reading them; for that to work, we have to ensure we read the
	 * page referenced by the ending cursor, since we may be deleting only a
	 * partial page at the end of the truncation.  Our caller already fully
	 * instantiated the end cursor, so we know that page is pinned in memory
	 * and we can proceed without concern.
	 */
	if (start == NULL) {
		do {
			WT_RET(__wt_btcur_remove(stop));
			for (;;) {
				if ((ret = __wt_btcur_prev(stop, 1)) != 0)
					break;
				stop->compare = 0;	/* Exact match */
				if ((ret = rmfunc(session, stop, 1)) != 0)
					break;
			}
		} while (ret == WT_RESTART);
	} else {
		do {
			WT_RET(__wt_btcur_remove(start));
			/*
			 * Reset ret each time through so that we don't loop
			 * forever in the cursor equals case.
			 */
			for (ret = 0;;) {
				if (stop != NULL &&
				    __cursor_equals(start, stop))
					break;
				if ((ret = __wt_btcur_next(start, 1)) != 0)
					break;
				start->compare = 0;	/* Exact match */
				if ((ret = rmfunc(session, start, 1)) != 0)
					break;
			}
		} while (ret == WT_RESTART);
	}

	WT_RET_NOTFOUND_OK(ret);
	return (0);
}