Exemple #1
0
/*
 * __curfile_remove --
 *	WT_CURSOR->remove method for the btree cursor type.
 */
static int
__curfile_remove(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL(cursor, session, remove, cbt->btree);

	WT_CURSOR_NEEDKEY(cursor);
	WT_CURSOR_NOVALUE(cursor);

	WT_BTREE_CURSOR_SAVE_AND_RESTORE(cursor, __wt_btcur_remove(cbt), ret);

	/*
	 * After a successful remove, copy the key: the value is not available.
	 */
	if (ret == 0) {
		if (F_ISSET(cursor, WT_CURSTD_KEY_INT) &&
		    !WT_DATA_IN_ITEM(&(cursor)->key)) {
			WT_ERR(__wt_buf_set(session, &cursor->key,
			    cursor->key.data, cursor->key.size));
			F_CLR(cursor, WT_CURSTD_KEY_INT);
			F_SET(cursor, WT_CURSTD_KEY_EXT);
		}
		F_CLR(cursor, WT_CURSTD_VALUE_SET);
	}

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #2
0
/*
 * __curfile_insert --
 *	WT_CURSOR->insert method for the btree cursor type.
 */
static int
__curfile_insert(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL(cursor, session, insert, cbt->btree);
	if (!F_ISSET(cursor, WT_CURSTD_APPEND))
		WT_CURSOR_NEEDKEY(cursor);
	WT_CURSOR_NEEDVALUE(cursor);

	WT_BTREE_CURSOR_SAVE_AND_RESTORE(cursor, __wt_btcur_insert(cbt), ret);

	/*
	 * Insert is the one cursor operation that doesn't end with the cursor
	 * pointing to an on-page item. The standard macro handles errors
	 * correctly, but we need to leave the application cursor unchanged in
	 * the case of success, except for column-store appends, where we are
	 * returning a key.
	 */
	if (ret == 0) {
		if (!F_ISSET(cursor, WT_CURSTD_APPEND)) {
			F_SET(cursor, WT_CURSTD_KEY_EXT);
			F_CLR(cursor, WT_CURSTD_KEY_INT);
		}
		F_SET(cursor, WT_CURSTD_VALUE_EXT);
		F_CLR(cursor, WT_CURSTD_VALUE_INT);
	}

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #3
0
/*
 * __curds_insert --
 *	WT_CURSOR.insert method for the data-source cursor type.
 */
static int
__curds_insert(WT_CURSOR *cursor)
{
	WT_CURSOR *source;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source;

	CURSOR_UPDATE_API_CALL(cursor, session, insert);

	WT_ERR(__curds_txn_enter(session, true));

	WT_STAT_CONN_INCR(session, cursor_insert);
	WT_STAT_DATA_INCR(session, cursor_insert);
	WT_STAT_DATA_INCRV(session,
	    cursor_insert_bytes, cursor->key.size + cursor->value.size);

	if (!F_ISSET(cursor, WT_CURSTD_APPEND))
		WT_ERR(__curds_key_set(cursor));
	WT_ERR(__curds_value_set(cursor));
	ret = __curds_cursor_resolve(cursor, source->insert(source));

err:	__curds_txn_leave(session);

	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #4
0
/*
 * __curds_remove --
 *	WT_CURSOR.remove method for the data-source cursor type.
 */
static int
__curds_remove(WT_CURSOR *cursor)
{
	WT_CURSOR *source;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source;

	CURSOR_REMOVE_API_CALL(cursor, session, NULL);

	WT_STAT_CONN_INCR(session, cursor_remove);
	WT_STAT_DATA_INCR(session, cursor_remove);
	WT_STAT_DATA_INCRV(session, cursor_remove_bytes, cursor->key.size);

	WT_ERR(__curds_txn_enter(session, true));

	WT_ERR(__curds_key_set(cursor));
	ret = __curds_cursor_resolve(cursor, source->remove(source));

err:	__curds_txn_leave(session);

	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #5
0
/*
 * __curfile_remove --
 *	WT_CURSOR->remove method for the btree cursor type.
 */
static int
__curfile_remove(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_REMOVE_API_CALL(cursor, session, cbt->btree);
	WT_ERR(__cursor_checkkey(cursor));

	WT_ERR(__wt_btcur_remove(cbt));

	/*
	 * Remove with a search-key is fire-and-forget, no position and no key.
	 * Remove starting from a position maintains the position and a key.
	 * We don't know which it was at this layer, so can only assert the key
	 * is not set at all, or internal. There's never a value.
	 */
	WT_ASSERT(session,
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == 0 ||
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
	WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #6
0
/*
 * __curfile_modify --
 *	WT_CURSOR->modify method for the btree cursor type.
 */
static int
__curfile_modify(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL_BTREE(cursor, session, modify, cbt->btree);
	WT_ERR(__cursor_checkkey(cursor));

	/* Check for a rational modify vector count. */
	if (nentries <= 0)
		WT_ERR_MSG(session, EINVAL,
		    "Illegal modify vector with %d entries", nentries);

	WT_ERR(__wt_btcur_modify(cbt, entries, nentries));

	/*
	 * Modify maintains a position, key and value. Unlike update, it's not
	 * always an internal value.
	 */
	WT_ASSERT(session,
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
	WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) != 0);

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #7
0
/*
 * __curfile_insert --
 *	WT_CURSOR->insert method for the btree cursor type.
 */
static int
__curfile_insert(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL_BTREE(cursor, session, insert, cbt->btree);

	if (!F_ISSET(cursor, WT_CURSTD_APPEND))
		WT_ERR(__cursor_checkkey(cursor));
	WT_ERR(__cursor_checkvalue(cursor));

	WT_ERR(__wt_btcur_insert(cbt));

	/*
	 * Insert maintains no position, key or value (except for column-store
	 * appends, where we are returning a key).
	 */
	WT_ASSERT(session,
	    (F_ISSET(cursor, WT_CURSTD_APPEND) &&
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT) ||
	    (!F_ISSET(cursor, WT_CURSTD_APPEND) &&
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == 0));

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #8
0
/*
 * __curfile_insert --
 *	WT_CURSOR->insert method for the btree cursor type.
 */
static int
__curfile_insert(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL(cursor, session, insert, cbt->btree);
	if (!F_ISSET(cursor, WT_CURSTD_APPEND))
		WT_CURSOR_NEEDKEY(cursor);
	WT_CURSOR_NEEDVALUE(cursor);

	WT_BTREE_CURSOR_SAVE_AND_RESTORE(cursor, __wt_btcur_insert(cbt), ret);

	/*
	 * Insert is the one cursor operation that doesn't end with the cursor
	 * pointing to an on-page item (except for column-store appends, where
	 * we are returning a key). That is, the application's cursor continues
	 * to reference the application's memory after a successful cursor call,
	 * which isn't true anywhere else. We don't want to have to explain that
	 * scoping corner case, so we reset the application's cursor so it can
	 * free the referenced memory and continue on without risking subsequent
	 * core dumps.
	 */
	if (ret == 0) {
		if (!F_ISSET(cursor, WT_CURSTD_APPEND))
			F_CLR(cursor, WT_CURSTD_KEY_INT);
		F_CLR(cursor, WT_CURSTD_VALUE_INT);
	}

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #9
0
/*
 * __curds_remove --
 *	WT_CURSOR.remove method for the data-source cursor type.
*/
static int
__curds_remove(WT_CURSOR *cursor)
{
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	CURSOR_UPDATE_API_CALL(cursor, session, remove, NULL);

	WT_ERR(__curds_key_set(cursor));
	WT_ERR(cursor->data_source->remove(cursor->data_source));

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #10
0
/*
 * __curfile_remove --
 *	WT_CURSOR->remove method for the btree cursor type.
 */
static int
__curfile_remove(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL(cursor, session, remove, cbt->btree);
	WT_CURSOR_NEEDKEY(cursor);
	ret = __wt_btcur_remove((WT_CURSOR_BTREE *)cursor);
err:	CURSOR_UPDATE_API_END(session, ret);

	return (ret);
}
Exemple #11
0
/*
 * __wt_curfile_insert_check --
 *	WT_CURSOR->insert_check method for the btree cursor type.
 */
int
__wt_curfile_insert_check(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree);
	WT_ERR(__cursor_checkkey(cursor));

	ret = __wt_btcur_insert_check(cbt);

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #12
0
/*
 * __curfile_insert --
 *	WT_CURSOR->insert method for the btree cursor type.
 */
static int
__curfile_insert(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL(cursor, session, insert, cbt->btree);
	if (!F_ISSET(cursor, WT_CURSTD_APPEND))
		WT_CURSOR_NEEDKEY(cursor);
	WT_CURSOR_NEEDVALUE(cursor);
	ret = __wt_btcur_insert((WT_CURSOR_BTREE *)cursor);
err:	CURSOR_UPDATE_API_END(session, ret);

	return (ret);
}
Exemple #13
0
/*
 * __curfile_update --
 *	WT_CURSOR->update method for the btree cursor type.
 */
static int
__curfile_update(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL(cursor, session, update, cbt->btree);

	WT_CURSOR_NEEDKEY(cursor);
	WT_CURSOR_NEEDVALUE(cursor);

	WT_BTREE_CURSOR_SAVE_AND_RESTORE(cursor, __wt_btcur_update(cbt), ret);

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #14
0
/*
 * __curds_insert --
 *	WT_CURSOR.insert method for the data-source cursor type.
 */
static int
__curds_insert(WT_CURSOR *cursor)
{
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	CURSOR_UPDATE_API_CALL(cursor, session, insert, NULL);

	/* If not appending, we require a key. */
	if (!F_ISSET(cursor, WT_CURSTD_APPEND))
		WT_ERR(__curds_key_set(cursor));
	WT_ERR(__curds_value_set(cursor));
	WT_ERR(cursor->data_source->insert(cursor->data_source));

	/* If appending, we allocated a key. */
	if (F_ISSET(cursor, WT_CURSTD_APPEND))
		__curds_key_get(cursor);

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #15
0
/*
 * __curfile_update --
 *	WT_CURSOR->update method for the btree cursor type.
 */
static int
__curfile_update(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL_BTREE(cursor, session, update, cbt->btree);
	WT_ERR(__cursor_checkkey(cursor));
	WT_ERR(__cursor_checkvalue(cursor));

	WT_ERR(__wt_btcur_update(cbt));

	/* Update maintains a position, key and value. */
	WT_ASSERT(session,
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT &&
	    F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);

err:	CURSOR_UPDATE_API_END(session, ret);
	return (ret);
}
Exemple #16
0
/*
 * __curfile_reserve --
 *	WT_CURSOR->reserve method for the btree cursor type.
 */
static int
__curfile_reserve(WT_CURSOR *cursor)
{
	WT_CURSOR_BTREE *cbt;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	cbt = (WT_CURSOR_BTREE *)cursor;
	CURSOR_UPDATE_API_CALL_BTREE(cursor, session, reserve, cbt->btree);
	WT_ERR(__cursor_checkkey(cursor));

	WT_ERR(__wt_txn_context_check(session, true));

	WT_ERR(__wt_btcur_reserve(cbt));

	/*
	 * Reserve maintains a position and key, which doesn't match the library
	 * API, where reserve maintains a value. Fix the API by searching after
	 * each successful reserve operation.
	 */
	WT_ASSERT(session,
	    F_MASK(cursor, WT_CURSTD_KEY_SET) == WT_CURSTD_KEY_INT);
	WT_ASSERT(session, F_MASK(cursor, WT_CURSTD_VALUE_SET) == 0);

err:	CURSOR_UPDATE_API_END(session, ret);

	/*
	 * The application might do a WT_CURSOR.get_value call when we return,
	 * so we need a value and the underlying functions didn't set one up.
	 * For various reasons, those functions may not have done a search and
	 * any previous value in the cursor might race with WT_CURSOR.reserve
	 * (and in cases like LSM, the reserve never encountered the original
	 * key). For simplicity, repeat the search here.
	 */
	return (ret == 0 ? cursor->search(cursor) : ret);
}