static bool test_zinterstore(acl::redis_zset& redis ,int n) { acl::string dest_key, src1_key, src2_key; std::vector<acl::string> src_keys; for (int i = 0; i < n; i++) { dest_key.format("zset_dest_key_%d", i); src1_key.format("zset_src1_key_%d", i); src_keys.push_back(src1_key); src2_key.format("zset_src2_key_%d", i); src_keys.push_back(src2_key); redis.clear(); int ret = redis.zinterstore(dest_key.c_str(), src_keys); if (ret < 0) { printf("zinterstore error, dest: %s\r\n", dest_key.c_str()); return false; } src_keys.clear(); } return true; }
static bool test_zincrby(acl::redis_zset& redis, int n) { acl::string key; double inc = 2.5, result; acl::string member; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); for (int j = 0; j < 1000; j++) { member.format("member_%d", j); redis.clear(); if (redis.zincrby(key.c_str(), inc, member.c_str(), &result) == false) { printf("zincrby error, key: %s\r\n", key.c_str()); return false; } else if (j < 10 && i * j < 100) printf("zincrby ok key: %s, result: %.2f\r\n", key.c_str(), result); } } return true; }
static bool test_zrangebylex(acl::redis_zset& redis, int n) { acl::string key; const char* min = "[aaa", *max = "(g"; std::vector<acl::string> result; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); redis.clear(); int ret = redis.zrangebylex(key.c_str(), min, max, &result); if (ret < 0) { printf("zrangebylex error(%s), key: %s\r\n", redis.result_error(), key.c_str()); return false; } if (i >= 10) { result.clear(); continue; } std::vector<acl::string>::const_iterator cit; for (cit = result.begin(); cit != result.end(); ++cit) { if (cit != result.begin()) printf(", "); printf("%s", (*cit).c_str()); } printf("\r\n"); } return true; }
static bool test_zadd(acl::redis_zset& redis, int n) { acl::string key; std::map<acl::string, double> members; acl::string member; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); for (int j = 0; j < 1000; j++) { member.format("member_%d", j); members[member] = j; } redis.clear(); int ret = redis.zadd(key, members); if (ret < 0) { printf("add key: %s error\r\n", key.c_str()); return false; } else if (i < 10) printf("add ok, key: %s, ret: %d\r\n", key.c_str(), ret); members.clear(); } return true; }
static bool test_zscore(acl::redis_zset& redis, int n) { acl::string key; acl::string member; bool ret; double result; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); for (int j = 0; j < 1000; j++) { member.format("member_%d", j); redis.clear(); ret = redis.zscore(key.c_str(), member.c_str(), result); if (ret == false) { printf("zscore error, key: %s\r\n", key.c_str()); return false; } else if (j > 0 && j * i < 100) printf("zscore ok, key: %s, member:%s, " "score: %.2f\r\n", key.c_str(), member.c_str(), result); } } return true; }
static bool test_zrem(acl::redis_zset& redis, int n) { acl::string key; acl::string member; std::vector<acl::string> members; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); for (int j = 900; j < 1000; j++) { member.format("member_%d", j); members.push_back(member); } redis.clear(); int ret = redis.zrem(key.c_str(), members); if (ret < 0) { printf("zrem error, key: %s\r\n", key.c_str()); return false; } else if (i < 10) printf("zrem ok, key: %s, ret: %d\r\n", key.c_str(), ret); } return true; }
static bool test_zrank(acl::redis_zset& redis, int n) { acl::string key; acl::string member; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); for (int j = 0; j < 1000; j++) { member.format("member_%d", j); redis.clear(); int ret = redis.zrank(key.c_str(), member.c_str()); if (ret < 0) { printf("zrank error, key: %s\r\n", key.c_str()); return false; } else if (j > 0 && j * i < 100) printf("zrank ok, key: %s, member:%s, " "rank: %d\r\n", key.c_str(), member.c_str(), ret); } } return true; }
static bool test_zcard(acl::redis_zset& redis, int i, const char* key) { // 因为该协议数据比较小,所以在组装请求数据时不必采用分片方式 redis.get_client()->set_slice_request(false); int ret = redis.zcard(key); if (ret < 0) { printf("zcard key: %s error\r\n", key); return false; } else if (i < 10) printf("zcard ok, key: %s, count: %d\r\n", key, ret); return true; }
static bool test_zscan(acl::redis_zset& redis, int n) { acl::string key; int ret = 0; std::vector<std::pair<acl::string, double> > result; std::vector<std::pair<acl::string, double> >::const_iterator cit; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); while (true) { redis.clear(); ret = redis.zscan(key.c_str(), ret, result); if (ret < 0) { printf("zscan failed, key: %s\r\n", key.c_str()); return false; } if (i >= 10) { if (ret == 0) break; } for (cit = result.begin(); cit != result.end(); ++cit) { printf("%s: %.2f\r\n", cit->first.c_str(), cit->second); } if (ret == 0) { printf("zscan over, key: %s\r\n", key.c_str()); break; } } } return true; }
static bool test_zcard(acl::redis_zset& redis, int n) { acl::string key; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); redis.clear(); int ret = redis.zcard(key.c_str()); if (ret < 0) { printf("zcard key: %s error\r\n", key.c_str()); return false; } else if (i < 10) printf("zcard ok, key: %s, count: %d\r\n", key.c_str(), ret); } return true; }
static bool test_zlexcount(acl::redis_zset& redis, int n) { acl::string key; const char* min = "[aaa", *max = "(g"; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); redis.clear(); int ret = redis.zlexcount(key.c_str(), min, max); if (ret < 0) { printf("zlexcount error, key: %s\r\n", key.c_str()); return false; } if (i >= 10) continue; printf("key: %s, count: %d\r\n", key.c_str(), ret); } return true; }
static bool test_zrange(acl::redis_zset& redis, int i, const char* key, const char* hmac) { int start = 0, end = -1; // 请求的数据量比较小,所以在组装请求协议时不必采用分片方式 redis.get_client()->set_slice_request(false); // 对服务器返回的数据也不分片 redis.get_client()->set_slice_respond(false); int ret = redis.zrange(key, start, end, NULL); if (ret <= 0) { printf("zrange return: %d\r\n", ret); return false; } // 获得数组元素结果集 const acl::redis_result* result = redis.get_result(); if (result == NULL) { printf("result null\r\n"); return false; } size_t size; // 直接获得数组集合 const acl::redis_result** children = result->get_children(&size); if (children == NULL || size == 0) { printf("no children: %s, size: %d\r\n", children ? "no" : "yes", (int) size); return false; } // 校验获得的所有数据片的 MD5 值,与传入的进行比较 acl::md5* md5; if (hmac != NULL) md5 = new acl::md5; else md5 = NULL; const acl::redis_result* child; size_t len, argc, n; // 先遍历所有数组元素对象 for (size_t j = 0; j < size; j++) { child = children[j]; if (child == NULL) continue; // 因为前面设置了禁止对响应数据进行分片,所以只需取第一个元素 argc = child->get_size(); assert(argc == 1); const char* ptr = child->get(0, &len); if (ptr == NULL) { printf("first is null\r\n"); continue; } const char* dat = strchr(ptr, ':'); if (dat == NULL) { printf("invalid data, j: %d\n", (int) j); continue; } dat++; n = dat - ptr; if (len < n) { printf("invalid data, j: %d\n", (int) j); continue; } len -= n; // 取出数据计算 md5 值 if (md5 != NULL) md5->update(dat, len); } if (md5 != NULL) md5->finish(); // 获得字符串方式的 MD5 值 if (md5 != NULL) { const char* ptr = md5->get_string(); if (strcmp(ptr, hmac) != 0) { printf("md5 error, hmac: %s, %s, key: %s\r\n", hmac, ptr, key); return false; } else if (i < 10) printf("md5 ok, hmac: %s, %s, key: %s\r\n", hmac, ptr, key); delete md5; } else if (i < 10) printf("ok, key: %s\r\n", key); return true; }
static bool test_zadd(acl::redis_zset& redis, int i, const char* key, const char* big_data, size_t length, size_t base_length) { // 将大数据进行分割,计算出分割后的数据块个数 size_t nmember = length / base_length; if (length % base_length != 0) nmember++; // 从连接对象中获得统一的内存池分配对象,分配小内存块 acl::dbuf_pool* pool = redis.get_pool(); // 动态分配数据块指针数组内存 const char** members = (const char**) pool->dbuf_alloc(nmember * sizeof(char*)); // 动态分配数据块长度数组内存 size_t* lens = (size_t*) pool->dbuf_alloc(nmember * sizeof(size_t)); // 动态分配数据块分值数组内存 double* scores = (double*) pool->dbuf_alloc(nmember * sizeof(double)); // 将大数据切分成小数据,置入数据块数组中,使用递增的整数做为分值 size_t len; const char* ptr = big_data; char* buf, id[64]; int n; for (size_t j = 0; j < nmember; j++) { len = length > base_length ? base_length : length; // 在每个原始数据前面加唯一前缀,从而可以保证有序集合中对象中 // 的每个成员数据都是不同的 n = acl::safe_snprintf(id, sizeof(id), "%lu:", (unsigned long) j); buf = (char*) pool->dbuf_alloc(len + n); memcpy(buf, id, n); memcpy(buf + n, ptr, len); members[j] = buf; lens[j] = len + n; // 该数据块的总长度:唯一前缀+数据 scores[j] = (double) j; // 剩余数据块长度 length -= len; ptr += len; } // 要求 redis 连接对象采用内存链协议组装方式,避免内部组装请求协议时 // 再组装成大内存 redis.get_client()->set_slice_request(true); // 开始向 redis 添加数据 int ret = redis.zadd(key, members, lens, scores, nmember); if (ret < 0) { printf("add key: %s error\r\n", key); return false; } else if (i < 10) printf("add ok, key: %s, ret: %d\r\n", key, ret); return true; }
static bool test_zrangebyscore(acl::redis_zset& redis, int n) { acl::string key; double min = 2, max = 10; printf("================test zrangebyscore=====================\r\n"); std::vector<acl::string> result; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); redis.clear(); result.clear(); int ret = redis.zrangebyscore(key.c_str(), min, max, &result); if (ret < 0) { printf("zrangebyscore error, key: %s\r\n", key.c_str()); return false; } else if (i >= 10) { result.clear(); continue; } printf("zrangebyscore ok, key: %s, ret: %d\r\n", key.c_str(), ret); std::vector<acl::string>::const_iterator cit; for (cit = result.begin(); cit != result.end(); ++cit) { if (cit != result.begin()) printf(", "); printf("%s", (*cit).c_str()); } printf("\r\n"); result.clear(); } printf("===========test zrangebyscore_with_scores==============\r\n"); std::vector<std::pair<acl::string, double> > result2; for (int i = 0; i < n; i++) { key.format("%s_%d", __keypre.c_str(), i); redis.clear(); result.clear(); int ret = redis.zrangebyscore_with_scores(key.c_str(), min, max, result2); if (ret < 0) { printf("zrangebyscore_with_scores error, key: %s\r\n", key.c_str()); return false; } else if (i >= 10) { result2.clear(); continue; } printf("zrangebyscore_with_scores ok, key: %s, ret: %d\r\n", key.c_str(), ret); std::vector<std::pair<acl::string, double> >::const_iterator cit; for (cit = result2.begin(); cit != result2.end(); ++cit) { if (cit != result2.begin()) printf(", "); printf("%s: %.2f", cit->first.c_str(), cit->second); } printf("\r\n"); result2.clear(); } return true; }