bool indexInsert(size_t indexId, fstring key, llong recId) override { assert(started == m_status); assert(indexId < m_indices.size()); WT_ITEM item; WT_SESSION* ses = m_session.ses; const Schema& schema = m_sconf.getIndexSchema(indexId); WT_CURSOR* cur = m_indices[indexId].insert; WtWritableIndex::setKeyVal(schema, cur, key, recId, &item, &m_wrtBuf); int err = cur->insert(cur); m_sizeDiff += sizeof(llong) + key.size(); if (schema.m_isUnique) { if (WT_DUPLICATE_KEY == err) { return false; } if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger insert unique index: %s", ses->strerror(ses, err)); } } else { if (WT_DUPLICATE_KEY == err) { assert(0); // assert in debug return true; // ignore in release } if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger insert multi index: %s", ses->strerror(ses, err)); } } return true; }
/*! [thread scan] */ void * scan_thread(void *conn_arg) { WT_CONNECTION *conn; WT_CURSOR *cursor; WT_SESSION *session; const char *key, *value; int ret; conn = conn_arg; ret = conn->open_session(conn, NULL, NULL, &session); ret = session->open_cursor( session, "table:access", NULL, NULL, &cursor); /* Show all records. */ while ((ret = cursor->next(cursor)) == 0) { ret = cursor->get_key(cursor, &key); ret = cursor->get_value(cursor, &value); printf("Got record: %s : %s\n", key, value); } if (ret != WT_NOTFOUND) fprintf(stderr, "WT_CURSOR.next: %s\n", session->strerror(session, ret)); return (NULL); }
explicit WtDbTransaction(WtWritableSegment* seg) : m_seg(seg), m_sconf(*seg->m_schema) { WT_CONNECTION* conn = seg->m_wtConn; int err = conn->open_session(conn, NULL, NULL, &m_session.ses); if (err) { THROW_STD(invalid_argument , "FATAL: wiredtiger open session(dir=%s) = %s" , conn->get_home(conn), wiredtiger_strerror(err) ); } WT_SESSION* ses = m_session.ses; err = ses->open_cursor(ses, g_dataStoreUri, NULL, "overwrite=true", &m_store.cursor); if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger store open cursor: %s" , ses->strerror(ses, err)); } m_indices.resize(seg->m_indices.size()); for (size_t indexId = 0; indexId < m_indices.size(); ++indexId) { ReadableIndex* index = seg->m_indices[indexId].get(); WtWritableIndex* wtIndex = dynamic_cast<WtWritableIndex*>(index); assert(NULL != wtIndex); const char* uri = wtIndex->getIndexUri().c_str(); err = ses->open_cursor(ses, uri, NULL, "overwrite=false", &m_indices[indexId].insert.cursor); if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger open index cursor: %s" , ses->strerror(ses, err)); } err = ses->open_cursor(ses, uri, NULL, "overwrite=true", &m_indices[indexId].overwrite.cursor); if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger open index cursor: %s" , ses->strerror(ses, err)); } } m_sizeDiff = 0; m_wrtStore = dynamic_cast<WtWritableStore*>(seg->m_wrtStore.get()); assert(nullptr != m_store); g_wtDbTxnLiveCnt++; g_wtDbTxnCreatedCnt++; if (getEnvBool("TerarkDB_TrackBuggyObjectLife")) { fprintf(stderr, "DEBUG: WtDbTransaction live count = %zd, created = %zd\n" , g_wtDbTxnLiveCnt.load(), g_wtDbTxnCreatedCnt.load()); } }
void do_rollback() override { resetCursors(); #if TERARK_WT_USE_TXN WT_SESSION* ses = m_session.ses; int err = ses->rollback_transaction(ses, NULL); if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger rollback_transaction: %s" , ses->strerror(ses, err)); } #endif }
bool do_commit() override { resetCursors(); #if TERARK_WT_USE_TXN WT_SESSION* ses = m_session.ses; int err = ses->commit_transaction(ses, NULL); if (err) { m_strError = "wiredtiger commit_transaction: "; m_strError += ses->strerror(ses, err); assert(!"wiredtiger commit_transaction failed"); return false; } #endif m_wrtStore->estimateIncDataSize(m_sizeDiff); return true; }
void do_startTransaction() override { #if TERARK_WT_USE_TXN WT_SESSION* ses = m_session.ses; const char* txnConfig = getenv("TerarkDB_WiredtigerTransactionConfig"); if (NULL == txnConfig) { // wiredtiger 2.8.0 is not binary compatible with 2.7.0 txnConfig = "isolation=read-committed,sync=false"; } // fprintf(stderr, "INFO: %s: txnConfig=%s\n", BOOST_CURRENT_FUNCTION, txnConfig); int err = ses->begin_transaction(ses, txnConfig); if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger begin_transaction: %s" , ses->strerror(ses, err)); } #endif m_sizeDiff = 0; }
void indexSearch(size_t indexId, fstring key, valvec<llong>* recIdvec) override { assert(started == m_status); assert(indexId < m_indices.size()); WT_ITEM item; WT_SESSION* ses = m_session.ses; const Schema& schema = m_sconf.getIndexSchema(indexId); WT_CURSOR* cur = m_indices[indexId].insert; WtWritableIndex::setKeyVal(schema, cur, key, 0, &item, &m_wrtBuf); recIdvec->erase_all(); if (schema.m_isUnique) { int err = cur->search(cur); BOOST_SCOPE_EXIT(cur) { cur->reset(cur); } BOOST_SCOPE_EXIT_END; if (WT_NOTFOUND == err) { return; } if (err) { THROW_STD(invalid_argument , "ERROR: wiredtiger search: %s", ses->strerror(ses, err)); } llong recId = 0; cur->get_value(cur, &recId); recIdvec->push_back(recId); }
static int cursor_scope_ops(WT_CURSOR *cursor) { struct { const char *key; const char *value; int (*apply)(WT_CURSOR *); } *op, ops[] = { { "key1", "value1", cursor->insert, }, { "key1", "value2", cursor->update, }, { "key1", "value2", cursor->search, }, { "key1", "value2", cursor->remove, }, { NULL, NULL, NULL } }; WT_SESSION *session; const char *key, *value; char keybuf[10], valuebuf[10]; int ret; session = cursor->session; for (op = ops; op->key != NULL; op++) { key = value = NULL; /*! [cursor scope operation] */ (void)snprintf(keybuf, sizeof(keybuf), "%s", op->key); cursor->set_key(cursor, keybuf); (void)snprintf(valuebuf, sizeof(valuebuf), "%s", op->value); cursor->set_value(cursor, valuebuf); /* * The application must keep the key and value memory valid * until the next operation that positions the cursor. * Modifying either the key or value buffers is not permitted. */ /* Apply the operation (insert, update, search or remove). */ if ((ret = op->apply(cursor)) != 0) { fprintf(stderr, "Error performing the operation: %s\n", session->strerror(session, ret)); return (ret); } /* * Except for WT_CURSOR::insert, the cursor has been positioned * and no longer references application memory, so application * buffers can be safely overwritten. */ if (op->apply != cursor->insert) { strcpy(keybuf, "no key"); strcpy(valuebuf, "no value"); } /* * Check that get_key/value behave as expected after the * operation. */ if ((ret = cursor->get_key(cursor, &key)) != 0 || (op->apply != cursor->remove && (ret = cursor->get_value(cursor, &value)) != 0)) { fprintf(stderr, "Error in get_key/value: %s\n", session->strerror(session, ret)); return (ret); } /* * Except for WT_CURSOR::insert (which does not position the * cursor), the application now has pointers to memory owned * by the cursor. Modifying the memory referenced by either * key or value is not permitted. */ /* Check that the cursor's key and value are what we expect. */ if (op->apply != cursor->insert) if (key == keybuf || (op->apply != cursor->remove && value == valuebuf)) { fprintf(stderr, "Cursor points at application memory!\n"); return (EINVAL); } if (strcmp(key, op->key) != 0 || (op->apply != cursor->remove && strcmp(value, op->value) != 0)) { fprintf(stderr, "Unexpected key / value!\n"); return (EINVAL); } /*! [cursor scope operation] */ } return (0); }