#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
|