Skip to content

Commit

Permalink
feat: Add string command bitop (#47)
Browse files Browse the repository at this point in the history
* feat:add string command bitop

* feat:add string command bitop

* feat : add string cmd bitop

* feat: add string cmd bitop

* feat: add string cmd bitop

* feat: add stream cmd bitop bitop ops

* feat : Add string command bitop

* feat : Add string command bitop

* feat : Add string command bitop

* feat : Add string command bitop

* feat : Add string command bitop

* feat: add string command bitop

* mearge branch

* mearge branch

* merge branch

* merge brance

* merge branch

* merge branch

* feat: string cmd bitop
  • Loading branch information
callme-taota authored Dec 3, 2023
1 parent 5f8ee3b commit 171844d
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/base_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace pikiwidb {
// string cmd
const std::string kCmdNameSet = "set";
const std::string kCmdNameGet = "get";
const std::string kCmdNameBitOp = "bitop";
const std::string kCmdNameIncrby = "incrby";
const std::string kCmdNameStrlen = "strlen";
const std::string kCmdNameSetex = "setex";
Expand Down
113 changes: 112 additions & 1 deletion src/cmd_kv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

#include "cmd_kv.h"
#include "pstd_string.h"
#include "pstd/pstd_string.h"
#include "pstd_util.h"
#include "store.h"

Expand Down Expand Up @@ -216,6 +216,117 @@ void BitCountCmd::DoCmd(PClient* client) {
client->AppendInteger(static_cast<int64_t>(count));
}

BitOpCmd::BitOpCmd(const std::string& name, int16_t arity)
: BaseCmd(name, arity, CmdFlagsWrite, AclCategoryWrite | AclCategoryString) {}

bool BitOpCmd::DoInitial(PClient* client) {
if (!(pstd::StringEqualCaseInsensitive(client->argv_[1], "and") ||
pstd::StringEqualCaseInsensitive(client->argv_[1], "or") ||
pstd::StringEqualCaseInsensitive(client->argv_[1], "not") ||
pstd::StringEqualCaseInsensitive(client->argv_[1], "xor"))) {
client->SetRes(CmdRes::kSyntaxErr, "operation error");
return false;
}
return true;
}

static std::string StringBitOp(const std::vector<std::string>& keys, BitOpCmd::BitOp op) {
PString res;

switch (op) {
case BitOpCmd::kBitOpAnd:
case BitOpCmd::kBitOpOr:
case BitOpCmd::kBitOpXor:
for (auto k : keys) {
PObject* val = nullptr;
if (PSTORE.GetValueByType(k, val, PType_string) != PError_ok) {
continue;
}

auto str = GetDecodedString(val);
if (res.empty()) {
res = *str;
continue;
}

if (str->size() > res.size()) {
res.resize(str->size());
}

for (size_t i = 0; i < str->size(); ++i) {
if (op == BitOpCmd::kBitOpAnd) {
res[i] &= (*str)[i];
} else if (op == BitOpCmd::kBitOpOr) {
res[i] |= (*str)[i];
} else if (op == BitOpCmd::kBitOpXor) {
res[i] ^= (*str)[i];
}
}
}
break;

case BitOpCmd::kBitOpNot: {
assert(keys.size() == 1);
PObject* val = nullptr;
if (PSTORE.GetValueByType(keys[0], val, PType_string) != PError_ok) {
break;
}

auto str = GetDecodedString(val);
res.resize(str->size());

for (size_t i = 0; i < str->size(); ++i) {
res[i] = ~(*str)[i];
}

break;
}

default:
break;
}

return res;
}

void BitOpCmd::DoCmd(PClient* client) {
std::vector<std::string> keys;
for (size_t i = 3; i < client->argv_.size(); ++i) {
keys.push_back(client->argv_[i]);
}

PError err = PError_param;
PString res;

if (client->Key().size() == 2) {
if (pstd::StringEqualCaseInsensitive(client->argv_[1], "or")) {
err = PError_ok;
res = StringBitOp(keys, kBitOpOr);
}
} else if (client->Key().size() == 3) {
if (pstd::StringEqualCaseInsensitive(client->argv_[1], "xor")) {
err = PError_ok;
res = StringBitOp(keys, kBitOpXor);
} else if (pstd::StringEqualCaseInsensitive(client->argv_[1], "and")) {
err = PError_ok;
res = StringBitOp(keys, kBitOpAnd);
} else if (pstd::StringEqualCaseInsensitive(client->argv_[1], "not")) {
if (client->argv_.size() == 4) {
err = PError_ok;
res = StringBitOp(keys, kBitOpNot);
}
}
}

if (err != PError_ok) {
client->SetRes(CmdRes::kSyntaxErr);
} else {
PSTORE.SetValue(client->argv_[2], PObject::CreateString(res));
client->SetRes(CmdRes::kOk, std::to_string(static_cast<long>(res.size())));
}
client->SetRes(CmdRes::kOk, std::to_string(static_cast<long>(res.size())));
}

StrlenCmd::StrlenCmd(const std::string& name, int16_t arity)
: BaseCmd(name, arity, CmdFlagsReadonly, AclCategoryRead | AclCategoryString) {}

Expand Down
17 changes: 17 additions & 0 deletions src/cmd_kv.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ class SetCmd : public BaseCmd {
void DoCmd(PClient *client) override;
};

class BitOpCmd : public BaseCmd {
public:
enum BitOp {
kBitOpAnd,
kBitOpOr,
kBitOpNot,
kBitOpXor,
};
BitOpCmd(const std::string &name, int16_t arity);

protected:
bool DoInitial(PClient *client) override;

private:
void DoCmd(PClient *client) override;
};

class StrlenCmd : public BaseCmd {
public:
StrlenCmd(const std::string &name, int16_t arity);
Expand Down
3 changes: 3 additions & 0 deletions src/cmd_table_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void CmdTableManager::InitCmdTable() {
cmds_->insert(std::make_pair(kCmdNameGet, std::move(getPtr)));
std::unique_ptr<BaseCmd> setPtr = std::make_unique<SetCmd>(kCmdNameSet, -3);
cmds_->insert(std::make_pair(kCmdNameSet, std::move(setPtr)));

std::unique_ptr<BaseCmd> bitOpPtr = std::make_unique<BitOpCmd>(kCmdNameBitOp, -4);
cmds_->insert(std::make_pair(kCmdNameBitOp, std::move(bitOpPtr)));
std::unique_ptr<BaseCmd> appendPtr = std::make_unique<AppendCmd>(kCmdNameAppend, 3);
cmds_->insert(std::make_pair(kCmdNameAppend, std::move(appendPtr)));
std::unique_ptr<BaseCmd> getsetPtr = std::make_unique<GetsetCmd>(kCmdNameGetset, 3);
Expand Down
2 changes: 1 addition & 1 deletion src/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const PCommandInfo PCommandTable::s_info[] = {
{"mget", PAttr_read, -2, &mget},
{"append", PAttr_write, 3, &append},
{"bitcount", PAttr_read, -2, &bitcount},
{"bitop", PAttr_write, -4, &bitop},
// {"bitop", PAttr_write, -4, &bitop},
{"getbit", PAttr_read, 3, &getbit},
{"setbit", PAttr_write, 4, &setbit},
{"incr", PAttr_write, 2, &incr},
Expand Down

0 comments on commit 171844d

Please sign in to comment.