本文整理汇总了C++中WT_CURSOR::prev方法的典型用法代码示例。如果您正苦于以下问题:C++ WT_CURSOR::prev方法的具体用法?C++ WT_CURSOR::prev怎么用?C++ WT_CURSOR::prev使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WT_CURSOR
的用法示例。
在下文中一共展示了WT_CURSOR::prev方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1:
/*
* __curindex_search_near --
* WT_CURSOR->search_near method for index cursors.
*/
static int
__curindex_search_near(WT_CURSOR *cursor, int *exact)
{
WT_CURSOR *child;
WT_CURSOR_INDEX *cindex;
WT_DECL_RET;
WT_ITEM found_key;
WT_SESSION_IMPL *session;
int cmp;
cindex = (WT_CURSOR_INDEX *)cursor;
child = cindex->child;
JOINABLE_CURSOR_API_CALL(cursor, session, search, NULL);
/*
* We are searching using the application-specified key, which
* (usually) doesn't contain the primary key, so it is just a prefix of
* any matching index key. That said, if there is an exact match, we
* want to find the first matching index entry and set exact equal to
* zero.
*
* Do a search_near, and if we find an entry that is too small, step to
* the next one. In the unlikely event of a search past the end of the
* tree, go back to the last key.
*/
__wt_cursor_set_raw_key(child, &cursor->key);
WT_ERR(child->search_near(child, &cmp));
if (cmp < 0) {
if ((ret = child->next(child)) == WT_NOTFOUND)
ret = child->prev(child);
WT_ERR(ret);
}
/*
* We expect partial matches, and want the smallest record with a key
* greater than or equal to the search key.
*
* If the found key starts with the search key, we indicate a match by
* setting exact equal to zero.
*
* The compare function expects application-supplied keys to come first
* so we flip the sign of the result to match what callers expect.
*/
found_key = child->key;
if (found_key.size > cursor->key.size)
found_key.size = cursor->key.size;
WT_ERR(__wt_compare(
session, cindex->index->collator, &cursor->key, &found_key, exact));
*exact = -*exact;
WT_ERR(__curindex_move(cindex));
if (0) {
err: F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT);
}
API_END_RET(session, ret);
}
示例2: find_table_count
/*
* Ensure that icount matches the number of records in the
* existing table.
*/
int find_table_count(CONFIG *cfg)
{
WT_CONNECTION *conn;
WT_CURSOR *cursor;
WT_SESSION *session;
char *key;
int ret;
conn = cfg->conn;
if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) {
lprintf(cfg, ret, 0,
"open_session failed finding existing table count");
goto err;
}
if ((ret = session->open_cursor(session, cfg->uri,
NULL, NULL, &cursor)) != 0) {
lprintf(cfg, ret, 0,
"open_cursor failed finding existing table count");
goto err;
}
if ((ret = cursor->prev(cursor)) != 0) {
lprintf(cfg, ret, 0,
"cursor prev failed finding existing table count");
goto err;
}
cursor->get_key(cursor, &key);
cfg->icount = (uint32_t)atoi(key);
err: session->close(session, NULL);
return (ret);
}
示例3: cursor
boost::optional<RecordId> WiredTigerRecordStore::oplogStartHack(
OperationContext* txn, const RecordId& startingPosition) const {
if (!_useOplogHack)
return boost::none;
{
WiredTigerRecoveryUnit* wru = WiredTigerRecoveryUnit::get(txn);
_oplogSetStartHack(wru);
}
WiredTigerCursor cursor(_uri, _tableId, true, txn);
WT_CURSOR* c = cursor.get();
int cmp;
c->set_key(c, _makeKey(startingPosition));
int ret = WT_OP_CHECK(c->search_near(c, &cmp));
if (ret == 0 && cmp > 0)
ret = c->prev(c); // landed one higher than startingPosition
if (ret == WT_NOTFOUND)
return RecordId(); // nothing <= startingPosition
invariantWTOK(ret);
int64_t key;
ret = c->get_key(c, &key);
invariantWTOK(ret);
return _fromKey(key);
}
示例4:
/*
* __wt_bloom_open --
* Open a Bloom filter object for use by a single session. The filter must
* have been created and finalized.
*/
int
__wt_bloom_open(WT_SESSION_IMPL *session,
const char *uri, uint32_t factor, uint32_t k,
WT_CURSOR *owner, WT_BLOOM **bloomp)
{
WT_BLOOM *bloom;
WT_CURSOR *c;
WT_DECL_RET;
uint64_t size;
WT_RET(__bloom_init(session, uri, NULL, &bloom));
WT_ERR(__bloom_open_cursor(bloom, owner));
c = bloom->c;
/* Find the largest key, to get the size of the filter. */
WT_ERR(c->prev(c));
WT_ERR(c->get_key(c, &size));
WT_ERR(c->reset(c));
WT_ERR(__bloom_setup(bloom, 0, size, factor, k));
*bloomp = bloom;
return (0);
err: (void)__wt_bloom_close(bloom);
return (ret);
}
示例5: next
boost::optional<Record> next() final {
if (_eof)
return {};
WT_CURSOR* c = _cursor->get();
bool mustAdvance = true;
if (_lastReturnedId.isNull() && !_forward && _rs._isCapped) {
// In this case we need to seek to the highest visible record.
const RecordId reverseCappedInitialSeekPoint =
_readUntilForOplog.isNull() ? _rs.lowestCappedHiddenRecord() : _readUntilForOplog;
if (!reverseCappedInitialSeekPoint.isNull()) {
c->set_key(c, _makeKey(reverseCappedInitialSeekPoint));
int cmp;
int seekRet = WT_OP_CHECK(c->search_near(c, &cmp));
if (seekRet == WT_NOTFOUND) {
_eof = true;
return {};
}
invariantWTOK(seekRet);
// If we landed at or past the lowest hidden record, we must advance to be in
// the visible range.
mustAdvance = _rs.isCappedHidden(reverseCappedInitialSeekPoint)
? (cmp >= 0)
: (cmp > 0); // No longer hidden.
}
}
if (mustAdvance) {
// Nothing after the next line can throw WCEs.
// Note that an unpositioned (or eof) WT_CURSOR returns the first/last entry in the
// table when you call next/prev.
int advanceRet = WT_OP_CHECK(_forward ? c->next(c) : c->prev(c));
if (advanceRet == WT_NOTFOUND) {
_eof = true;
return {};
}
invariantWTOK(advanceRet);
}
int64_t key;
invariantWTOK(c->get_key(c, &key));
const RecordId id = _fromKey(key);
if (!isVisible(id)) {
_eof = true;
return {};
}
WT_ITEM value;
invariantWTOK(c->get_value(c, &value));
_lastReturnedId = id;
return {{id, {static_cast<const char*>(value.data), static_cast<int>(value.size)}}};
}
示例6: restore
bool restore() final {
if (!_cursor)
_cursor.emplace(_rs.getURI(), _rs.tableId(), true, _txn);
// This will ensure an active session exists, so any restored cursors will bind to it
invariant(WiredTigerRecoveryUnit::get(_txn)->getSession(_txn) == _cursor->getSession());
// If we've hit EOF, then this iterator is done and need not be restored.
if (_eof)
return true;
if (_lastReturnedId.isNull())
return true;
WT_CURSOR* c = _cursor->get();
c->set_key(c, _makeKey(_lastReturnedId));
int cmp;
int ret = WT_OP_CHECK(c->search_near(c, &cmp));
if (ret == WT_NOTFOUND) {
_eof = true;
return !_rs._isCapped;
}
invariantWTOK(ret);
if (cmp == 0)
return true; // Landed right where we left off.
if (_rs._isCapped) {
// Doc was deleted either by cappedDeleteAsNeeded() or cappedTruncateAfter().
// It is important that we error out in this case so that consumers don't
// silently get 'holes' when scanning capped collections. We don't make
// this guarantee for normal collections so it is ok to skip ahead in that case.
_eof = true;
return false;
}
if (_forward && cmp > 0) {
// We landed after where we were. Move back one so that next() will return this
// document.
ret = WT_OP_CHECK(c->prev(c));
} else if (!_forward && cmp < 0) {
// Do the opposite for reverse cursors.
ret = WT_OP_CHECK(c->next(c));
}
if (ret != WT_NOTFOUND)
invariantWTOK(ret);
return true;
}
示例7:
/*
* __curds_prev --
* WT_CURSOR.prev method for the data-source cursor type.
*/
static int
__curds_prev(WT_CURSOR *cursor)
{
WT_CURSOR *source;
WT_DECL_RET;
WT_SESSION_IMPL *session;
source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source;
CURSOR_API_CALL(cursor, session, prev, NULL);
WT_STAT_CONN_INCR(session, cursor_prev);
WT_STAT_DATA_INCR(session, cursor_prev);
WT_ERR(__curds_txn_enter(session, false));
F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
ret = __curds_cursor_resolve(cursor, source->prev(source));
err: __curds_txn_leave(session);
API_END_RET(session, ret);
}
示例8: strlen
//.........这里部分代码省略.........
ret = cursor->get_value(cursor, &value);
/*! [Get the cursor's string value] */
}
{
/*! [Set the cursor's string value] */
/* Set the cursor's string value. */
const char *value = "another value";
cursor->set_value(cursor, value);
/*! [Set the cursor's string value] */
}
{
/*! [Get the cursor's raw value] */
WT_ITEM value; /* Get the cursor's raw value. */
ret = cursor->get_value(cursor, &value);
/*! [Get the cursor's raw value] */
}
{
/*! [Set the cursor's raw value] */
WT_ITEM value; /* Set the cursor's raw value. */
value.data = "another value";
value.size = strlen("another value");
cursor->set_value(cursor, &value);
/*! [Set the cursor's raw value] */
}
/*! [Return the next record] */
ret = cursor->next(cursor);
/*! [Return the next record] */
/*! [Return the previous record] */
ret = cursor->prev(cursor);
/*! [Return the previous record] */
/*! [Reset the cursor] */
ret = cursor->reset(cursor);
/*! [Reset the cursor] */
{
WT_CURSOR *other = NULL;
/*! [Cursor comparison] */
int compare;
ret = cursor->compare(cursor, other, &compare);
if (compare == 0) {
/* Cursors reference the same key */
} else if (compare < 0) {
/* Cursor key less than other key */
} else if (compare > 0) {
/* Cursor key greater than other key */
}
/*! [Cursor comparison] */
}
{
/*! [Search for an exact match] */
const char *key = "some key";
cursor->set_key(cursor, key);
ret = cursor->search(cursor);
/*! [Search for an exact match] */
}
cursor_search_near(cursor);
{
示例9: main
//.........这里部分代码省略.........
/*
* Create the calls table, give names and types to the columns. All the
* columns will be stored together, so no column groups are declared.
*/
ret = session->create(session, "table:calls",
"key_format=r,"
"value_format=qrrSS,"
"columns=(id,call_date,cust_id,emp_id,call_type,notes)");
/*
* Create an index on the calls table with a composite key of cust_id
* and call_date.
*/
ret = session->create(session, "index:calls:cust_date",
"columns=(cust_id,call_date)");
/* Populate the calls table with some data. */
ret = session->open_cursor(
session, "table:calls", NULL, "append", &cursor);
for (callp = call_sample; callp->call_type != NULL; callp++) {
cursor->set_value(cursor, callp->call_date, callp->cust_id,
callp->emp_id, callp->call_type, callp->notes);
ret = cursor->insert(cursor);
}
ret = cursor->close(cursor);
/*
* First query: a call arrives. In SQL:
*
* SELECT id, name FROM Customers WHERE phone=?
*
* Use the cust_phone index, lookup by phone number to fill the
* customer record. The cursor will have a key format of "S" for a
* string because the cust_phone index has a single column ("phone"),
* which is of type "S".
*
* Specify the columns we want: the customer ID and the name. This
* means the cursor's value format will be "rS".
*/
ret = session->open_cursor(session,
"index:customers:phone(id,name)", NULL, NULL, &cursor);
cursor->set_key(cursor, "123-456-7890");
ret = cursor->search(cursor);
if (ret == 0) {
ret = cursor->get_value(cursor, &cust.id, &cust.name);
printf("Read customer record for %s (ID %" PRIu64 ")\n",
cust.name, cust.id);
}
ret = cursor->close(cursor);
/*
* Next query: get the recent order history. In SQL:
*
* SELECT * FROM Calls WHERE cust_id=? ORDER BY call_date DESC LIMIT 3
*
* Use the call_cust_date index to find the matching calls. Since it is
* is in increasing order by date for a given customer, we want to start
* with the last record for the customer and work backwards.
*
* Specify a subset of columns to be returned. (Note that if these were
* all covered by the index, the primary would not have to be accessed.)
* Stop after getting 3 records.
*/
ret = session->open_cursor(session,
"index:calls:cust_date(cust_id,call_type,notes)",
NULL, NULL, &cursor);
/*
* The keys in the index are (cust_id,call_date) -- we want the largest
* call date for a given cust_id. Search for (cust_id+1,0), then work
* backwards.
*/
cust.id = 1;
cursor->set_key(cursor, cust.id + 1, 0);
ret = cursor->search_near(cursor, &exact);
/*
* If the table is empty, search_near will return WT_NOTFOUND, else the
* cursor will be positioned on a matching key if one exists, or an
* adjacent key if one does not. If the positioned key is equal to or
* larger than the search key, go back one.
*/
if (ret == 0 && exact >= 0)
ret = cursor->prev(cursor);
for (count = 0; ret == 0 && count < 3; ++count) {
ret = cursor->get_value(cursor,
&call.cust_id, &call.call_type, &call.notes);
if (call.cust_id != cust.id)
break;
printf("Call record: customer %" PRIu64 " (%s: %s)\n",
call.cust_id, call.call_type, call.notes);
ret = cursor->prev(cursor);
}
/*! [call-center work] */
ret = conn->close(conn, NULL);
return (ret);
}
示例10: cappedDeleteAsNeeded_inlock
int64_t WiredTigerRecordStore::cappedDeleteAsNeeded_inlock(OperationContext* txn,
const RecordId& justInserted) {
// we do this is a side transaction in case it aborts
WiredTigerRecoveryUnit* realRecoveryUnit =
checked_cast<WiredTigerRecoveryUnit*>(txn->releaseRecoveryUnit());
invariant(realRecoveryUnit);
WiredTigerSessionCache* sc = realRecoveryUnit->getSessionCache();
OperationContext::RecoveryUnitState const realRUstate =
txn->setRecoveryUnit(new WiredTigerRecoveryUnit(sc), OperationContext::kNotInUnitOfWork);
WiredTigerRecoveryUnit::get(txn)->markNoTicketRequired(); // realRecoveryUnit already has
WT_SESSION* session = WiredTigerRecoveryUnit::get(txn)->getSession(txn)->getSession();
int64_t dataSize = _dataSize.load();
int64_t numRecords = _numRecords.load();
int64_t sizeOverCap = (dataSize > _cappedMaxSize) ? dataSize - _cappedMaxSize : 0;
int64_t sizeSaved = 0;
int64_t docsOverCap = 0, docsRemoved = 0;
if (_cappedMaxDocs != -1 && numRecords > _cappedMaxDocs)
docsOverCap = numRecords - _cappedMaxDocs;
try {
WriteUnitOfWork wuow(txn);
WiredTigerCursor curwrap(_uri, _tableId, true, txn);
WT_CURSOR* c = curwrap.get();
RecordId newestOld;
int ret = 0;
while ((sizeSaved < sizeOverCap || docsRemoved < docsOverCap) && (docsRemoved < 20000) &&
(ret = WT_OP_CHECK(c->next(c))) == 0) {
int64_t key;
ret = c->get_key(c, &key);
invariantWTOK(ret);
// don't go past the record we just inserted
newestOld = _fromKey(key);
if (newestOld >= justInserted) // TODO: use oldest uncommitted instead
break;
if (_shuttingDown)
break;
WT_ITEM old_value;
invariantWTOK(c->get_value(c, &old_value));
++docsRemoved;
sizeSaved += old_value.size;
if (_cappedDeleteCallback) {
uassertStatusOK(_cappedDeleteCallback->aboutToDeleteCapped(
txn,
newestOld,
RecordData(static_cast<const char*>(old_value.data), old_value.size)));
}
}
if (ret != WT_NOTFOUND) {
invariantWTOK(ret);
}
if (docsRemoved > 0) {
// if we scanned to the end of the collection or past our insert, go back one
if (ret == WT_NOTFOUND || newestOld >= justInserted) {
ret = WT_OP_CHECK(c->prev(c));
}
invariantWTOK(ret);
WiredTigerCursor startWrap(_uri, _tableId, true, txn);
WT_CURSOR* start = startWrap.get();
ret = WT_OP_CHECK(start->next(start));
invariantWTOK(ret);
ret = session->truncate(session, NULL, start, c, NULL);
if (ret == ENOENT || ret == WT_NOTFOUND) {
// TODO we should remove this case once SERVER-17141 is resolved
log() << "Soft failure truncating capped collection. Will try again later.";
docsRemoved = 0;
} else {
invariantWTOK(ret);
_changeNumRecords(txn, -docsRemoved);
_increaseDataSize(txn, -sizeSaved);
wuow.commit();
}
}
} catch (const WriteConflictException& wce) {
delete txn->releaseRecoveryUnit();
txn->setRecoveryUnit(realRecoveryUnit, realRUstate);
log() << "got conflict truncating capped, ignoring";
return 0;
} catch (...) {
delete txn->releaseRecoveryUnit();
txn->setRecoveryUnit(realRecoveryUnit, realRUstate);
throw;
}
delete txn->releaseRecoveryUnit();
txn->setRecoveryUnit(realRecoveryUnit, realRUstate);
return docsRemoved;
}
示例11: strlen
//.........这里部分代码省略.........
const char *key = "another key";
cursor->set_key(cursor, key);
/*! [Set the cursor's string key] */
}
{
/*! [Set the cursor's record number key] */
uint64_t recno = 37; /* Set the cursor's record number key. */
cursor->set_key(cursor, recno);
/*! [Set the cursor's record number key] */
}
{
/*! [Set the cursor's string value] */
/* Set the cursor's string value. */
const char *value = "another value";
cursor->set_value(cursor, value);
/*! [Set the cursor's string value] */
}
{
/*! [Set the cursor's raw value] */
WT_ITEM value; /* Set the cursor's raw value. */
value.data = "another value";
value.size = strlen("another value");
cursor->set_value(cursor, &value);
/*! [Set the cursor's raw value] */
}
/*! [Return the next record] */
ret = cursor->next(cursor);
/*! [Return the next record] */
/*! [Return the previous record] */
ret = cursor->prev(cursor);
/*! [Return the previous record] */
/*! [Reset the cursor] */
ret = cursor->reset(cursor);
/*! [Reset the cursor] */
{
WT_CURSOR *other = NULL;
/*! [Cursor comparison] */
int compare;
ret = cursor->compare(cursor, other, &compare);
if (compare == 0) {
/* Cursors reference the same key */
} else if (compare < 0) {
/* Cursor key less than other key */
} else if (compare > 0) {
/* Cursor key greater than other key */
}
/*! [Cursor comparison] */
}
{
/*! [Search for an exact match] */
const char *key = "some key";
cursor->set_key(cursor, key);
ret = cursor->search(cursor);
/*! [Search for an exact match] */
}
cursor_search_near(cursor);
{
示例12: calloc
int
setup_truncate(CONFIG *cfg, CONFIG_THREAD *thread, WT_SESSION *session) {
TRUNCATE_CONFIG *trunc_cfg;
TRUNCATE_QUEUE_ENTRY *truncate_item;
WORKLOAD *workload;
WT_CURSOR *cursor;
char *key, *truncate_key;
int ret;
uint64_t end_point, final_stone_gap, i, start_point;
end_point = final_stone_gap = start_point = 0;
trunc_cfg = &thread->trunc_cfg;
workload = thread->workload;
/* We are limited to only one table when running truncate. */
if ((ret = session->open_cursor(
session, cfg->uris[0], NULL, NULL, &cursor)) != 0)
goto err;
/* How many entries between each stone. */
trunc_cfg->stone_gap =
(workload->truncate_count * workload->truncate_pct) / 100;
/* How many stones we need. */
trunc_cfg->needed_stones =
workload->truncate_count / trunc_cfg->stone_gap;
final_stone_gap = trunc_cfg->stone_gap;
/* Reset this value for use again. */
trunc_cfg->stone_gap = 0;
/*
* Here we check if there is data in the collection. If there is
* data available, then we need to setup some initial truncation
* stones.
*/
if ((ret = cursor->next(cursor)) != 0 ||
(ret = cursor->get_key(cursor, &key)) != 0) {
lprintf(cfg, ret, 0, "truncate setup start: failed");
goto err;
}
start_point = decode_key(key);
if ((cursor->reset(cursor)) != 0 || (ret = cursor->prev(cursor)) != 0 ||
(ret = cursor->get_key(cursor, &key)) != 0) {
lprintf(cfg, ret, 0, "truncate setup end: failed");
goto err;
}
end_point = decode_key(key);
/* Assign stones if there are enough documents. */
if (start_point + trunc_cfg->needed_stones > end_point)
trunc_cfg->stone_gap = 0;
else
trunc_cfg->stone_gap =
(end_point - start_point) / trunc_cfg->needed_stones;
/* If we have enough data allocate some stones. */
if (trunc_cfg->stone_gap != 0) {
trunc_cfg->expected_total = (end_point - start_point);
for (i = 1; i <= trunc_cfg->needed_stones; i++) {
truncate_key = calloc(cfg->key_sz, 1);
if (truncate_key == NULL) {
ret = enomem(cfg);
goto err;
}
truncate_item = calloc(sizeof(TRUNCATE_QUEUE_ENTRY), 1);
if (truncate_item == NULL) {
free(truncate_key);
ret = enomem(cfg);
goto err;
}
generate_key(
cfg, truncate_key, trunc_cfg->stone_gap * i);
truncate_item->key = truncate_key;
truncate_item->diff =
(trunc_cfg->stone_gap * i) - trunc_cfg->last_key;
TAILQ_INSERT_TAIL( &cfg->stone_head, truncate_item, q);
trunc_cfg->last_key = trunc_cfg->stone_gap * i;
trunc_cfg->num_stones++;
}
}
trunc_cfg->stone_gap = final_stone_gap;
err: if ((ret = cursor->close(cursor)) != 0) {
lprintf(cfg, ret, 0, "truncate setup: cursor close failed");
}
return (ret);
}
示例13: strlen
//.........这里部分代码省略.........
/*! [Get the cursor's string value] */
const char *value; /* Get the cursor's string value. */
error_check(cursor->get_value(cursor, &value));
/*! [Get the cursor's string value] */
}
{
/*! [Get the cursor's raw value] */
WT_ITEM value; /* Get the cursor's raw value. */
error_check(cursor->get_value(cursor, &value));
/*! [Get the cursor's raw value] */
}
{
/*! [Set the cursor's raw value] */
WT_ITEM value; /* Set the cursor's raw value. */
value.data = "another value";
value.size = strlen("another value");
cursor->set_value(cursor, &value);
/*! [Set the cursor's raw value] */
error_check(cursor->insert(cursor));
}
/*! [Return the next record] */
error_check(cursor->next(cursor));
/*! [Return the next record] */
/*! [Reset the cursor] */
error_check(cursor->reset(cursor));
/*! [Reset the cursor] */
/*! [Return the previous record] */
error_check(cursor->prev(cursor));
/*! [Return the previous record] */
{
WT_CURSOR *other = NULL;
error_check(
session->open_cursor(session, NULL, cursor, NULL, &other));
{
/*! [Cursor comparison] */
int compare;
error_check(cursor->compare(cursor, other, &compare));
if (compare == 0) {
/* Cursors reference the same key */
} else if (compare < 0) {
/* Cursor key less than other key */
} else if (compare > 0) {
/* Cursor key greater than other key */
}
/*! [Cursor comparison] */
}
{
/*! [Cursor equality] */
int equal;
error_check(cursor->equals(cursor, other, &equal));
if (equal) {
/* Cursors reference the same key */
}
/*! [Cursor equality] */
}
}