#include <deque> #include <string> #include "leveldb/db.h" #include "leveldb/slice.h" #include "leveldb/status.h" #include "leveldb/write_batch.h" #include "port/port_stdcxx.h" #include "util/coding.h" #include "util/mutexlock.h" #include "util/serialize_value.h" #include <unordered_set> // #include "fielddb/field_db.h" #include "fielddb/SliceHashSet.h" #ifndef REQUEST_H #define REQUEST_H namespace fielddb { using namespace leveldb; // 在taskqueue中的Request,由taskqueue最开始的线程处理一批Request // 这个思路与write写入的思路类似 class FieldDB; class Request { public: friend class FieldDB; enum RequestType { FieldsReq_t, //ValueReq_t, iCreateReq_t, iDeleteReq_t, DeleteReq_t, BatchReq_t, }; public: // Request(std::string *Key,std::string *Value,port::Mutex *mu): // Key(Key),Value(Value),hasFields(false),cond_(mu) { } // Request(std::string *Key,FieldArray *Fields,port::Mutex *mu): // Key(Key),Fields(Fields),hasFields(true),cond_(mu) { } Request(RequestType type,port::Mutex *mu): type_(type),cond_(mu),done(false) { parent = this; }; //virtual ~Request(); inline bool isFieldsReq() { return type_ == FieldsReq_t; } // inline bool isValueReq() { return type_ == ValueReq_t; } inline bool isiCreateReq() { return type_ == iCreateReq_t; } inline bool isiDeleteReq() { return type_ == iDeleteReq_t; } inline bool isDeleteReq() { return type_ == DeleteReq_t; } inline bool isBatchReq() { return type_ == BatchReq_t; } //用于含有Fields的 virtual void ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, WriteBatch &MetaBatch,fielddb::FieldDB *DB,SliceHashSet &batchKeySet); //主要用于icreate和idelete在队列中的注册当前状态 virtual void Prepare(FieldDB *DB); virtual void Finalize(FieldDB *DB); virtual void PendReq(Request *req); bool isPending(); // protected: bool done; Status s; port::CondVar cond_; RequestType type_; Request *parent; }; //含有field的put class FieldsReq : public Request { public: FieldsReq(Slice Key,const FieldArray &Fields,port::Mutex *mu): Key(Key),Request(FieldsReq_t,mu) { for(auto &[name,value] : Fields) { SliceFields.push_back({name,value}); } }; FieldsReq(Slice Key, Slice Value,port::Mutex *mu): Key(Key),Request(FieldsReq_t,mu) { Slice nameSlice, valSlice; while(GetLengthPrefixedSlice(&Value, &nameSlice)) { if(GetLengthPrefixedSlice(&Value, &valSlice)) { SliceFields.push_back({nameSlice,valSlice}); } else { std::cout << "name and val not match! From FieldsReq Init" << std::endl; } nameSlice.clear(), valSlice.clear(); } } void ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, WriteBatch &MetaBatch,fielddb::FieldDB *DB,SliceHashSet &batchKeySet) override; Slice Key; FieldSliceArray SliceFields; }; //不含有field的put,但是计划被弃用了 // class ValueReq : public Request { // public: // ValueReq(std::string *Key,std::string *Value,port::Mutex *mu): // Key(Key),Value(Value),Request(ValueReq_t,mu) { }; // std::string *Key; // std::string *Value; // }; //创建索引的request class iCreateReq : public Request { public: iCreateReq(Slice Field,port::Mutex *mu): Field(Field),Request(iCreateReq_t, mu),Existed(false) { }; void ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, WriteBatch &MetaBatch,fielddb::FieldDB *DB,SliceHashSet &batchKeySet) override; void Prepare(FieldDB *DB) override; void Finalize(FieldDB *DB) override; void PendReq(Request *req) override; bool Existed; Slice Field; std::deque<Request *> pending_list; }; //删除索引的request class iDeleteReq : public Request { public: iDeleteReq(Slice Field,port::Mutex *mu): Field(Field),Request(iDeleteReq_t, mu),Deleted(false) { }; void ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, WriteBatch &MetaBatch,fielddb::FieldDB *DB,SliceHashSet &batchKeySet) override; void Prepare(FieldDB *DB) override; void Finalize(FieldDB *DB) override; void PendReq(Request *req) override; bool Deleted; Slice Field; std::deque<Request *> pending_list; }; //删除key的request class DeleteReq : public Request { public: DeleteReq(Slice Key,port::Mutex *mu): Key(Key),Request(DeleteReq_t,mu) { }; void ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, WriteBatch &MetaBatch,fielddb::FieldDB *DB,SliceHashSet &batchKeySet) override; Slice Key; }; class BatchReq : public Request { public: BatchReq(WriteBatch *Batch,port::Mutex *mu); ~BatchReq(); void ConstructBatch(WriteBatch &KVBatch,WriteBatch &IndexBatch, WriteBatch &MetaBatch,fielddb::FieldDB *DB,SliceHashSet &batchKeySet) override; WriteBatch *Batch; std::deque<Request *> sub_requests; // std::deque<std::string> str_buf; // std::deque<FieldArray> fa_buf; }; class SnapshotReq; class XSnapshot { friend class SnapshotReq; public: XSnapshot(const Snapshot *kv,const Snapshot *index) : kv_snapshot(kv), index_snapshot(index) {} const leveldb::Snapshot *kv_snapshot; const leveldb::Snapshot *index_snapshot; }; class SnapshotReq : public Request { public: SnapshotReq(port::Mutex *mu):Request(iCreateReq_t, mu) { }; void Prepare(FieldDB *DB); XSnapshot *xSnapshot; }; } #endif