Skip to content

Commit

Permalink
add zrevrange & zrevrangebyscore
Browse files Browse the repository at this point in the history
  • Loading branch information
KernelMaker committed Aug 26, 2015
1 parent 4f8a668 commit 1775ea1
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/pika_command.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,16 @@ class ZScoreCmd : public Cmd {
virtual void Do(std::list<std::string> &argvs, std::string &ret);
};

class ZRevrangeCmd : public Cmd {
public:
ZRevrangeCmd(int a) : Cmd(a) {};
virtual void Do(std::list<std::string> &argvs, std::string &ret);
};

class ZRevrangebyscoreCmd : public Cmd {
public:
ZRevrangebyscoreCmd(int a) : Cmd(a) {};
virtual void Do(std::list<std::string> &argvs, std::string &ret);
};

#endif
4 changes: 4 additions & 0 deletions src/pika.cc
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ int main(int argc, char **argv)
g_pikaCmd.insert(std::pair<std::string, Cmd *>("zrevrank", zrevrankptr));
ZScoreCmd *zscoreptr = new ZScoreCmd(3);
g_pikaCmd.insert(std::pair<std::string, Cmd *>("zscore", zscoreptr));
ZRevrangeCmd *zrevrangeptr = new ZRevrangeCmd(-4);
g_pikaCmd.insert(std::pair<std::string, Cmd *>("zrevrange", zrevrangeptr));
ZRevrangebyscoreCmd *zrevrangebyscoreptr = new ZRevrangebyscoreCmd(-4);
g_pikaCmd.insert(std::pair<std::string, Cmd *>("zrevrangebyscore", zrevrangebyscoreptr));

/*
* Init the server
Expand Down
204 changes: 204 additions & 0 deletions src/pika_zset.cc
Original file line number Diff line number Diff line change
Expand Up @@ -759,3 +759,207 @@ void ZScoreCmd::Do(std::list<std::string> &argv, std::string &ret) {
}
}

void ZRevrangeCmd::Do(std::list<std::string> &argv, std::string &ret) {
if ((arity > 0 && (int)argv.size() != arity) || (arity < 0 && (int)argv.size() < -arity)) {
ret = "-ERR wrong number of arguments for ";
ret.append(argv.front());
ret.append(" command\r\n");
return;
}
argv.pop_front();
std::string key = argv.front();
argv.pop_front();
std::string str_start = argv.front();
argv.pop_front();
int64_t start;
if (!string2l(str_start.data(), str_start.size(), &start)) {
ret = "-ERR value is not an integer or out of range\r\n";
return;
}
std::string str_stop = argv.front();
argv.pop_front();
int64_t stop;
if (!string2l(str_stop.data(), str_stop.size(), &stop)) {
ret = "-ERR value is not an integer or out of range\r\n";
return;
}
bool is_ws = false;
if (argv.size() == 1) {
std::string ws = argv.front();
transform(ws.begin(), ws.end(), ws.begin(), ::tolower);
if (ws == "withscores") {
is_ws = true;
} else {
ret = "-ERR syntax error\r\n";
return;
}
} else if (argv.size() > 1) {
ret = "-ERR syntax error\r\n";
return;
}

std::vector<nemo::SM> sms;
nemo::Status s = g_pikaServer->GetHandle()->ZRange(key, start, stop, sms);
if (s.ok()) {
char buf[32];
char buf_len[32];
std::vector<nemo::SM>::reverse_iterator iter;
if (is_ws) {
snprintf(buf, sizeof(buf), "*%lu\r\n", sms.size() * 2);
ret.append(buf);
for (iter = sms.rbegin(); iter != sms.rend(); iter++) {
snprintf(buf, sizeof(buf), "$%lu\r\n", iter->member.size());
ret.append(buf);
ret.append(iter->member.data(), iter->member.size());
ret.append("\r\n");
int32_t len = 0;
len = d2string(buf, sizeof(buf), iter->score);
snprintf(buf_len, sizeof(buf_len), "$%d\r\n", len);
ret.append(buf_len);
ret.append(buf);
ret.append("\r\n");
}
} else {
snprintf(buf, sizeof(buf), "*%lu\r\n", sms.size());
ret.append(buf);
for (iter = sms.rbegin(); iter != sms.rend(); iter++) {
snprintf(buf, sizeof(buf), "$%lu\r\n", iter->member.size());
ret.append(buf);
ret.append(iter->member.data(), iter->member.size());
ret.append("\r\n");
}
}
} else {
ret.append("-ERR ");
ret.append(s.ToString().c_str());
ret.append("\r\n");
}
}

void ZRevrangebyscoreCmd::Do(std::list<std::string> &argv, std::string &ret) {
if ((arity > 0 && (int)argv.size() != arity) || (arity < 0 && (int)argv.size() < -arity)) {
ret = "-ERR wrong number of arguments for ";
ret.append(argv.front());
ret.append(" command\r\n");
return;
}
argv.pop_front();
std::string key = argv.front();
argv.pop_front();
std::string str_start = argv.front();
argv.pop_front();
bool is_lo = false;
bool is_ro = false;
double start;
if (str_start[0] == '(') {
is_lo = true;
str_start = str_start.substr(1, str_start.size());
}
if (str_start == "-inf") {
start = nemo::ZSET_SCORE_MIN;
} else if (str_start == "+inf" || str_start == "inf") {
start = nemo::ZSET_SCORE_MAX;
} else {
if (!string2d(str_start.data(), str_start.size(), &start)) {
ret = "-ERR value is not an integer or out of range\r\n";
return;
}
}
std::string str_stop = argv.front();
argv.pop_front();
double stop;
if (str_stop[0] == '(') {
is_ro = true;
str_stop = str_stop.substr(1, str_stop.size());
}
if (str_stop == "+inf" || str_stop == "inf") {
stop = nemo::ZSET_SCORE_MAX;
} else if (str_stop == "-inf") {
stop = nemo::ZSET_SCORE_MIN;
} else {
if (!string2d(str_stop.data(), str_stop.size(), &stop)) {
ret = "-ERR value is not an integer or out of range\r\n";
return;
}
}

bool is_ws = false;
size_t size = argv.size();
int64_t offset = 0;
int64_t count = -1;
std::string ar;
if (size != 0 && size != 1 && size != 3 && size != 4) {
ret = "-ERR syntax error\r\n";
return;
} else {
while (argv.size() > 0) {
ar = argv.front();
argv.pop_front();
transform(ar.begin(), ar.end(), ar.begin(), ::tolower);
if (ar == "withscores") {
is_ws = true;
} else if (ar == "limit" && argv.size() >= 2) {
std::string str_offset;
std::string str_count;
str_offset = argv.front();
argv.pop_front();
if (!string2l(str_offset.data(), str_offset.size(), &offset)) {
ret = "-ERR syntax error\r\n";
return;
}
if (offset < 0) {
offset = 0;
}
str_count = argv.front();
argv.pop_front();
if (!string2l(str_count.data(), str_count.size(), &count)) {
ret = "-ERR syntax error\r\n";
return;
}
} else {
ret = "-ERR syntax error\r\n";
return;
}
}
std::vector<nemo::SM> sms;
nemo::Status s = g_pikaServer->GetHandle()->ZRangebyscore(key, stop, start, sms, offset, is_lo, is_ro);
if (s.ok()) {
std::vector<nemo::SM>::reverse_iterator iter;
count = count >= 0 ? count : INT_MAX;
char buf[32];
char buf_len[32];
uint64_t len = sms.size() > (uint64_t)count ? count : sms.size();
if (is_ws) {
snprintf(buf, sizeof(buf), "*%lu\r\n", len * 2);
ret.append(buf);
for (iter = sms.rbegin(); count != 0 && iter != sms.rend(); iter++, count--) {
snprintf(buf, sizeof(buf), "$%lu\r\n", iter->member.size());
ret.append(buf);
ret.append(iter->member.data(), iter->member.size());
ret.append("\r\n");
int32_t len = 0;
len = d2string(buf, sizeof(buf), iter->score);
snprintf(buf_len, sizeof(buf_len), "$%d\r\n", len);
ret.append(buf_len);
ret.append(buf);
ret.append("\r\n");
}
} else {
snprintf(buf, sizeof(buf), "*%lu\r\n", len);
ret.append(buf);
for (iter = sms.rbegin(); count != 0 && iter != sms.rend(); iter++, count--) {
snprintf(buf, sizeof(buf), "$%lu\r\n", iter->member.size());
ret.append(buf);
ret.append(iter->member.data(), iter->member.size());
ret.append("\r\n");
}
}
} else {
ret.append("-ERR ");
ret.append(s.ToString().c_str());
ret.append("\r\n");
}

}
}

0 comments on commit 1775ea1

Please sign in to comment.