/* * __curfile_equals -- * WT_CURSOR->equals method for the btree cursor type. */ static int __curfile_equals(WT_CURSOR *a, WT_CURSOR *b, int *equalp) { WT_CURSOR_BTREE *cbt; WT_DECL_RET; WT_SESSION_IMPL *session; cbt = (WT_CURSOR_BTREE *)a; CURSOR_API_CALL(a, session, equals, cbt->btree); /* * Check both cursors are a "file:" type then call the underlying * function, it can handle cursors pointing to different objects. */ if (!WT_PREFIX_MATCH(a->internal_uri, "file:") || !WT_PREFIX_MATCH(b->internal_uri, "file:")) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); WT_CURSOR_CHECKKEY(a); WT_CURSOR_CHECKKEY(b); ret = __wt_btcur_equals( (WT_CURSOR_BTREE *)a, (WT_CURSOR_BTREE *)b, equalp); err: API_END_RET(session, ret); }
/* * __curbulk_insert_row_skip_check -- * Row-store bulk cursor insert, without key-sort checks. */ static int __curbulk_insert_row_skip_check(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_DECL_RET; WT_SESSION_IMPL *session; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; /* * Bulk cursor inserts are updates, but don't need auto-commit * transactions because they are single-threaded and not visible * until the bulk cursor is closed. */ CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_FAST_DATA_INCR(session, cursor_insert_bulk); WT_CURSOR_CHECKKEY(cursor); WT_CURSOR_CHECKVALUE(cursor); ret = __wt_bulk_insert_row(session, cbulk); err: API_END_RET(session, ret); }
/* * __curindex_compare -- * WT_CURSOR->compare method for the index cursor type. */ static int __curindex_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) { WT_CURSOR_INDEX *cindex; WT_DECL_RET; WT_SESSION_IMPL *session; cindex = (WT_CURSOR_INDEX *)a; JOINABLE_CURSOR_API_CALL(a, session, compare, NULL); /* Check both cursors are "index:" type. */ if (!WT_PREFIX_MATCH(a->uri, "index:") || strcmp(a->uri, b->uri) != 0) WT_ERR_MSG(session, EINVAL, "Cursors must reference the same object"); WT_CURSOR_CHECKKEY(a); WT_CURSOR_CHECKKEY(b); ret = __wt_compare( session, cindex->index->collator, &a->key, &b->key, cmpp); err: API_END_RET(session, ret); }
/* * __curbulk_insert_fix -- * Fixed-length column-store bulk cursor insert. */ static int __curbulk_insert_fix(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_DECL_RET; WT_SESSION_IMPL *session; uint64_t recno; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; /* * Bulk cursor inserts are updates, but don't need auto-commit * transactions because they are single-threaded and not visible * until the bulk cursor is closed. */ CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_FAST_DATA_INCR(session, cursor_insert_bulk); /* * If the "append" flag was configured, the application doesn't have to * supply a key, else require a key. */ if (F_ISSET(cursor, WT_CURSTD_APPEND)) recno = cbulk->recno + 1; else { WT_CURSOR_CHECKKEY(cursor); if ((recno = cursor->recno) <= cbulk->recno) WT_ERR(__bulk_col_keycmp_err(cbulk)); } WT_CURSOR_CHECKVALUE(cursor); /* * Insert any skipped records as deleted records, update the current * record count. */ for (; recno != cbulk->recno + 1; ++cbulk->recno) WT_ERR(__wt_bulk_insert_fix(session, cbulk, true)); cbulk->recno = recno; /* Insert the current record. */ ret = __wt_bulk_insert_fix(session, cbulk, false); err: API_END_RET(session, ret); }
/* * __curbulk_insert_row -- * Row-store bulk cursor insert, with key-sort checks. */ static int __curbulk_insert_row(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_DECL_RET; WT_SESSION_IMPL *session; int cmp; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; /* * Bulk cursor inserts are updates, but don't need auto-commit * transactions because they are single-threaded and not visible * until the bulk cursor is closed. */ CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_FAST_DATA_INCR(session, cursor_insert_bulk); WT_CURSOR_CHECKKEY(cursor); WT_CURSOR_CHECKVALUE(cursor); /* * If this isn't the first key inserted, compare it against the last key * to ensure the application doesn't accidentally corrupt the table. */ if (!cbulk->first_insert) { WT_ERR(__wt_compare(session, btree->collator, &cursor->key, &cbulk->last, &cmp)); if (cmp <= 0) WT_ERR(__bulk_row_keycmp_err(cbulk)); } else cbulk->first_insert = false; /* Save a copy of the key for the next comparison. */ WT_ERR(__wt_buf_set(session, &cbulk->last, cursor->key.data, cursor->key.size)); ret = __wt_bulk_insert_row(session, cbulk); err: API_END_RET(session, ret); }
/* * __curbulk_insert_var -- * Variable-length column-store bulk cursor insert. */ static int __curbulk_insert_var(WT_CURSOR *cursor) { WT_BTREE *btree; WT_CURSOR_BULK *cbulk; WT_DECL_RET; WT_SESSION_IMPL *session; uint64_t recno; cbulk = (WT_CURSOR_BULK *)cursor; btree = cbulk->cbt.btree; /* * Bulk cursor inserts are updates, but don't need auto-commit * transactions because they are single-threaded and not visible * until the bulk cursor is closed. */ CURSOR_API_CALL(cursor, session, insert, btree); WT_STAT_FAST_DATA_INCR(session, cursor_insert_bulk); /* * If the "append" flag was configured, the application doesn't have to * supply a key, else require a key. */ if (F_ISSET(cursor, WT_CURSTD_APPEND)) recno = cbulk->recno + 1; else { WT_CURSOR_CHECKKEY(cursor); if ((recno = cursor->recno) <= cbulk->recno) WT_ERR(__bulk_col_keycmp_err(cbulk)); } WT_CURSOR_CHECKVALUE(cursor); if (!cbulk->first_insert) { /* * If not the first insert and the key space is sequential, * compare the current value against the last value; if the * same, just increment the RLE count. */ if (recno == cbulk->recno + 1 && cbulk->last.size == cursor->value.size && memcmp(cbulk->last.data, cursor->value.data, cursor->value.size) == 0) { ++cbulk->rle; ++cbulk->recno; goto duplicate; } /* Insert the previous key/value pair. */ WT_ERR(__wt_bulk_insert_var(session, cbulk, false)); } else cbulk->first_insert = false; /* * Insert any skipped records as deleted records, update the current * record count and RLE counter. */ if (recno != cbulk->recno + 1) { cbulk->rle = (recno - cbulk->recno) - 1; WT_ERR(__wt_bulk_insert_var(session, cbulk, true)); } cbulk->rle = 1; cbulk->recno = recno; /* Save a copy of the value for the next comparison. */ ret = __wt_buf_set(session, &cbulk->last, cursor->value.data, cursor->value.size); duplicate: err: API_END_RET(session, ret); }