mirror of https://gitee.com/bigwinds/arangodb
Use SingleDelete where possible (#6660)
This commit is contained in:
parent
fd1019c51e
commit
806d56389c
|
@ -378,9 +378,12 @@ void IResearchRocksDBRecoveryHelper::PutCF(uint32_t column_family_id,
|
|||
}
|
||||
}
|
||||
|
||||
void IResearchRocksDBRecoveryHelper::DeleteCF(uint32_t column_family_id,
|
||||
// common implementation for DeleteCF / SingleDeleteCF
|
||||
void IResearchRocksDBRecoveryHelper::handleDeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) {
|
||||
if (column_family_id == _documentCF) {
|
||||
return;
|
||||
}
|
||||
auto coll =
|
||||
lookupCollection(*_dbFeature, *_engine, RocksDBKey::objectId(key));
|
||||
|
||||
|
@ -415,14 +418,6 @@ void IResearchRocksDBRecoveryHelper::DeleteCF(uint32_t column_family_id,
|
|||
}
|
||||
|
||||
trx.commit();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void IResearchRocksDBRecoveryHelper::SingleDeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) {
|
||||
// not needed for anything atm
|
||||
}
|
||||
|
||||
void IResearchRocksDBRecoveryHelper::DeleteRangeCF(uint32_t column_family_id,
|
||||
|
|
|
@ -68,10 +68,14 @@ class IResearchRocksDBRecoveryHelper final : public RocksDBRecoveryHelper {
|
|||
const rocksdb::Slice& value) override;
|
||||
|
||||
virtual void DeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) override;
|
||||
const rocksdb::Slice& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
}
|
||||
|
||||
virtual void SingleDeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) override;
|
||||
const rocksdb::Slice& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
}
|
||||
|
||||
virtual void DeleteRangeCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& begin_key,
|
||||
|
@ -79,6 +83,10 @@ class IResearchRocksDBRecoveryHelper final : public RocksDBRecoveryHelper {
|
|||
|
||||
virtual void LogData(const rocksdb::Slice& blob) override;
|
||||
|
||||
private:
|
||||
|
||||
void handleDeleteCF(uint32_t column_family_id, const rocksdb::Slice& key);
|
||||
|
||||
private:
|
||||
std::set<IndexId> _recoveredIndexes; // set of already recovered indexes
|
||||
DatabaseFeature* _dbFeature;
|
||||
|
|
|
@ -1453,7 +1453,7 @@ Result RocksDBCollection::removeDocument(
|
|||
// disable indexing in this transaction if we are allowed to
|
||||
IndexingDisabler disabler(mthd, trx->isSingleOperationTransaction());
|
||||
|
||||
Result res = mthd->Delete(RocksDBColumnFamily::documents(), key.ref());
|
||||
Result res = mthd->SingleDelete(RocksDBColumnFamily::documents(), key.ref());
|
||||
if (res.fail()) {
|
||||
return res;
|
||||
}
|
||||
|
@ -1515,7 +1515,7 @@ Result RocksDBCollection::updateDocument(
|
|||
blackListKey(oldKey->string().data(),
|
||||
static_cast<uint32_t>(oldKey->string().size()));
|
||||
|
||||
res = mthd->Delete(RocksDBColumnFamily::documents(), oldKey.ref());
|
||||
res = mthd->SingleDelete(RocksDBColumnFamily::documents(), oldKey.ref());
|
||||
if (res.fail()) {
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -207,6 +207,11 @@ arangodb::Result RocksDBReadOnlyMethods::Delete(rocksdb::ColumnFamilyHandle* cf,
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_READ_ONLY);
|
||||
}
|
||||
|
||||
arangodb::Result RocksDBReadOnlyMethods::SingleDelete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_READ_ONLY);
|
||||
}
|
||||
|
||||
std::unique_ptr<rocksdb::Iterator> RocksDBReadOnlyMethods::NewIterator(
|
||||
rocksdb::ReadOptions const& opts, rocksdb::ColumnFamilyHandle* cf) {
|
||||
TRI_ASSERT(cf != nullptr);
|
||||
|
@ -288,6 +293,14 @@ arangodb::Result RocksDBTrxMethods::Delete(rocksdb::ColumnFamilyHandle* cf,
|
|||
return s.ok() ? arangodb::Result() : rocksutils::convertStatus(s);
|
||||
}
|
||||
|
||||
|
||||
arangodb::Result RocksDBTrxMethods::SingleDelete(rocksdb::ColumnFamilyHandle* cf,
|
||||
RocksDBKey const& key) {
|
||||
TRI_ASSERT(cf != nullptr);
|
||||
rocksdb::Status s = _state->_rocksTransaction->SingleDelete(cf, key.string());
|
||||
return s.ok() ? arangodb::Result() : rocksutils::convertStatus(s);
|
||||
}
|
||||
|
||||
std::unique_ptr<rocksdb::Iterator> RocksDBTrxMethods::NewIterator(
|
||||
rocksdb::ReadOptions const& opts, rocksdb::ColumnFamilyHandle* cf) {
|
||||
TRI_ASSERT(cf != nullptr);
|
||||
|
@ -334,6 +347,13 @@ arangodb::Result RocksDBTrxUntrackedMethods::Delete(rocksdb::ColumnFamilyHandle*
|
|||
return s.ok() ? arangodb::Result() : rocksutils::convertStatus(s);
|
||||
}
|
||||
|
||||
arangodb::Result RocksDBTrxUntrackedMethods::SingleDelete(rocksdb::ColumnFamilyHandle* cf,
|
||||
RocksDBKey const& key) {
|
||||
TRI_ASSERT(cf != nullptr);
|
||||
rocksdb::Status s = _state->_rocksTransaction->SingleDeleteUntracked(cf, key.string());
|
||||
return s.ok() ? arangodb::Result() : rocksutils::convertStatus(s);
|
||||
}
|
||||
|
||||
// =================== RocksDBBatchedMethods ====================
|
||||
|
||||
RocksDBBatchedMethods::RocksDBBatchedMethods(RocksDBTransactionState* state,
|
||||
|
@ -385,6 +405,13 @@ arangodb::Result RocksDBBatchedMethods::Delete(rocksdb::ColumnFamilyHandle* cf,
|
|||
return arangodb::Result();
|
||||
}
|
||||
|
||||
arangodb::Result RocksDBBatchedMethods::SingleDelete(rocksdb::ColumnFamilyHandle* cf,
|
||||
RocksDBKey const& key) {
|
||||
TRI_ASSERT(cf != nullptr);
|
||||
_wb->SingleDelete(cf, key.string());
|
||||
return arangodb::Result();
|
||||
}
|
||||
|
||||
std::unique_ptr<rocksdb::Iterator> RocksDBBatchedMethods::NewIterator(
|
||||
rocksdb::ReadOptions const& ro, rocksdb::ColumnFamilyHandle* cf) {
|
||||
TRI_ASSERT(cf != nullptr);
|
||||
|
|
|
@ -95,6 +95,10 @@ class RocksDBMethods {
|
|||
|
||||
virtual arangodb::Result Delete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) = 0;
|
||||
/// contrary to Delete, a SingleDelete may only be used
|
||||
/// when keys are inserted exactly once (and never overwritten)
|
||||
virtual arangodb::Result SingleDelete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) = 0;
|
||||
|
||||
virtual std::unique_ptr<rocksdb::Iterator> NewIterator(
|
||||
rocksdb::ReadOptions const&, rocksdb::ColumnFamilyHandle*) = 0;
|
||||
|
@ -133,6 +137,8 @@ class RocksDBReadOnlyMethods final : public RocksDBMethods {
|
|||
rocksutils::StatusHint hint = rocksutils::StatusHint::none) override;
|
||||
arangodb::Result Delete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const& key) override;
|
||||
arangodb::Result SingleDelete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) override;
|
||||
|
||||
std::unique_ptr<rocksdb::Iterator> NewIterator(
|
||||
rocksdb::ReadOptions const&, rocksdb::ColumnFamilyHandle*) override;
|
||||
|
@ -166,6 +172,8 @@ class RocksDBTrxMethods : public RocksDBMethods {
|
|||
rocksutils::StatusHint hint = rocksutils::StatusHint::none) override;
|
||||
arangodb::Result Delete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const& key) override;
|
||||
arangodb::Result SingleDelete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) override;
|
||||
|
||||
std::unique_ptr<rocksdb::Iterator> NewIterator(
|
||||
rocksdb::ReadOptions const&, rocksdb::ColumnFamilyHandle*) override;
|
||||
|
@ -188,6 +196,8 @@ class RocksDBTrxUntrackedMethods final : public RocksDBTrxMethods {
|
|||
rocksutils::StatusHint hint = rocksutils::StatusHint::none) override;
|
||||
arangodb::Result Delete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const& key) override;
|
||||
arangodb::Result SingleDelete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) override;
|
||||
};
|
||||
|
||||
/// wraps a writebatch - non transactional
|
||||
|
@ -207,6 +217,9 @@ class RocksDBBatchedMethods final : public RocksDBMethods {
|
|||
rocksutils::StatusHint hint = rocksutils::StatusHint::none) override;
|
||||
arangodb::Result Delete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const& key) override;
|
||||
arangodb::Result SingleDelete(rocksdb::ColumnFamilyHandle*,
|
||||
RocksDBKey const&) override;
|
||||
|
||||
std::unique_ptr<rocksdb::Iterator> NewIterator(
|
||||
rocksdb::ReadOptions const&, rocksdb::ColumnFamilyHandle*) override;
|
||||
|
||||
|
|
|
@ -361,9 +361,9 @@ class WBReader final : public rocksdb::WriteBatch::Handler {
|
|||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
rocksdb::Status DeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) override {
|
||||
if (column_family_id == RocksDBColumnFamily::documents()->GetID()) {
|
||||
void handleDeleteCF(uint32_t cfId,
|
||||
const rocksdb::Slice& key) {
|
||||
if (cfId == RocksDBColumnFamily::documents()->GetID()) {
|
||||
uint64_t objectId = RocksDBKey::objectId(key);
|
||||
Operations* ops = nullptr;
|
||||
if (shouldHandleCollection(objectId, &ops)) {
|
||||
|
@ -378,9 +378,9 @@ class WBReader final : public rocksdb::WriteBatch::Handler {
|
|||
} else {
|
||||
// We have to adjust the estimate with an insert
|
||||
uint64_t hash = 0;
|
||||
if (column_family_id == RocksDBColumnFamily::vpack()->GetID()) {
|
||||
if (cfId == RocksDBColumnFamily::vpack()->GetID()) {
|
||||
hash = RocksDBVPackIndex::HashForKey(key);
|
||||
} else if (column_family_id == RocksDBColumnFamily::edge()->GetID()) {
|
||||
} else if (cfId == RocksDBColumnFamily::edge()->GetID()) {
|
||||
hash = RocksDBEdgeIndex::HashForKey(key);
|
||||
}
|
||||
|
||||
|
@ -393,6 +393,11 @@ class WBReader final : public rocksdb::WriteBatch::Handler {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rocksdb::Status DeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
|
||||
RocksDBEngine* engine =
|
||||
static_cast<RocksDBEngine*>(EngineSelectorFeature::ENGINE);
|
||||
|
@ -405,6 +410,8 @@ class WBReader final : public rocksdb::WriteBatch::Handler {
|
|||
|
||||
rocksdb::Status SingleDeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
|
||||
RocksDBEngine* engine =
|
||||
static_cast<RocksDBEngine*>(EngineSelectorFeature::ENGINE);
|
||||
for (auto helper : engine->recoveryHelpers()) {
|
||||
|
|
|
@ -432,15 +432,15 @@ class WALParser final : public rocksdb::WriteBatch::Handler {
|
|||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
rocksdb::Status DeleteCF(uint32_t column_family_id,
|
||||
rocksdb::Slice const& key) override {
|
||||
// for Delete / SingleDelete
|
||||
void handleDeleteCF(uint32_t cfId, rocksdb::Slice const& key) {
|
||||
tick();
|
||||
|
||||
if (column_family_id != _primaryCF) {
|
||||
return rocksdb::Status(); // ignore all document operations
|
||||
if (cfId != _primaryCF) {
|
||||
return; // ignore all document operations
|
||||
} else if (_state != TRANSACTION && _state != SINGLE_REMOVE) {
|
||||
resetTransientState();
|
||||
return rocksdb::Status();
|
||||
return;
|
||||
}
|
||||
TRI_ASSERT(_state != SINGLE_REMOVE || _currentTrxId == 0);
|
||||
|
||||
|
@ -450,7 +450,7 @@ class WALParser final : public rocksdb::WriteBatch::Handler {
|
|||
TRI_voc_cid_t const cid = std::get<1>(triple);
|
||||
if (!shouldHandleCollection(dbid, cid)) {
|
||||
_removedDocRid = 0; // ignore rid too
|
||||
return rocksdb::Status(); // no reset here
|
||||
return; // no reset here
|
||||
}
|
||||
TRI_ASSERT(_vocbase->id() == dbid);
|
||||
|
||||
|
@ -475,7 +475,17 @@ class WALParser final : public rocksdb::WriteBatch::Handler {
|
|||
if (_state == SINGLE_REMOVE) {
|
||||
resetTransientState();
|
||||
}
|
||||
}
|
||||
|
||||
rocksdb::Status DeleteCF(uint32_t column_family_id,
|
||||
rocksdb::Slice const& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
rocksdb::Status SingleDeleteCF(uint32_t column_family_id,
|
||||
rocksdb::Slice const& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
|
|
|
@ -158,11 +158,14 @@ RocksDBVPackIndexIterator::RocksDBVPackIndexIterator(
|
|||
|
||||
RocksDBMethods* mthds = RocksDBTransactionState::toMethods(trx);
|
||||
rocksdb::ReadOptions options = mthds->iteratorReadOptions();
|
||||
if (!reverse) {
|
||||
// we need to have a pointer to a slice for the upper bound
|
||||
// so we need to assign the slice to an instance variable here
|
||||
_upperBound = _bounds.end();
|
||||
options.iterate_upper_bound = &_upperBound;
|
||||
if (reverse) {
|
||||
_rangeBound = _bounds.start();
|
||||
options.iterate_lower_bound = &_rangeBound;
|
||||
} else {
|
||||
_rangeBound = _bounds.end();
|
||||
options.iterate_upper_bound = &_rangeBound;
|
||||
}
|
||||
|
||||
TRI_ASSERT(options.prefix_same_as_start);
|
||||
|
@ -394,7 +397,7 @@ int RocksDBVPackIndex::fillElement(VPackBuilder& leased,
|
|||
TRI_ASSERT(leased.isEmpty());
|
||||
if (!_useExpansion) {
|
||||
// fast path for inserts... no array elements used
|
||||
leased.openArray();
|
||||
leased.openArray(true);
|
||||
|
||||
size_t const n = _paths.size();
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
|
@ -817,12 +820,23 @@ Result RocksDBVPackIndex::removeInternal(transaction::Methods* trx,
|
|||
}
|
||||
|
||||
size_t const count = elements.size();
|
||||
if (_unique) {
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
arangodb::Result r = mthds->Delete(_cf, elements[i]);
|
||||
if (!r.ok()) {
|
||||
res = r.errorNumber();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// non-unique index contain the unique objectID
|
||||
// they should be written exactly once
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
arangodb::Result r = mthds->SingleDelete(_cf, elements[i]);
|
||||
if (!r.ok()) {
|
||||
res = r.errorNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
auto state = RocksDBTransactionState::toState(trx);
|
||||
|
|
|
@ -135,7 +135,8 @@ class RocksDBVPackIndexIterator final : public IndexIterator {
|
|||
std::unique_ptr<rocksdb::Iterator> _iterator;
|
||||
bool const _reverse;
|
||||
RocksDBKeyBounds _bounds;
|
||||
rocksdb::Slice _upperBound; // used for iterate_upper_bound
|
||||
// used for iterate_upper_bound iterate_lower_bound
|
||||
rocksdb::Slice _rangeBound;
|
||||
};
|
||||
|
||||
class RocksDBVPackIndex : public RocksDBIndex {
|
||||
|
|
|
@ -569,15 +569,15 @@ class MyWALParser : public rocksdb::WriteBatch::Handler, public WalAccessContext
|
|||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
rocksdb::Status DeleteCF(uint32_t column_family_id,
|
||||
rocksdb::Slice const& key) override {
|
||||
// for Delete / SingleDelete
|
||||
void handleDeleteCF(uint32_t cfId, rocksdb::Slice const& key) {
|
||||
tick();
|
||||
|
||||
if (column_family_id != _primaryCF) {
|
||||
return rocksdb::Status(); // ignore all document operations
|
||||
if (cfId != _primaryCF) {
|
||||
return; // ignore all document operations
|
||||
} else if (_state != TRANSACTION && _state != SINGLE_REMOVE) {
|
||||
resetTransientState();
|
||||
return rocksdb::Status();
|
||||
return;
|
||||
}
|
||||
TRI_ASSERT(_state != SINGLE_REMOVE || _currentTrxId == 0);
|
||||
TRI_ASSERT(_state != TRANSACTION || _trxDbId != 0);
|
||||
|
@ -590,7 +590,7 @@ class MyWALParser : public rocksdb::WriteBatch::Handler, public WalAccessContext
|
|||
if (!shouldHandleCollection(dbid, cid)) {
|
||||
_removedDocRid = 0; // ignore rid too
|
||||
|
||||
return rocksdb::Status(); // no reset here
|
||||
return; // no reset here
|
||||
}
|
||||
|
||||
StringRef docKey = RocksDBKey::primaryKey(key);
|
||||
|
@ -624,7 +624,17 @@ class MyWALParser : public rocksdb::WriteBatch::Handler, public WalAccessContext
|
|||
if (_state == SINGLE_REMOVE) {
|
||||
resetTransientState();
|
||||
}
|
||||
}
|
||||
|
||||
rocksdb::Status DeleteCF(uint32_t column_family_id,
|
||||
rocksdb::Slice const& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
rocksdb::Status SingleDeleteCF(uint32_t column_family_id,
|
||||
rocksdb::Slice const& key) override {
|
||||
handleDeleteCF(column_family_id, key);
|
||||
return rocksdb::Status();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue