|
@ -1309,7 +1309,8 @@ Status DBImpl::Put(const WriteOptions& o, const Slice& key, const Slice& val) { |
|
|
|
|
|
|
|
|
Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { |
|
|
Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { |
|
|
//ToDo
|
|
|
//ToDo
|
|
|
WriteBatch batch; // 创建事务
|
|
|
|
|
|
|
|
|
WriteBatch batch; // 创建主数据库的事务
|
|
|
|
|
|
WriteBatch indexBatch; // 创建二级索引数据库的事务
|
|
|
Status s; |
|
|
Status s; |
|
|
|
|
|
|
|
|
// 在主数据库删除数据
|
|
|
// 在主数据库删除数据
|
|
@ -1317,38 +1318,52 @@ Status DBImpl::Delete(const WriteOptions& options, const Slice& key) { |
|
|
|
|
|
|
|
|
// 如果不是在 indexDb_ 上调用 Delete,则需要处理索引删除
|
|
|
// 如果不是在 indexDb_ 上调用 Delete,则需要处理索引删除
|
|
|
if (indexDb_ != nullptr) { |
|
|
if (indexDb_ != nullptr) { |
|
|
// 遍历fieldWithIndex_,检查是否需要删除索引
|
|
|
|
|
|
for (const auto& field : fieldWithIndex_) { |
|
|
|
|
|
size_t field_pos = key.ToString().find(field + ":"); |
|
|
|
|
|
if (field_pos != std::string::npos) { |
|
|
|
|
|
size_t value_start = field_pos + field.size() + 1; |
|
|
|
|
|
size_t value_end = key.ToString().find("|", value_start); |
|
|
|
|
|
if (value_end == std::string::npos) { |
|
|
|
|
|
value_end = key.ToString().size(); |
|
|
|
|
|
} |
|
|
|
|
|
std::string fieldValue = key.ToString().substr(value_start, value_end - value_start); |
|
|
|
|
|
|
|
|
// 遍历 fieldWithIndex_,检查是否需要删除索引
|
|
|
|
|
|
for (const auto& field : fieldWithIndex_) { |
|
|
|
|
|
size_t field_pos = key.ToString().find(field + ":"); |
|
|
|
|
|
if (field_pos != std::string::npos) { |
|
|
|
|
|
size_t value_start = field_pos + field.size() + 1; |
|
|
|
|
|
size_t value_end = key.ToString().find("|", value_start); |
|
|
|
|
|
if (value_end == std::string::npos) { |
|
|
|
|
|
value_end = key.ToString().size(); |
|
|
|
|
|
} |
|
|
|
|
|
std::string fieldValue = key.ToString().substr(value_start, value_end - value_start); |
|
|
|
|
|
|
|
|
if (!fieldValue.empty()) { |
|
|
|
|
|
std::string indexKey = field + ":" + fieldValue; |
|
|
|
|
|
|
|
|
if (!fieldValue.empty()) { |
|
|
|
|
|
std::string indexKey = field + ":" + fieldValue; |
|
|
|
|
|
|
|
|
// 将索引删除操作加入事务
|
|
|
|
|
|
batch.Delete(Slice(indexKey)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 将索引删除操作加入二级索引数据库的事务
|
|
|
|
|
|
indexBatch.Delete(Slice(indexKey)); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 如果是 indexDb_ 调用,则仅提交该数据库的删除操作
|
|
|
|
|
|
if (this == indexDb_) { |
|
|
|
|
|
s = indexDb_->Write(options, &batch); // 删除操作直接提交给 indexDb_
|
|
|
|
|
|
} else { |
|
|
|
|
|
// 使用 `this->Write` 提交事务
|
|
|
|
|
|
s = this->Write(options, &batch); // 提交给主数据库和索引数据库的事务
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 提交主数据库的 WriteBatch
|
|
|
|
|
|
s = this->Write(options, &batch); |
|
|
|
|
|
if (!s.ok()) { |
|
|
|
|
|
return s; // 如果主数据库删除失败,则直接返回错误
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!s.ok()) { |
|
|
|
|
|
// 如果操作失败,则返回错误状态
|
|
|
|
|
|
return s; |
|
|
|
|
|
|
|
|
// 提交二级索引数据库的 WriteBatch
|
|
|
|
|
|
s = indexDb_->Write(options, &indexBatch); |
|
|
|
|
|
if (!s.ok()) { |
|
|
|
|
|
// 如果二级索引数据库删除失败,回滚主数据库的删除操作
|
|
|
|
|
|
// 回滚操作:重新插入已删除的主数据库的键
|
|
|
|
|
|
WriteBatch rollbackBatch; |
|
|
|
|
|
rollbackBatch.Put(key, ""); // 将原始数据重新插入主数据库
|
|
|
|
|
|
Status rollbackStatus = this->Write(options, &rollbackBatch); |
|
|
|
|
|
if (!rollbackStatus.ok()) { |
|
|
|
|
|
return rollbackStatus; // 如果回滚操作失败,返回回滚错误
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return s; // 返回二级索引数据库删除失败的状态
|
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// 如果是 indexDb_ 调用,则仅提交该数据库的删除操作
|
|
|
|
|
|
s = this->Write(options, &batch); // 删除操作直接提交给 indexDb_
|
|
|
|
|
|
if (!s.ok()) { |
|
|
|
|
|
return s; // 如果操作失败,则返回错误状态
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return Status::OK(); |
|
|
return Status::OK(); |
|
|