mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 01:10:52 +08:00
580 lines
13 KiB
C++
580 lines
13 KiB
C++
#include "acl_stdafx.hpp"
|
|
#ifndef ACL_PREPARE_COMPILE
|
|
#include "acl_cpp/stdlib/string.hpp"
|
|
#include "acl_cpp/stdlib/dbuf_pool.hpp"
|
|
#include "acl_cpp/stdlib/snprintf.hpp"
|
|
#include "acl_cpp/redis/redis_client.hpp"
|
|
#include "acl_cpp/redis/redis_result.hpp"
|
|
#include "acl_cpp/redis/redis_list.hpp"
|
|
#endif
|
|
|
|
#if !defined(ACL_CLIENT_ONLY) && !defined(ACL_REDIS_DISABLE)
|
|
|
|
namespace acl
|
|
{
|
|
|
|
#define INT_LEN 11
|
|
#define LONG_LEN 21
|
|
|
|
redis_list::redis_list()
|
|
{
|
|
}
|
|
|
|
redis_list::redis_list(redis_client* conn)
|
|
: redis_command(conn)
|
|
{
|
|
}
|
|
|
|
redis_list::redis_list(redis_client_cluster* cluster)
|
|
: redis_command(cluster)
|
|
{
|
|
}
|
|
|
|
redis_list::redis_list(redis_client_cluster* cluster, size_t)
|
|
: redis_command(cluster)
|
|
{
|
|
}
|
|
|
|
redis_list::redis_list(redis_client_pipeline* pipeline)
|
|
: redis_command(pipeline)
|
|
{
|
|
}
|
|
|
|
redis_list::~redis_list()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
int redis_list::llen(const char* key)
|
|
{
|
|
const char* argv[2];
|
|
size_t lens[2];
|
|
|
|
argv[0] = "LLEN";
|
|
lens[0] = sizeof("LLEN") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
hash_slot(key);
|
|
build_request(2, argv, lens);
|
|
return get_number();
|
|
}
|
|
|
|
bool redis_list::lindex(const char* key, size_t idx, string& buf)
|
|
{
|
|
const char* argv[3];
|
|
size_t lens[3];
|
|
|
|
argv[0] = "LINDEX";
|
|
lens[0] = sizeof("LINDEX") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
char* tmp = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
(void) safe_snprintf(tmp, LONG_LEN, "%lu", (unsigned long) idx);
|
|
argv[2] = tmp;
|
|
lens[2] = strlen(tmp);
|
|
|
|
hash_slot(key);
|
|
build_request(3, argv, lens);
|
|
return get_string(buf) >= 0 ? true : false;
|
|
}
|
|
|
|
bool redis_list::lset(const char* key, int idx, const char* value)
|
|
{
|
|
return lset(key, idx, value, strlen(value));
|
|
}
|
|
|
|
bool redis_list::lset(const char* key, int idx, const char* value, size_t len)
|
|
{
|
|
const char* argv[4];
|
|
size_t lens[4];
|
|
|
|
argv[0] = "LSET";
|
|
lens[0] = sizeof("LSET") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
char* tmp = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
(void) safe_snprintf(tmp, LONG_LEN, "%lu", (unsigned long) idx);
|
|
argv[2] = tmp;
|
|
lens[2] = strlen(tmp);
|
|
|
|
argv[3] = value;
|
|
lens[3] = len;
|
|
|
|
hash_slot(key);
|
|
build_request(4, argv, lens);
|
|
return check_status();
|
|
}
|
|
|
|
int redis_list::linsert_before(const char* key, const char* pivot,
|
|
const char* value)
|
|
{
|
|
return linsert_before(key, pivot, strlen(pivot), value, strlen(value));
|
|
}
|
|
|
|
int redis_list::linsert_before(const char* key, const char* pivot,
|
|
size_t pivot_len, const char* value, size_t value_len)
|
|
{
|
|
return linsert(key, "BEFORE", pivot, pivot_len, value, value_len);
|
|
}
|
|
|
|
int redis_list::linsert_after(const char* key, const char* pivot,
|
|
const char* value)
|
|
{
|
|
return linsert_after(key, pivot, strlen(pivot), value, strlen(value));
|
|
}
|
|
|
|
int redis_list::linsert_after(const char* key, const char* pivot,
|
|
size_t pivot_len, const char* value, size_t value_len)
|
|
{
|
|
return linsert(key, "AFTER", pivot, pivot_len, value, value_len);
|
|
}
|
|
|
|
int redis_list::linsert(const char* key, const char* pos, const char* pivot,
|
|
size_t pivot_len, const char* value, size_t value_len)
|
|
{
|
|
const char* argv[5];
|
|
size_t lens[5];
|
|
|
|
argv[0] = "LINSERT";
|
|
lens[0] = sizeof("LINSERT") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
argv[2] = pos;
|
|
lens[2] = strlen(pos);
|
|
argv[3] = pivot;
|
|
lens[3] = pivot_len;
|
|
argv[4] = value;
|
|
lens[4] = value_len;
|
|
|
|
hash_slot(key);
|
|
build_request(5, argv, lens);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::lpush(const char* key, const char* first_value, ...)
|
|
{
|
|
std::vector<const char*> values;
|
|
values.push_back(first_value);
|
|
|
|
va_list ap;
|
|
va_start(ap, first_value);
|
|
const char* value;
|
|
|
|
while ((value = va_arg(ap, const char*)) != NULL)
|
|
values.push_back(value);
|
|
va_end(ap);
|
|
|
|
return lpush(key, values);
|
|
}
|
|
|
|
int redis_list::lpush(const char* key, const char* values[], size_t argc)
|
|
{
|
|
hash_slot(key);
|
|
build("LPUSH", key, values, argc);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::lpush(const char* key, const std::vector<string>& values)
|
|
{
|
|
hash_slot(key);
|
|
build("LPUSH", key, values);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::lpush(const char* key, const std::vector<const char*>& values)
|
|
{
|
|
hash_slot(key);
|
|
build("LPUSH", key, values);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::lpush(const char* key, const char* values[],
|
|
const size_t lens[], size_t argc)
|
|
{
|
|
hash_slot(key);
|
|
build("LPUSH", key, values, lens, argc);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::rpush(const char* key, const char* first_value, ...)
|
|
{
|
|
std::vector<const char*> values;
|
|
values.push_back(first_value);
|
|
|
|
va_list ap;
|
|
va_start(ap, first_value);
|
|
const char* value;
|
|
|
|
while ((value = va_arg(ap, const char*)) != NULL)
|
|
values.push_back(value);
|
|
va_end(ap);
|
|
|
|
return rpush(key, values);
|
|
}
|
|
|
|
int redis_list::rpush(const char* key, const char* values[], size_t argc)
|
|
{
|
|
hash_slot(key);
|
|
build("RPUSH", key, values, argc);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::rpush(const char* key, const std::vector<string>& values)
|
|
{
|
|
hash_slot(key);
|
|
build("RPUSH", key, values);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::rpush(const char* key, const std::vector<const char*>& values)
|
|
{
|
|
hash_slot(key);
|
|
build("RPUSH", key, values);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::rpush(const char* key, const char* values[],
|
|
const size_t lens[], size_t argc)
|
|
{
|
|
hash_slot(key);
|
|
build("RPUSH", key, values, lens, argc);
|
|
return get_number();
|
|
}
|
|
|
|
int redis_list::lpushx(const char* key, const char* value)
|
|
{
|
|
return lpushx(key, value, strlen(value));
|
|
}
|
|
|
|
int redis_list::lpushx(const char* key, const char* value, size_t len)
|
|
{
|
|
return pushx("LPUSHX", key, value, len);
|
|
}
|
|
|
|
int redis_list::rpushx(const char* key, const char* value)
|
|
{
|
|
return rpushx(key, value, strlen(value));
|
|
}
|
|
|
|
int redis_list::rpushx(const char* key, const char* value, size_t len)
|
|
{
|
|
return pushx("RPUSHX", key, value, len);
|
|
}
|
|
|
|
int redis_list::pushx(const char* cmd, const char* key,
|
|
const char* value, size_t len)
|
|
{
|
|
const char* argv[3];
|
|
size_t lens[3];
|
|
|
|
argv[0] = cmd;
|
|
lens[0] = strlen(cmd);
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
argv[2] = value;
|
|
lens[2] = len;
|
|
|
|
hash_slot(key);
|
|
build_request(3, argv, lens);
|
|
return get_number();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
int redis_list::lpop(const char* key, string& buf)
|
|
{
|
|
return pop("LPOP", key, buf);
|
|
}
|
|
|
|
int redis_list::rpop(const char* key, string& buf)
|
|
{
|
|
return pop("RPOP", key, buf);
|
|
}
|
|
|
|
int redis_list::pop(const char* cmd, const char* key, string& buf)
|
|
{
|
|
const char* argv[2];
|
|
size_t lens[2];
|
|
|
|
argv[0] = cmd;
|
|
lens[0] = strlen(cmd);
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
hash_slot(key);
|
|
build_request(2, argv, lens);
|
|
return (int) get_string(buf);
|
|
}
|
|
|
|
bool redis_list::blpop(std::pair<string, string>& result, size_t timeout,
|
|
const char* first_key, ...)
|
|
{
|
|
std::vector<const char*> keys;
|
|
keys.push_back(first_key);
|
|
|
|
va_list ap;
|
|
va_start(ap, first_key);
|
|
const char* key;
|
|
while ((key = va_arg(ap, const char*)) != NULL)
|
|
keys.push_back(key);
|
|
va_end(ap);
|
|
|
|
hash_slot(first_key);
|
|
return blpop(keys, timeout, result);
|
|
}
|
|
|
|
bool redis_list::blpop(const std::vector<const char*>& keys, size_t timeout,
|
|
std::pair<string, string>& result)
|
|
{
|
|
return bpop("BLPOP", keys, timeout, result);
|
|
}
|
|
|
|
|
|
bool redis_list::blpop(const std::vector<string>& keys, size_t timeout,
|
|
std::pair<string, string>& result)
|
|
{
|
|
return bpop("BLPOP", keys, timeout, result);
|
|
}
|
|
|
|
bool redis_list::brpop(std::pair<string, string>& result, size_t timeout,
|
|
const char* first_key, ...)
|
|
{
|
|
std::vector<const char*> keys;
|
|
keys.push_back(first_key);
|
|
|
|
va_list ap;
|
|
va_start(ap, first_key);
|
|
const char* key;
|
|
while ((key = va_arg(ap, const char*)) != NULL)
|
|
keys.push_back(key);
|
|
va_end(ap);
|
|
|
|
hash_slot(first_key);
|
|
return brpop(keys, timeout, result);
|
|
}
|
|
|
|
bool redis_list::brpop(const std::vector<const char*>& keys, size_t timeout,
|
|
std::pair<string, string>& result)
|
|
{
|
|
return bpop("BRPOP", keys, timeout, result);
|
|
}
|
|
|
|
|
|
bool redis_list::brpop(const std::vector<string>& keys, size_t timeout,
|
|
std::pair<string, string>& result)
|
|
{
|
|
return bpop("BRPOP", keys, timeout, result);
|
|
}
|
|
|
|
bool redis_list::bpop(const char* cmd, const std::vector<const char*>& keys,
|
|
size_t timeout, std::pair<string, string>& result)
|
|
{
|
|
size_t argc = 2 + keys.size();
|
|
const char** args = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*));
|
|
size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t));
|
|
|
|
args[0] = cmd;
|
|
lens[0] = strlen(cmd);
|
|
|
|
size_t i = 1;
|
|
std::vector<const char*>::const_iterator cit = keys.begin();
|
|
for (; cit != keys.end(); ++cit) {
|
|
args[i] = *cit;
|
|
lens[i] = strlen(args[i]);
|
|
i++;
|
|
}
|
|
|
|
char* buf = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
safe_snprintf(buf, LONG_LEN, "%lu", (unsigned long) timeout);
|
|
args[i] = buf;
|
|
lens[i] = strlen(args[i]);
|
|
|
|
build_request(argc, args, lens);
|
|
return bpop(result);
|
|
}
|
|
|
|
bool redis_list::bpop(const char* cmd, const std::vector<string>& keys,
|
|
size_t timeout, std::pair<string, string>& result)
|
|
{
|
|
size_t argc = 2 + keys.size();
|
|
const char** args = (const char**) dbuf_->dbuf_alloc(argc * sizeof(char*));
|
|
size_t* lens = (size_t*) dbuf_->dbuf_alloc(argc * sizeof(size_t));
|
|
|
|
args[0] = cmd;
|
|
lens[0] = strlen(cmd);
|
|
|
|
size_t i = 1;
|
|
std::vector<string>::const_iterator cit = keys.begin();
|
|
for (; cit != keys.end(); ++cit) {
|
|
args[i] = (*cit).c_str();
|
|
lens[i] = (*cit).length();
|
|
i++;
|
|
}
|
|
|
|
char* buf = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
safe_snprintf(buf, LONG_LEN, "%lu", (unsigned long) timeout);
|
|
args[i] = buf;
|
|
lens[i] = strlen(args[i]);
|
|
|
|
build_request(argc, args, lens);
|
|
return bpop(result);
|
|
}
|
|
|
|
bool redis_list::bpop(std::pair<string, string>& out)
|
|
{
|
|
int rw_timeout = -1;
|
|
const redis_result* result = run(0, &rw_timeout);
|
|
if (result == NULL)
|
|
return false;
|
|
if (result->get_type() != REDIS_RESULT_ARRAY)
|
|
return false;
|
|
size_t size = result->get_size();
|
|
if (size == 0)
|
|
return false;
|
|
if (size != 2)
|
|
return false;
|
|
|
|
const redis_result* first = result->get_child(0);
|
|
const redis_result* second = result->get_child(1);
|
|
if (first == NULL || second == NULL
|
|
|| first->get_type() != REDIS_RESULT_STRING
|
|
|| second->get_type() != REDIS_RESULT_STRING) {
|
|
|
|
return false;
|
|
}
|
|
|
|
string buf;
|
|
first->argv_to_string(buf);
|
|
out.first = buf;
|
|
|
|
second->argv_to_string(buf);
|
|
out.second = buf;
|
|
return true;
|
|
}
|
|
|
|
bool redis_list::rpoplpush(const char* src, const char* dst,
|
|
string* buf /* = NULL */)
|
|
{
|
|
const char* argv[3];
|
|
size_t lens[3];
|
|
|
|
argv[0] = "RPOPLPUSH";
|
|
lens[0] = sizeof("RPOPLPUSH") - 1;
|
|
argv[1] = src;
|
|
lens[1] = strlen(src);
|
|
argv[2] = dst;
|
|
lens[2] = strlen(dst);
|
|
|
|
build_request(3, argv, lens);
|
|
return get_string(buf) >= 0 ? true : false;
|
|
}
|
|
|
|
bool redis_list::brpoplpush(const char* src, const char* dst,
|
|
size_t timeout, string* buf /* = NULL */)
|
|
{
|
|
const char* argv[4];
|
|
size_t lens[4];
|
|
|
|
argv[0] = "BRPOPLPUSH";
|
|
lens[0] = sizeof("BRPOPLPUSH") - 1;
|
|
argv[1] = src;
|
|
lens[1] = strlen(src);
|
|
argv[2] = dst;
|
|
lens[2] = strlen(dst);
|
|
|
|
char* tmp = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
safe_snprintf(tmp, LONG_LEN, "%lu", (unsigned long) timeout);
|
|
argv[3] = tmp;
|
|
lens[3] = strlen(argv[3]);
|
|
|
|
build_request(4, argv, lens);
|
|
return get_string(buf) >= 0 ? true : false;
|
|
}
|
|
|
|
bool redis_list::lrange(const char* key, int start, int end,
|
|
std::vector<string>* result)
|
|
{
|
|
const char* argv[4];
|
|
size_t lens[4];
|
|
|
|
argv[0] = "LRANGE";
|
|
lens[0] = sizeof("LRANGE") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
char* start_s = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
char* end_s = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
safe_snprintf(start_s, LONG_LEN, "%d", start);
|
|
safe_snprintf(end_s, LONG_LEN, "%d", end);
|
|
|
|
argv[2] = start_s;
|
|
lens[2] = strlen(start_s);
|
|
argv[3] = end_s;
|
|
lens[3] = strlen(end_s);
|
|
|
|
hash_slot(key);
|
|
build_request(4, argv, lens);
|
|
return get_strings(result) < 0 ? false : true;
|
|
}
|
|
|
|
int redis_list::lrem(const char* key, int count, const char* value)
|
|
{
|
|
return lrem(key, count, value, strlen(value));
|
|
}
|
|
|
|
int redis_list::lrem(const char* key, int count, const char* value, size_t len)
|
|
{
|
|
const char* argv[4];
|
|
size_t lens[4];
|
|
|
|
argv[0] = "LREM";
|
|
lens[0] = sizeof("LREM") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
char* buf = (char*) dbuf_->dbuf_alloc(INT_LEN);
|
|
safe_snprintf(buf, INT_LEN, "%d", count);
|
|
argv[2] = buf;
|
|
lens[2] = strlen(buf);
|
|
|
|
argv[3] = value;
|
|
lens[3] = len;
|
|
|
|
hash_slot(key);
|
|
build_request(4, argv, lens);
|
|
return get_number();
|
|
}
|
|
|
|
bool redis_list::ltrim(const char* key, int start, int end)
|
|
{
|
|
const char* argv[4];
|
|
size_t lens[4];
|
|
|
|
argv[0] = "LTRIM";
|
|
lens[0] = sizeof("LTRIM") - 1;
|
|
argv[1] = key;
|
|
lens[1] = strlen(key);
|
|
|
|
char* start_s = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
char* end_s = (char*) dbuf_->dbuf_alloc(LONG_LEN);
|
|
safe_snprintf(start_s, LONG_LEN, "%d", start);
|
|
safe_snprintf(end_s, LONG_LEN, "%d", end);
|
|
|
|
argv[2] = start_s;
|
|
lens[2] = strlen(start_s);
|
|
argv[3] = end_s;
|
|
lens[3] = strlen(end_s);
|
|
|
|
hash_slot(key);
|
|
build_request(4, argv, lens);
|
|
return check_status();
|
|
}
|
|
|
|
} // namespace acl
|
|
|
|
#endif // ACL_CLIENT_ONLY
|