|
|
@ -23,7 +23,8 @@ void Request::PendReq(Request *req) { |
|
|
|
|
|
|
|
//为虚函数提供最基本的实现
|
|
|
|
void Request::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string *> &batchKeySet) |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB, |
|
|
|
std::unordered_set<std::string> &batchKeySet) |
|
|
|
{ |
|
|
|
assert(0); |
|
|
|
} |
|
|
@ -45,12 +46,13 @@ bool Request::isPending() { |
|
|
|
|
|
|
|
/*******FieldsReq*******/ |
|
|
|
void FieldsReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string *> &batchKeySet) |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB, |
|
|
|
std::unordered_set<std::string> &batchKeySet) |
|
|
|
{ |
|
|
|
if (batchKeySet.find(Key) != batchKeySet.end()){ |
|
|
|
if (batchKeySet.find(*Key) != batchKeySet.end()){ |
|
|
|
return;//并发的被合并的put/delete请求只处理一次
|
|
|
|
} else { |
|
|
|
batchKeySet.insert(Key); |
|
|
|
batchKeySet.insert(*Key); |
|
|
|
} |
|
|
|
std::string val_str; |
|
|
|
Status s = DB->kvDB_->Get(ReadOptions(), *Key, &val_str); |
|
|
@ -64,8 +66,6 @@ void FieldsReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
assert(0); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
KVBatch.Put(Slice(*Key), Slice(SerializeValue(*Fields))); |
|
|
|
bool HasIndex = false; |
|
|
|
bool HasOldIndex = false; |
|
|
|
{ |
|
|
@ -101,7 +101,8 @@ void FieldsReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
KVBatch.Put(Slice(*Key), Slice(SerializeValue(*Fields))); |
|
|
|
//2.对于没有冲突但含有索引操作的put,构建metaKV,这里直接将KV对简单编码后写入metaDB
|
|
|
|
if(HasIndex || HasOldIndex) { |
|
|
|
std::string MetaKey,MetaValue; |
|
|
@ -147,12 +148,13 @@ void FieldsReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
|
|
|
|
/*******DeleteReq*******/ |
|
|
|
void DeleteReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string *> &batchKeySet) |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB, |
|
|
|
std::unordered_set<std::string> &batchKeySet) |
|
|
|
{ |
|
|
|
if (batchKeySet.find(Key) != batchKeySet.end()){ |
|
|
|
if (batchKeySet.find(*Key) != batchKeySet.end()){ |
|
|
|
return;//并发的被合并的put/delete请求只处理一次
|
|
|
|
} else { |
|
|
|
batchKeySet.insert(Key); |
|
|
|
batchKeySet.insert(*Key); |
|
|
|
} |
|
|
|
//1. 读取当前的最新的键值对,判断是否存在含有键值对的field
|
|
|
|
//2.1 如果无,则正常构造delete
|
|
|
@ -160,10 +162,10 @@ void DeleteReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
//在kvDB和metaDB中写入对应的delete
|
|
|
|
//2.3 如果存在field的索引状态是Creating或者Deleting,那么在那个队列上面进行等待
|
|
|
|
std::string val_str; |
|
|
|
DB->kvDB_->Get(ReadOptions(), *Key, &val_str); |
|
|
|
Status s = DB->kvDB_->Get(ReadOptions(), *Key, &val_str); |
|
|
|
if (s.IsNotFound()) return; |
|
|
|
FieldArray *Fields = new FieldArray; |
|
|
|
ParseValue(val_str,Fields); |
|
|
|
|
|
|
|
KVBatch.Delete(Slice(*Key)); |
|
|
|
bool HasIndex = false; |
|
|
|
{ |
|
|
@ -183,6 +185,7 @@ void DeleteReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
//assert(0);
|
|
|
|
} |
|
|
|
} |
|
|
|
KVBatch.Delete(Slice(*Key)); |
|
|
|
//2.对于没有冲突但含有索引操作的delete,构建metaKV,这里直接将KV对简单编码后写入metaDB
|
|
|
|
if(HasIndex) { |
|
|
|
std::string MetaKey; |
|
|
@ -233,7 +236,8 @@ void iCreateReq::PendReq(Request *req) { |
|
|
|
} |
|
|
|
|
|
|
|
void iCreateReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string *> &batchKeySet) |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB, |
|
|
|
std::unordered_set<std::string> &batchKeySet) |
|
|
|
{ |
|
|
|
//遍历数据库,构建二级索引到indexbatch,(更新metaDB中的元数据为Index类型的(Field,Creating))
|
|
|
|
//一个indexwritebatch写入,那么索引创建删除应该和metadb没有交互
|
|
|
@ -282,7 +286,7 @@ void iDeleteReq::Prepare(FieldDB *DB) { |
|
|
|
done = true; |
|
|
|
} else { |
|
|
|
//如果正在创建或者删除,那么pend到对应的请求上
|
|
|
|
parent->PendReq(this); |
|
|
|
parent->PendReq(this->parent); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -292,7 +296,7 @@ void iDeleteReq::PendReq(Request* req) { |
|
|
|
} |
|
|
|
|
|
|
|
void iDeleteReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string *> &batchKeySet) |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string> &batchKeySet) |
|
|
|
{ |
|
|
|
std::vector<std::pair<std::string, std::string>> keysAndVal = |
|
|
|
DB->FindKeysAndValByFieldName(*Field); |
|
|
@ -330,9 +334,17 @@ BatchReq::BatchReq(WriteBatch *Batch,port::Mutex *mu): |
|
|
|
void Put(const Slice &key, const Slice &value) override { |
|
|
|
//为key和value构造存储的地方,防止由于string的析构造成可能得内存访问错误
|
|
|
|
str_buf->push_back(key.ToString()); |
|
|
|
fa_buf->push_back({{"",value.ToString()}}); |
|
|
|
FieldArray *field = new FieldArray; |
|
|
|
field = ParseValue(value.ToString(), field); |
|
|
|
if (field == nullptr){ //batch中的value没有field
|
|
|
|
fa_buf->push_back({{"",value.ToString()}}); |
|
|
|
} else { |
|
|
|
fa_buf->push_back(*field); |
|
|
|
} |
|
|
|
|
|
|
|
sub_requests->emplace_back(new FieldsReq(&str_buf->back(),&fa_buf->back(),mu)); |
|
|
|
sub_requests->back()->parent = req; |
|
|
|
delete field; |
|
|
|
} |
|
|
|
void Delete(const Slice &key) override { |
|
|
|
str_buf->push_back(key.ToString()); |
|
|
@ -366,10 +378,10 @@ BatchReq::~BatchReq() { |
|
|
|
} |
|
|
|
|
|
|
|
void BatchReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string *> &batchKeySet) |
|
|
|
WriteBatch &MetaBatch,fielddb::FieldDB *DB,std::unordered_set<std::string> &batchKeySet) |
|
|
|
{ |
|
|
|
WriteBatch Sub_KVBatch,Sub_IndexBatch,Sub_MetaBatch; |
|
|
|
std::unordered_set<std::string *> Sub_batchKeySet; |
|
|
|
std::unordered_set<std::string> Sub_batchKeySet; |
|
|
|
//由于batch是有顺序的,根据我们现在的一个key只处理最开始的算法,这里需要反向迭代
|
|
|
|
for(auto subreq = sub_requests.rbegin(); subreq != sub_requests.rend(); subreq++ ) { |
|
|
|
(*subreq)->ConstructBatch(Sub_KVBatch, Sub_IndexBatch, Sub_MetaBatch, DB, Sub_batchKeySet); |
|
|
@ -382,7 +394,7 @@ void BatchReq::ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, |
|
|
|
KVBatch.Append(Sub_KVBatch); |
|
|
|
IndexBatch.Append(Sub_IndexBatch); |
|
|
|
MetaBatch.Append(Sub_MetaBatch); |
|
|
|
batchKeySet.insert(batchKeySet.begin(),batchKeySet.end()); |
|
|
|
batchKeySet.insert(Sub_batchKeySet.begin(),Sub_batchKeySet.end()); |
|
|
|
} |
|
|
|
|
|
|
|
|