mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 10:25:47 +02:00
Add basic GET command for both mc and redis
This commit is contained in:
parent
5ebbfa5a64
commit
9a6e8e31be
6 changed files with 64 additions and 6 deletions
|
@ -12,4 +12,8 @@ ConnectionContext::ConnectionContext(::io::Sink* stream, Connection* owner)
|
||||||
: ReplyBuilder(owner->protocol(), stream), owner_(owner) {
|
: ReplyBuilder(owner->protocol(), stream), owner_(owner) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Protocol ConnectionContext::protocol() const {
|
||||||
|
return owner_->protocol();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dfly
|
} // namespace dfly
|
||||||
|
|
|
@ -24,6 +24,8 @@ class ConnectionContext : public ReplyBuilder {
|
||||||
return owner_;
|
return owner_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Protocol protocol() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Connection* owner_;
|
Connection* owner_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -146,6 +146,9 @@ void Service::DispatchMC(const MemcacheParser::Command& cmd, std::string_view va
|
||||||
strcpy(cmd_name, "SET");
|
strcpy(cmd_name, "SET");
|
||||||
strcpy(set_opt, "NX");
|
strcpy(set_opt, "NX");
|
||||||
break;
|
break;
|
||||||
|
case MemcacheParser::GET:
|
||||||
|
strcpy(cmd_name, "GET");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cntx->SendMCClientError("bad command line format");
|
cntx->SendMCClientError("bad command line format");
|
||||||
return;
|
return;
|
||||||
|
@ -168,7 +171,6 @@ void Service::DispatchMC(const MemcacheParser::Command& cmd, std::string_view va
|
||||||
DispatchCommand(arg_list, cntx);
|
DispatchCommand(arg_list, cntx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Service::RegisterHttp(HttpListenerBase* listener) {
|
void Service::RegisterHttp(HttpListenerBase* listener) {
|
||||||
CHECK_NOTNULL(listener);
|
CHECK_NOTNULL(listener);
|
||||||
}
|
}
|
||||||
|
@ -191,8 +193,8 @@ void Service::Ping(CmdArgList args, ConnectionContext* cntx) {
|
||||||
void Service::Set(CmdArgList args, ConnectionContext* cntx) {
|
void Service::Set(CmdArgList args, ConnectionContext* cntx) {
|
||||||
set_qps.Inc();
|
set_qps.Inc();
|
||||||
|
|
||||||
std::string_view key = ArgS(args, 1);
|
string_view key = ArgS(args, 1);
|
||||||
std::string_view val = ArgS(args, 2);
|
string_view val = ArgS(args, 2);
|
||||||
VLOG(2) << "Set " << key << " " << val;
|
VLOG(2) << "Set " << key << " " << val;
|
||||||
|
|
||||||
ShardId sid = Shard(key, shard_count());
|
ShardId sid = Shard(key, shard_count());
|
||||||
|
@ -205,6 +207,29 @@ void Service::Set(CmdArgList args, ConnectionContext* cntx) {
|
||||||
cntx->SendStored();
|
cntx->SendStored();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Service::Get(CmdArgList args, ConnectionContext* cntx) {
|
||||||
|
string_view key = ArgS(args, 1);
|
||||||
|
ShardId sid = Shard(key, shard_count());
|
||||||
|
|
||||||
|
OpResult<string> opres;
|
||||||
|
|
||||||
|
shard_set_.Await(sid, [&] {
|
||||||
|
EngineShard* es = EngineShard::tlocal();
|
||||||
|
OpResult<DbSlice::MainIterator> res = es->db_slice.Find(0, key);
|
||||||
|
if (res) {
|
||||||
|
opres.value() = res.value()->second;
|
||||||
|
} else {
|
||||||
|
opres = res.status();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opres) {
|
||||||
|
cntx->SendGetReply(key, 0, opres.value());
|
||||||
|
} else if (opres.status() == OpStatus::KEY_NOTFOUND) {
|
||||||
|
cntx->SendGetNotFound();
|
||||||
|
}
|
||||||
|
cntx->EndMultilineReply();
|
||||||
|
}
|
||||||
|
|
||||||
VarzValue::Map Service::GetVarzStats() {
|
VarzValue::Map Service::GetVarzStats() {
|
||||||
VarzValue::Map res;
|
VarzValue::Map res;
|
||||||
|
@ -227,7 +252,8 @@ void Service::RegisterCommands() {
|
||||||
using CI = CommandId;
|
using CI = CommandId;
|
||||||
|
|
||||||
registry_ << CI{"PING", CO::STALE | CO::FAST, -1, 0, 0, 0}.HFUNC(Ping)
|
registry_ << CI{"PING", CO::STALE | CO::FAST, -1, 0, 0, 0}.HFUNC(Ping)
|
||||||
<< CI{"SET", CO::WRITE | CO::DENYOOM, -3, 1, 1, 1}.HFUNC(Set);
|
<< CI{"SET", CO::WRITE | CO::DENYOOM, -3, 1, 1, 1}.HFUNC(Set)
|
||||||
|
<< CI{"GET", CO::READONLY | CO::FAST, 2, 1, 1, 1}.HFUNC(Get);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dfly
|
} // namespace dfly
|
||||||
|
|
|
@ -48,6 +48,7 @@ class Service {
|
||||||
private:
|
private:
|
||||||
void Ping(CmdArgList args, ConnectionContext* cntx);
|
void Ping(CmdArgList args, ConnectionContext* cntx);
|
||||||
void Set(CmdArgList args, ConnectionContext* cntx);
|
void Set(CmdArgList args, ConnectionContext* cntx);
|
||||||
|
void Get(CmdArgList args, ConnectionContext* cntx);
|
||||||
|
|
||||||
void RegisterCommands();
|
void RegisterCommands();
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,6 @@ void RespSerializer::SendSimpleString(std::string_view str) {
|
||||||
Send(v, ABSL_ARRAYSIZE(v));
|
Send(v, ABSL_ARRAYSIZE(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RespSerializer::SendBulkString(std::string_view str) {
|
void RespSerializer::SendBulkString(std::string_view str) {
|
||||||
char tmp[absl::numbers_internal::kFastToBufferSize + 3];
|
char tmp[absl::numbers_internal::kFastToBufferSize + 3];
|
||||||
tmp[0] = '$'; // Format length
|
tmp[0] = '$'; // Format length
|
||||||
|
@ -97,7 +96,6 @@ void ReplyBuilder::SendStored() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ReplyBuilder::SendMCClientError(string_view str) {
|
void ReplyBuilder::SendMCClientError(string_view str) {
|
||||||
DCHECK(protocol_ == Protocol::MEMCACHE);
|
DCHECK(protocol_ == Protocol::MEMCACHE);
|
||||||
|
|
||||||
|
@ -105,6 +103,12 @@ void ReplyBuilder::SendMCClientError(string_view str) {
|
||||||
serializer_->Send(v, ABSL_ARRAYSIZE(v));
|
serializer_->Send(v, ABSL_ARRAYSIZE(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReplyBuilder::EndMultilineReply() {
|
||||||
|
if (protocol_ == Protocol::MEMCACHE) {
|
||||||
|
serializer_->SendDirect("END\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ReplyBuilder::SendError(string_view str) {
|
void ReplyBuilder::SendError(string_view str) {
|
||||||
DCHECK(protocol_ == Protocol::REDIS);
|
DCHECK(protocol_ == Protocol::REDIS);
|
||||||
|
|
||||||
|
@ -134,4 +138,20 @@ void ReplyBuilder::SendError(OpStatus status) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReplyBuilder::SendGetReply(std::string_view key, uint32_t flags, std::string_view value) {
|
||||||
|
if (protocol_ == Protocol::REDIS) {
|
||||||
|
as_resp()->SendBulkString(value);
|
||||||
|
} else {
|
||||||
|
string first = absl::StrCat("VALUE ", key, " ", flags, " ", value.size(), "\r\n");
|
||||||
|
iovec v[] = {IoVec(first), IoVec(value), IoVec(kCRLF)};
|
||||||
|
serializer_->Send(v, ABSL_ARRAYSIZE(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplyBuilder::SendGetNotFound() {
|
||||||
|
if (protocol_ == Protocol::REDIS) {
|
||||||
|
as_resp()->SendNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dfly
|
} // namespace dfly
|
||||||
|
|
|
@ -76,6 +76,7 @@ class ReplyBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendMCClientError(std::string_view str);
|
void SendMCClientError(std::string_view str);
|
||||||
|
void EndMultilineReply();
|
||||||
|
|
||||||
void SendSimpleRespString(std::string_view str) {
|
void SendSimpleRespString(std::string_view str) {
|
||||||
as_resp()->SendSimpleString(str);
|
as_resp()->SendSimpleString(str);
|
||||||
|
@ -84,6 +85,10 @@ class ReplyBuilder {
|
||||||
void SendRespBlob(std::string_view str) {
|
void SendRespBlob(std::string_view str) {
|
||||||
as_resp()->SendDirect(str);
|
as_resp()->SendDirect(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendGetReply(std::string_view key, uint32_t flags, std::string_view value);
|
||||||
|
void SendGetNotFound();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RespSerializer* as_resp() {
|
RespSerializer* as_resp() {
|
||||||
return static_cast<RespSerializer*>(serializer_.get());
|
return static_cast<RespSerializer*>(serializer_.get());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue