mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-10 18:05:44 +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) {
|
||||
}
|
||||
|
||||
Protocol ConnectionContext::protocol() const {
|
||||
return owner_->protocol();
|
||||
}
|
||||
|
||||
} // namespace dfly
|
||||
|
|
|
@ -24,6 +24,8 @@ class ConnectionContext : public ReplyBuilder {
|
|||
return owner_;
|
||||
}
|
||||
|
||||
Protocol protocol() const;
|
||||
|
||||
private:
|
||||
Connection* owner_;
|
||||
};
|
||||
|
|
|
@ -146,6 +146,9 @@ void Service::DispatchMC(const MemcacheParser::Command& cmd, std::string_view va
|
|||
strcpy(cmd_name, "SET");
|
||||
strcpy(set_opt, "NX");
|
||||
break;
|
||||
case MemcacheParser::GET:
|
||||
strcpy(cmd_name, "GET");
|
||||
break;
|
||||
default:
|
||||
cntx->SendMCClientError("bad command line format");
|
||||
return;
|
||||
|
@ -168,7 +171,6 @@ void Service::DispatchMC(const MemcacheParser::Command& cmd, std::string_view va
|
|||
DispatchCommand(arg_list, cntx);
|
||||
}
|
||||
|
||||
|
||||
void Service::RegisterHttp(HttpListenerBase* listener) {
|
||||
CHECK_NOTNULL(listener);
|
||||
}
|
||||
|
@ -191,8 +193,8 @@ void Service::Ping(CmdArgList args, ConnectionContext* cntx) {
|
|||
void Service::Set(CmdArgList args, ConnectionContext* cntx) {
|
||||
set_qps.Inc();
|
||||
|
||||
std::string_view key = ArgS(args, 1);
|
||||
std::string_view val = ArgS(args, 2);
|
||||
string_view key = ArgS(args, 1);
|
||||
string_view val = ArgS(args, 2);
|
||||
VLOG(2) << "Set " << key << " " << val;
|
||||
|
||||
ShardId sid = Shard(key, shard_count());
|
||||
|
@ -205,6 +207,29 @@ void Service::Set(CmdArgList args, ConnectionContext* cntx) {
|
|||
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 res;
|
||||
|
@ -227,7 +252,8 @@ void Service::RegisterCommands() {
|
|||
using CI = CommandId;
|
||||
|
||||
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
|
||||
|
|
|
@ -48,6 +48,7 @@ class Service {
|
|||
private:
|
||||
void Ping(CmdArgList args, ConnectionContext* cntx);
|
||||
void Set(CmdArgList args, ConnectionContext* cntx);
|
||||
void Get(CmdArgList args, ConnectionContext* cntx);
|
||||
|
||||
void RegisterCommands();
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ void RespSerializer::SendSimpleString(std::string_view str) {
|
|||
Send(v, ABSL_ARRAYSIZE(v));
|
||||
}
|
||||
|
||||
|
||||
void RespSerializer::SendBulkString(std::string_view str) {
|
||||
char tmp[absl::numbers_internal::kFastToBufferSize + 3];
|
||||
tmp[0] = '$'; // Format length
|
||||
|
@ -97,7 +96,6 @@ void ReplyBuilder::SendStored() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void ReplyBuilder::SendMCClientError(string_view str) {
|
||||
DCHECK(protocol_ == Protocol::MEMCACHE);
|
||||
|
||||
|
@ -105,6 +103,12 @@ void ReplyBuilder::SendMCClientError(string_view str) {
|
|||
serializer_->Send(v, ABSL_ARRAYSIZE(v));
|
||||
}
|
||||
|
||||
void ReplyBuilder::EndMultilineReply() {
|
||||
if (protocol_ == Protocol::MEMCACHE) {
|
||||
serializer_->SendDirect("END\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ReplyBuilder::SendError(string_view str) {
|
||||
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
|
||||
|
|
|
@ -76,6 +76,7 @@ class ReplyBuilder {
|
|||
}
|
||||
|
||||
void SendMCClientError(std::string_view str);
|
||||
void EndMultilineReply();
|
||||
|
||||
void SendSimpleRespString(std::string_view str) {
|
||||
as_resp()->SendSimpleString(str);
|
||||
|
@ -84,6 +85,10 @@ class ReplyBuilder {
|
|||
void SendRespBlob(std::string_view str) {
|
||||
as_resp()->SendDirect(str);
|
||||
}
|
||||
|
||||
void SendGetReply(std::string_view key, uint32_t flags, std::string_view value);
|
||||
void SendGetNotFound();
|
||||
|
||||
private:
|
||||
RespSerializer* as_resp() {
|
||||
return static_cast<RespSerializer*>(serializer_.get());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue