mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-29 18:37:41 +08:00
optimize and test pkv
This commit is contained in:
parent
dcd8b7478c
commit
d1bf85c81c
@ -5,17 +5,21 @@
|
||||
#include "stdafx.h"
|
||||
#include "proto/redis_object.h"
|
||||
#include "proto/redis_coder.h"
|
||||
#include "redis_key.h"
|
||||
#include "redis_string.h"
|
||||
#include "redis_handler.h"
|
||||
|
||||
namespace pkv {
|
||||
|
||||
#define EQ !strcasecmp
|
||||
|
||||
redis_handler::redis_handler(shared_db& db, const redis_coder& parser,
|
||||
redis_handler::redis_handler(shared_db& db, redis_coder& parser,
|
||||
acl::socket_stream& conn)
|
||||
: db_(db)
|
||||
, parser_(parser)
|
||||
, conn_(conn)
|
||||
, builder_(parser.get_cache())
|
||||
, coder_(parser.get_cache())
|
||||
{
|
||||
}
|
||||
|
||||
@ -68,13 +72,17 @@ bool redis_handler::handle_one(const redis_object &obj) {
|
||||
//
|
||||
//
|
||||
if (EQ(cmd, "SET")) {
|
||||
return set(obj);
|
||||
redis_string redis(db_, obj, parser_);
|
||||
return redis.set(builder_);
|
||||
} else if (EQ(cmd, "GET")) {
|
||||
return get(obj);
|
||||
redis_string redis(db_, obj, parser_);
|
||||
return redis.get(builder_);
|
||||
} else if (EQ(cmd, "DEL")) {
|
||||
return del(obj);
|
||||
redis_key redis(db_, obj, parser_);
|
||||
return redis.del(builder_);
|
||||
} else if (EQ(cmd, "TYPE")) {
|
||||
return type(obj);
|
||||
redis_key redis(db_, obj, parser_);
|
||||
return redis.type(builder_);
|
||||
} else if (EQ(cmd, "HSET")) {
|
||||
return hset(obj);
|
||||
} else if (EQ(cmd, "HGET")) {
|
||||
@ -96,118 +104,6 @@ bool redis_handler::handle_one(const redis_object &obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_handler::set(const redis_object &obj) {
|
||||
auto& objs = obj.get_objects();
|
||||
if (objs.size() < 3) {
|
||||
logger_error("invalid SET params' size=%zd", objs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto key = objs[1]->get_str();
|
||||
if (key == nullptr || *key == 0) {
|
||||
logger_error("key null");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto value = objs[2]->get_str();
|
||||
if (value == nullptr || *value == 0) {
|
||||
logger_error("value null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!var_cfg_disable_serialize) {
|
||||
std::string buff;
|
||||
coder_.create_object().set_string(value);
|
||||
coder_.to_string(buff);
|
||||
coder_.clear();
|
||||
|
||||
if (!var_cfg_disable_save) {
|
||||
if (!db_->set(key, buff.c_str())) {
|
||||
logger_error("db set error, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builder_.create_object().set_status("OK");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_handler::get(const redis_object &obj) {
|
||||
auto& objs = obj.get_objects();
|
||||
if (objs.size() < 2) {
|
||||
logger_error("invalid GET params' size=%zd", objs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto key = objs[1]->get_str();
|
||||
if (key == nullptr || *key == 0) {
|
||||
logger_error("key null");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string buff;
|
||||
if (!db_->get(key, buff) || buff.empty()) {
|
||||
logger_error("db get error, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
redis_coder builder;
|
||||
size_t len = buff.size();
|
||||
(void) builder.update(buff.c_str(), len);
|
||||
if (len > 0) {
|
||||
logger_error("invalid buff in db, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& objs2 = builder.get_objects();
|
||||
if (objs2.size() != 1) {
|
||||
logger_error("invalid object in db, key=%s, size=%zd", key, objs2.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto o = objs2[0];
|
||||
if (o->get_type() != REDIS_OBJ_STRING) {
|
||||
logger_error("invalid object type=%d, key=%s", (int) o->get_type(), key);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto v = o->get_str();
|
||||
if (v == nullptr || *v == 0) {
|
||||
logger_error("value null, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
builder_.create_object().set_string(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_handler::del(const redis_object &obj) {
|
||||
auto& objs = obj.get_objects();
|
||||
if (objs.size() < 2) {
|
||||
logger_error("invalid SET params' size=%zd", objs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto key = objs[1]->get_str();
|
||||
if (key == nullptr || *key == 0) {
|
||||
logger_error("key null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!db_->del(key)) {
|
||||
logger_error("db del error, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
builder_.create_object().set_number(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_handler::type(const redis_object &obj) {
|
||||
builder_.create_object().set_status("string");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_handler::hset(const redis_object &obj) {
|
||||
auto& objs = obj.get_objects();
|
||||
if (objs.size() < 4) {
|
||||
@ -233,7 +129,7 @@ bool redis_handler::hset(const redis_object &obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
redis_coder builder;
|
||||
redis_coder builder(parser_.get_cache());
|
||||
builder.create_object()
|
||||
.create_child().set_string(name, true)
|
||||
.create_child().set_string(value, true);
|
||||
@ -281,7 +177,7 @@ bool redis_handler::hget(const redis_object &obj) {
|
||||
|
||||
//printf(">>hget: [%s]\r\n", buff.c_str());
|
||||
|
||||
redis_coder builder;
|
||||
redis_coder builder(parser_.get_cache());
|
||||
size_t len = buff.size();
|
||||
(void) builder.update(buff.c_str(), len);
|
||||
if (len > 0) {
|
||||
|
@ -13,7 +13,7 @@ class redis_object;
|
||||
|
||||
class redis_handler {
|
||||
public:
|
||||
explicit redis_handler(shared_db& db, const redis_coder& parser,
|
||||
explicit redis_handler(shared_db& db, redis_coder& parser,
|
||||
acl::socket_stream& conn);
|
||||
~redis_handler() = default;
|
||||
|
||||
@ -21,17 +21,13 @@ public:
|
||||
|
||||
private:
|
||||
shared_db& db_;
|
||||
const redis_coder& parser_;
|
||||
redis_coder& parser_;
|
||||
acl::socket_stream& conn_;
|
||||
redis_coder builder_;
|
||||
redis_coder coder_;
|
||||
acl::socket_stream& conn_;
|
||||
|
||||
bool handle_one(const redis_object& obj);
|
||||
|
||||
bool set(const redis_object& obj);
|
||||
bool get(const redis_object& obj);
|
||||
bool del(const redis_object& obj);
|
||||
bool type(const redis_object& obj);
|
||||
bool hset(const redis_object& obj);
|
||||
bool hget(const redis_object& obj);
|
||||
bool hdel(const redis_object& obj);
|
||||
|
43
app/wizard_demo/pkv/action/redis_key.cpp
Normal file
43
app/wizard_demo/pkv/action/redis_key.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by shuxin ¡¡¡¡zheng on 2023/7/31.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "redis_key.h"
|
||||
|
||||
namespace pkv {
|
||||
|
||||
redis_key::redis_key(shared_db& db, const redis_object& obj, redis_coder& base)
|
||||
: db_(db), obj_(obj), base_(base)
|
||||
{
|
||||
(void) base_;
|
||||
}
|
||||
|
||||
bool redis_key::del(redis_coder& result) {
|
||||
auto& objs = obj_.get_objects();
|
||||
if (objs.size() < 2) {
|
||||
logger_error("invalid SET params' size=%zd", objs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto key = objs[1]->get_str();
|
||||
if (key == nullptr || *key == 0) {
|
||||
logger_error("key null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!db_->del(key)) {
|
||||
logger_error("db del error, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
result.create_object().set_number(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_key::type(redis_coder& result) {
|
||||
result.create_object().set_status("string");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace pkv
|
28
app/wizard_demo/pkv/action/redis_key.h
Normal file
28
app/wizard_demo/pkv/action/redis_key.h
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by shuxin ¡¡¡¡zheng on 2023/7/31.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "dao/db.h"
|
||||
#include "proto/redis_coder.h"
|
||||
|
||||
namespace pkv {
|
||||
|
||||
class redis_object;
|
||||
class redis_coder;
|
||||
|
||||
class redis_key {
|
||||
public:
|
||||
redis_key(shared_db& db, const redis_object& obj, redis_coder& base);
|
||||
~redis_key() = default;
|
||||
|
||||
bool del(redis_coder& result);
|
||||
bool type(redis_coder& result);
|
||||
|
||||
private:
|
||||
shared_db& db_;
|
||||
const redis_object& obj_;
|
||||
redis_coder& base_;
|
||||
};
|
||||
|
||||
} // namespace pkv
|
108
app/wizard_demo/pkv/action/redis_string.cpp
Normal file
108
app/wizard_demo/pkv/action/redis_string.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
//
|
||||
// Created by shuxin ¡¡¡¡zheng on 2023/7/31.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "proto/redis_coder.h"
|
||||
#include "proto/redis_object.h"
|
||||
#include "redis_string.h"
|
||||
|
||||
namespace pkv {
|
||||
|
||||
redis_string::redis_string(shared_db& db, const redis_object &obj,
|
||||
redis_coder& base)
|
||||
: db_(db), obj_(obj), base_(base) {}
|
||||
|
||||
bool redis_string::set(redis_coder& result) {
|
||||
auto& objs = obj_.get_objects();
|
||||
if (objs.size() < 3) {
|
||||
logger_error("invalid SET params' size=%zd", objs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto key = objs[1]->get_str();
|
||||
if (key == nullptr || *key == 0) {
|
||||
logger_error("key null");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto value = objs[2]->get_str();
|
||||
if (value == nullptr || *value == 0) {
|
||||
logger_error("value null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!var_cfg_disable_serialize) {
|
||||
std::string buff;
|
||||
redis_coder coder(base_.get_cache());
|
||||
coder.create_object().create_child().set_string("string", true) // type
|
||||
.create_child().set_number(-1); // expire time
|
||||
coder.create_object().set_string(value);
|
||||
coder.to_string(buff);
|
||||
coder.clear();
|
||||
|
||||
//printf("buf=[%s]\n", buff.c_str());
|
||||
|
||||
if (!var_cfg_disable_save) {
|
||||
if (!db_->set(key, buff.c_str())) {
|
||||
logger_error("db set error, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.create_object().set_status("OK");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool redis_string::get(redis_coder& result) {
|
||||
auto& objs = obj_.get_objects();
|
||||
if (objs.size() < 2) {
|
||||
logger_error("invalid GET params' size=%zd", objs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto key = objs[1]->get_str();
|
||||
if (key == nullptr || *key == 0) {
|
||||
logger_error("key null");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string buff;
|
||||
if (!db_->get(key, buff) || buff.empty()) {
|
||||
logger_error("db get error, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
//printf(">>>get key=%s, val=[%s]\n", key, buff.c_str());
|
||||
redis_coder builder(base_.get_cache());
|
||||
size_t len = buff.size();
|
||||
(void) builder.update(buff.c_str(), len);
|
||||
if (len > 0) {
|
||||
logger_error("invalid buff in db, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& objs2 = builder.get_objects();
|
||||
if (objs2.size() != 2) {
|
||||
logger_error("invalid object in db, key=%s, size=%zd", key, objs2.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto o = objs2[1];
|
||||
if (o->get_type() != REDIS_OBJ_STRING) {
|
||||
logger_error("invalid object type=%d, key=%s", (int) o->get_type(), key);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto v = o->get_str();
|
||||
if (v == nullptr || *v == 0) {
|
||||
logger_error("value null, key=%s", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
result.create_object().set_string(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace pkv
|
27
app/wizard_demo/pkv/action/redis_string.h
Normal file
27
app/wizard_demo/pkv/action/redis_string.h
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by shuxin ¡¡¡¡zheng on 2023/7/31.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "dao/db.h"
|
||||
|
||||
namespace pkv {
|
||||
|
||||
class redis_object;
|
||||
class redis_coder;
|
||||
|
||||
class redis_string {
|
||||
public:
|
||||
redis_string(shared_db& db, const redis_object &obj, redis_coder& base);
|
||||
~redis_string() = default;
|
||||
|
||||
bool set(redis_coder& result);
|
||||
bool get(redis_coder& result);
|
||||
|
||||
private:
|
||||
shared_db& db_;
|
||||
const redis_object &obj_;
|
||||
redis_coder& base_;
|
||||
};
|
||||
|
||||
} // namespace pkv
|
@ -52,7 +52,8 @@ void master_service::on_accept(acl::socket_stream& conn) {
|
||||
}
|
||||
|
||||
void master_service::run(acl::socket_stream& conn, size_t size) {
|
||||
pkv::redis_coder parser;
|
||||
std::vector<redis_object*> cache;
|
||||
pkv::redis_coder parser(cache);
|
||||
pkv::redis_handler handler(db_, parser, conn);
|
||||
char buf[size];
|
||||
|
||||
@ -80,6 +81,10 @@ void master_service::run(acl::socket_stream& conn, size_t size) {
|
||||
|
||||
parser.clear();
|
||||
}
|
||||
|
||||
for (auto obj : cache) {
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
void master_service::proc_pre_jail() {
|
||||
|
@ -7,9 +7,16 @@
|
||||
|
||||
namespace pkv {
|
||||
|
||||
redis_coder::redis_coder(size_t cache_max) {
|
||||
cache_max_ = cache_max;
|
||||
curr_ = new redis_object(cache_, cache_max_);
|
||||
redis_coder::redis_coder(std::vector<redis_object*>& cache, size_t cache_max)
|
||||
: cache_(cache)
|
||||
, cache_max_(cache_max)
|
||||
{
|
||||
if (cache_.empty()) {
|
||||
curr_ = new redis_object(cache_, cache_max_);
|
||||
} else {
|
||||
curr_ = cache_.back();
|
||||
cache_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
redis_coder::~redis_coder() {
|
||||
@ -17,10 +24,6 @@ redis_coder::~redis_coder() {
|
||||
delete obj;
|
||||
}
|
||||
|
||||
for (auto obj : cache_) {
|
||||
delete obj;
|
||||
}
|
||||
|
||||
delete curr_;
|
||||
}
|
||||
|
||||
@ -105,7 +108,8 @@ bool test_redis_parse_once(const char* filepath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
redis_coder parser;
|
||||
std::vector<redis_object*> cache;
|
||||
redis_coder parser(cache);
|
||||
const char* data = buf.c_str();
|
||||
size_t len = buf.size();
|
||||
const char* left = parser.update(data, len);
|
||||
@ -153,7 +157,8 @@ bool test_redis_parse_stream(const char* filepath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
redis_coder parser;
|
||||
std::vector<redis_object*> cache;
|
||||
redis_coder parser(cache);
|
||||
const char* data = buf.c_str();
|
||||
size_t len = buf.size();
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
@ -191,7 +196,8 @@ bool test_redis_parse_stream(const char* filepath) {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool test_redis_build() {
|
||||
redis_coder builder;
|
||||
std::vector<redis_object*> cache;
|
||||
redis_coder builder(cache);
|
||||
|
||||
auto& obj = builder.create_object();
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace pkv {
|
||||
|
||||
class redis_coder {
|
||||
public:
|
||||
explicit redis_coder(size_t cache_max = 10000);
|
||||
explicit redis_coder(std::vector<redis_object*>& cache, size_t cache_max = 10000);
|
||||
~redis_coder();
|
||||
|
||||
const char* update(const char* data, size_t& len);
|
||||
@ -27,14 +27,18 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
NODISCARD std::vector<redis_object*>& get_cache() const {
|
||||
return cache_;
|
||||
}
|
||||
|
||||
public:
|
||||
NODISCARD redis_object& create_object();
|
||||
|
||||
bool to_string(std::string& out) const;
|
||||
|
||||
private:
|
||||
std::vector<redis_object*>& cache_;
|
||||
std::vector<redis_object*> objs_;
|
||||
std::vector<redis_object*> cache_;
|
||||
size_t cache_max_;
|
||||
redis_object* curr_;
|
||||
};
|
||||
|
@ -434,7 +434,7 @@ redis_object& redis_object::set_error(const std::string& data,
|
||||
return return_parent ? *parent_ : *this;
|
||||
}
|
||||
|
||||
redis_object& redis_object::set_number(int n, bool return_parent) {
|
||||
redis_object& redis_object::set_number(long long n, bool return_parent) {
|
||||
type_ = REDIS_OBJ_INTEGER;
|
||||
buf_ = std::to_string(n);
|
||||
return return_parent ? *parent_ : *this;
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
public:
|
||||
redis_object& set_status(const std::string& data, bool return_parent = false);
|
||||
redis_object& set_error(const std::string& data, bool return_parent = false);
|
||||
redis_object& set_number(int n, bool return_parent = false);
|
||||
redis_object& set_number(long long n, bool return_parent = false);
|
||||
redis_object& set_string(const std::string& data, bool return_parent = false);
|
||||
redis_object& create_child();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user