예제 #1
0
RedisReply RedisCon::pipeliningSingle(const std::vector<std::string> command)
{
    std::vector<const char*> argv;
    argv.reserve(command.size());
    std::vector<size_t> argvlen;
    argvlen.reserve(command.size());

    for (std::vector<std::string>::const_iterator it = command.begin(); it != command.end(); ++it) {
        argv.push_back(it->c_str());
        argvlen.push_back(it->size());
    }

    int err = redisAppendCommandArgv(connect_.get(), static_cast<int>(command.size()), argv.data(), argvlen.data());
	if (err != REDIS_OK) {
    	throw redis_transport_except(connect_->errstr);
    }

	redisReply *r;
	err = redisGetReply(connect_.get(), reinterpret_cast<void**>(&r));
	RedisReply reply(r);
	if (err != REDIS_OK) {
    	throw redis_transport_except(connect_->errstr);
    }
    return std::move(reply);
}
예제 #2
0
static VALUE connection_write(VALUE self, VALUE command) {
    redisParentContext *pc;
    int argc;
    char **argv = NULL;
    size_t *alen = NULL;
    int i;

    /* Commands should be an array of commands, where each command
     * is an array of string arguments. */
    if (TYPE(command) != T_ARRAY)
        rb_raise(rb_eArgError,"%s","not an array");

    Data_Get_Struct(self,redisParentContext,pc);
    if (!pc->context)
        rb_raise(rb_eRuntimeError,"%s","not connected");

    argc = (int)RARRAY_LEN(command);
    argv = malloc(argc*sizeof(char*));
    alen = malloc(argc*sizeof(size_t));
    for (i = 0; i < argc; i++) {
        /* Replace arguments in the arguments array to prevent their string
         * equivalents to be garbage collected before this loop is done. */
        VALUE entry = rb_obj_as_string(rb_ary_entry(command, i));
        rb_ary_store(command, i, entry);
        argv[i] = RSTRING_PTR(entry);
        alen[i] = RSTRING_LEN(entry);
    }
    redisAppendCommandArgv(pc->context,argc,(const char**)argv,alen);
    free(argv);
    free(alen);
    return Qnil;
}
예제 #3
0
static int cliSendCommand(int argc, char **argv, int repeat) {
    char *command = argv[0];
    size_t *argvlen;
    int j, output_raw;

    if (context == NULL) {
        printf("Not connected, please use: connect <host> <port>\n");
        return REDIS_OK;
    }

    output_raw = !strcasecmp(command,"info");
    if (!strcasecmp(command,"help") || !strcasecmp(command,"?")) {
        cliOutputHelp(--argc, ++argv);
        return REDIS_OK;
    }
    if (!strcasecmp(command,"shutdown")) config.shutdown = 1;
    if (!strcasecmp(command,"monitor")) config.monitor_mode = 1;
    if (!strcasecmp(command,"subscribe") ||
        !strcasecmp(command,"psubscribe")) config.pubsub_mode = 1;

#ifdef ALCHEMY_DATABASE
    DXDB_cliSendCommand(&argc, argv);
#endif

    /* Setup argument length */
    argvlen = malloc(argc*sizeof(size_t));
    for (j = 0; j < argc; j++)
        argvlen[j] = sdslen(argv[j]);

    while(repeat--) {
        redisAppendCommandArgv(context,argc,(const char**)argv,argvlen);
        while (config.monitor_mode) {
            if (cliReadReply(output_raw) != REDIS_OK) exit(1);
            fflush(stdout);
        }

        if (config.pubsub_mode) {
            if (!config.raw_output)
                printf("Reading messages... (press Ctrl-C to quit)\n");
            while (1) {
                if (cliReadReply(output_raw) != REDIS_OK) exit(1);
            }
        }

        if (cliReadReply(output_raw) != REDIS_OK) {
            free(argvlen);
            return REDIS_ERR;
        } else {
            /* Store database number when SELECT was successfully executed. */
            if (!strcasecmp(command,"select") && argc == 2) {
                config.dbnum = atoi(argv[1]);
                cliRefreshPrompt();
            }
        }
    }

    free(argvlen);
    return REDIS_OK;
}
예제 #4
0
int db_redis_append_command_argv(km_redis_con_t *con, redis_key_t *query, int queue) {
    char **argv = NULL;
    int ret, argc;

    print_query(query);

    if (queue > 0 && db_redis_push_query(con, query) != 0) {
        LM_ERR("Failed to queue redis command\n");
        return -1;
    }

    argc = db_redis_key_list2arr(query, &argv);
    if (argc < 0) {
        LM_ERR("Failed to allocate memory for query array\n");
        return -1;
    }
    LM_DBG("query has %d args\n", argc);

    ret = redisAppendCommandArgv(con->con, argc, (const char**)argv, NULL);

    // this should actually never happen, because if all replies
    // are properly consumed for the previous command, it won't send
    // out a new query until redisGetReply is called
    if (con->con->err == REDIS_ERR_EOF) {
        if (db_redis_connect(con) != 0) {
            LM_ERR("Failed to reconnect to redis db\n");
            pkg_free(argv);
            if (con->con) {
                redisFree(con->con);
                con->con = NULL;
            }
            return ret;
        }
        ret = redisAppendCommandArgv(con->con, argc, (const char**)argv, NULL);
    }
    pkg_free(argv);
    if (!con->con->err) {
        con->append_counter++;
    }
    return ret;
}
예제 #5
0
static int lconn_append_command(lua_State * L)
{
  redisContext * pContext = check_connection(L, 1);

  const char * argv[LUAHIREDIS_MAXARGS];
  size_t argvlen[LUAHIREDIS_MAXARGS];
  int nargs = load_args(L, pContext, 2, argv, argvlen);

  redisAppendCommandArgv(pContext, nargs, argv, argvlen);

  return 0;
}
예제 #6
0
파일: redis-cli.c 프로젝트: jrun/redis
static int cliSendCommand(int argc, char **argv, int repeat) {
    char *command = argv[0];
    size_t *argvlen;
    int j, output_raw;

    if (context == NULL) {
        printf("Not connected, please use: connect <host> <port>\n");
        return REDIS_OK;
    }

    output_raw = !strcasecmp(command,"info");
    if (!strcasecmp(command,"help") || !strcasecmp(command,"?")) {
        cliOutputHelp(--argc, ++argv);
        return REDIS_OK;
    }
    if (!strcasecmp(command,"shutdown")) config.shutdown = 1;
    if (!strcasecmp(command,"monitor")) config.monitor_mode = 1;
    if (!strcasecmp(command,"subscribe") ||
        !strcasecmp(command,"psubscribe")) config.pubsub_mode = 1;

    /* Setup argument length */
    argvlen = malloc(argc*sizeof(size_t));
    for (j = 0; j < argc; j++)
        argvlen[j] = sdslen(argv[j]);

    while(repeat--) {
        redisAppendCommandArgv(context,argc,(const char**)argv,argvlen);
        while (config.monitor_mode) {
            if (cliReadReply(output_raw) != REDIS_OK) exit(1);
            fflush(stdout);
        }

        if (config.pubsub_mode) {
            if (!config.raw_output)
                printf("Reading messages... (press Ctrl-C to quit)\n");
            while (1) {
                if (cliReadReply(output_raw) != REDIS_OK) exit(1);
            }
        }

        if (cliReadReply(output_raw) != REDIS_OK)
            return REDIS_ERR;
    }
    return REDIS_OK;
}
예제 #7
0
파일: hiredis.c 프로젝트: esromneb/hiredis
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen) {
    if (redisAppendCommandArgv(c,argc,argv,argvlen) != REDIS_OK)
        return NULL;
    return __redisBlockForReply(c);
}
예제 #8
0
/** Change the state of a connection to READONLY execute a command and switch to READWRITE
 *
 * @param[out] status_out Where to write the status from the command.
 * @param[out] reply_out Where to write the reply associated with the highest priority status.
 * @param[in] request The current request.
 * @param[in] conn to issue commands with.
 * @param[in] argc Redis command argument count.
 * @param[in] argv Redis command arguments.
 * @return
 *	- 0 success.
 *	- -1 normal failure.
 *	- -2 failure that may leave the connection in a READONLY state.
 */
static int redis_command_read_only(fr_redis_rcode_t *status_out, redisReply **reply_out,
				   REQUEST *request, fr_redis_conn_t *conn, int argc, char const **argv)
{
	bool			maybe_more = false;
	redisReply		*reply;
	fr_redis_rcode_t	status;

	*reply_out = NULL;

	redisAppendCommand(conn->handle, "READONLY");
	redisAppendCommandArgv(conn->handle, argc, argv, NULL);
	redisAppendCommand(conn->handle, "READWRITE");

	/*
	 *	Process the response for READONLY
	 */
	reply = NULL;	/* Doesn't set reply to NULL on error *sigh* */
	if (redisGetReply(conn->handle, (void **)&reply) == REDIS_OK) maybe_more = true;
	status = fr_redis_command_status(conn, reply);
	if (status != REDIS_RCODE_SUCCESS) {
		REDEBUG("Setting READONLY failed");

		*reply_out = reply;
		*status_out = status;

		if (maybe_more) {
			if (redisGetReply(conn->handle, (void **)&reply) != REDIS_OK) return -1;
			fr_redis_reply_free(reply);
			if (redisGetReply(conn->handle, (void **)&reply) != REDIS_OK) return -1;
			fr_redis_reply_free(reply);
		}
		return -1;
	}

	fr_redis_reply_free(reply);

	/*
	 *	Process the response for the command
	 */
	reply = NULL;
	if (redisGetReply(conn->handle, (void **)&reply) == REDIS_OK) maybe_more = true;
	status = fr_redis_command_status(conn, reply);
	if (status != REDIS_RCODE_SUCCESS) {
		*reply_out = reply;
		*status_out = status;

		if (maybe_more) {
			if (redisGetReply(conn->handle, (void **)&reply) != REDIS_OK) return -1;
			fr_redis_reply_free(reply);
		}
		return -1;
	}

	*reply_out = reply;
	*status_out = status;

	/*
	 *	Process the response for READWRITE
	 */
	reply = NULL;
	status = fr_redis_command_status(conn, reply);
	if ((redisGetReply(conn->handle, (void **)&reply) != REDIS_OK) || (status != REDIS_RCODE_SUCCESS)) {
		REDEBUG("Setting READWRITE failed");

		fr_redis_reply_free(*reply_out);
		*reply_out = reply;
		*status_out = status;

		return -2;
	}
	return 0;
}
/** Insert a new entry into the data store
 *
 * @copydetails cache_entry_insert_t
 */
static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config, void *driver_inst,
					 REQUEST *request, UNUSED void *handle, const rlm_cache_entry_t *c)
{
	rlm_cache_redis_t	*driver = driver_inst;
	TALLOC_CTX		*pool;

	vp_map_t		*map;

	fr_redis_conn_t		*conn;
	fr_redis_cluster_state_t	state;
	fr_redis_rcode_t	status;
	redisReply		*reply = NULL;
	int			s_ret;

	static char const	command[] = "RPUSH";
	char const		**argv;
	size_t			*argv_len;
	char const		**argv_p;
	size_t			*argv_len_p;

	int			pipelined = 0;	/* How many commands pending in the pipeline */
	redisReply		*replies[5];	/* Should have the same number of elements as pipelined commands */
	size_t			reply_num = 0, i;

	char			*p;
	int			cnt;

	vp_tmpl_t		expires_value;
	vp_map_t		expires = {
					.op	= T_OP_SET,
					.lhs	= &driver->expires_attr,
					.rhs	= &expires_value,
				};

	vp_tmpl_t		created_value;
	vp_map_t		created = {
					.op	= T_OP_SET,
					.lhs	= &driver->created_attr,
					.rhs	= &created_value,
					.next	= &expires
				};

	/*
	 *	Encode the entry created date
	 */
	tmpl_init(&created_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD);
	created_value.tmpl_data_type = PW_TYPE_DATE;
	created_value.tmpl_data_length = sizeof(created_value.tmpl_data_value.date);
	created_value.tmpl_data_value.date = c->created;

	/*
	 *	Encode the entry expiry time
	 *
	 *	Although Redis objects expire on their own, we still need this
	 *	to ignore entries that were created before the last epoch.
	 */
	tmpl_init(&expires_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD);
	expires_value.tmpl_data_type = PW_TYPE_DATE;
	expires_value.tmpl_data_length = sizeof(expires_value.tmpl_data_value.date);
	expires_value.tmpl_data_value.date = c->expires;
	expires.next = c->maps;	/* Head of the list */

	for (cnt = 0, map = &created; map; cnt++, map = map->next);

	/*
	 *	The majority of serialized entries should be under 1k.
	 *
	 * @todo We should really calculate this using some sort of moving average.
	 */
	pool = talloc_pool(request, 1024);
	if (!pool) return CACHE_ERROR;

	argv_p = argv = talloc_array(pool, char const *, (cnt * 3) + 2);	/* pair = 3 + cmd + key */
	argv_len_p = argv_len = talloc_array(pool, size_t, (cnt * 3) + 2);	/* pair = 3 + cmd + key */

	*argv_p++ = command;
	*argv_len_p++ = sizeof(command) - 1;

	*argv_p++ = (char const *)c->key;
	*argv_len_p++ = c->key_len;

	/*
	 *	Add the maps to the command string in reverse order
	 */
	for (map = &created; map; map = map->next) {
		if (fr_redis_tuple_from_map(pool, argv_p, argv_len_p, map) < 0) {
			REDEBUG("Failed encoding map as Redis K/V pair");
			talloc_free(pool);
			return CACHE_ERROR;
		}
		argv_p += 3;
		argv_len_p += 3;
	}

	RDEBUG3("Pipelining commands");
	RINDENT();

	for (s_ret = fr_redis_cluster_state_init(&state, &conn, driver->cluster, request, c->key, c->key_len, false);
	     s_ret == REDIS_RCODE_TRY_AGAIN;	/* Continue */
	     s_ret = fr_redis_cluster_state_next(&state, &conn, driver->cluster, request, status, &reply)) {
		/*
		 *	Start the transaction, as we need to set an expiry time too.
		 */
		if (c->expires > 0) {
			RDEBUG3("MULTI");
			if (redisAppendCommand(conn->handle, "MULTI") != REDIS_OK) {
			append_error:
				REXDENT();
				RERROR("Failed appending Redis command to output buffer: %s", conn->handle->errstr);
				talloc_free(pool);
				return CACHE_ERROR;
			}
			pipelined++;
		}

		if (RDEBUG_ENABLED3) {
			p = fr_asprint(request, (char const *)c->key, c->key_len, '\0');
			RDEBUG3("DEL \"%s\"", p);
			talloc_free(p);

		}

		if (redisAppendCommand(conn->handle, "DEL %b", c->key, c->key_len) != REDIS_OK) goto append_error;
		pipelined++;

		if (RDEBUG_ENABLED3) {
			RDEBUG3("argv command");
			RINDENT();
			for (i = 0; i < talloc_array_length(argv); i++) {
				p = fr_asprint(request, argv[i], argv_len[i], '\0');
				RDEBUG3("%s", p);
				talloc_free(p);
			}
			REXDENT();
		}
		redisAppendCommandArgv(conn->handle, talloc_array_length(argv), argv, argv_len);
		pipelined++;

		/*
		 *	Set the expiry time and close out the transaction.
		 */
		if (c->expires > 0) {
			if (RDEBUG_ENABLED3) {
				p = fr_asprint(request, (char const *)c->key, c->key_len, '\"');
				RDEBUG3("EXPIREAT \"%s\" %li", p, (long)c->expires);
				talloc_free(p);
			}
			if (redisAppendCommand(conn->handle, "EXPIREAT %b %i", c->key,
					       c->key_len, c->expires) != REDIS_OK) goto append_error;
			pipelined++;
			RDEBUG3("EXEC");
			if (redisAppendCommand(conn->handle, "EXEC") != REDIS_OK) goto append_error;
			pipelined++;
		}
		REXDENT();

		reply_num = fr_redis_pipeline_result(&status, replies, sizeof(replies) / sizeof(*replies),
						     conn, pipelined);
		reply = replies[0];
	}
	talloc_free(pool);

	if (s_ret != REDIS_RCODE_SUCCESS) {
		RERROR("Failed inserting entry");
		return CACHE_ERROR;
	}

	RDEBUG3("Command results");
	RINDENT();
	for (i = 0; i < reply_num; i++) {
		fr_redis_reply_print(L_DBG_LVL_3, replies[i], request, i);
		fr_redis_reply_free(replies[i]);
	}
	REXDENT();

	return CACHE_OK;
}

/** Call delete the cache entry from redis
 *
 * @copydetails cache_entry_expire_t
 */
static cache_status_t cache_entry_expire(UNUSED rlm_cache_config_t const *config, void *driver_inst,
					 REQUEST *request, UNUSED void *handle,  uint8_t const *key, size_t key_len)
{
	rlm_cache_redis_t		*driver = driver_inst;
	fr_redis_cluster_state_t	state;
	fr_redis_conn_t			*conn;
	fr_redis_rcode_t			status;
	redisReply			*reply = NULL;
	int				s_ret;

	for (s_ret = fr_redis_cluster_state_init(&state, &conn, driver->cluster, request, key, key_len, false);
	     s_ret == REDIS_RCODE_TRY_AGAIN;	/* Continue */
	     s_ret = fr_redis_cluster_state_next(&state, &conn, driver->cluster, request, status, &reply)) {
	     	reply = redisCommand(conn->handle, "DEL %b", key, key_len);
	     	status = fr_redis_command_status(conn, reply);
	}
	if (s_ret != REDIS_RCODE_SUCCESS) {
		RERROR("Failed expiring entry");
		fr_redis_reply_free(reply);
		return CACHE_ERROR;
	}

	rad_assert(reply);	/* clang scan */
	if (reply->type == REDIS_REPLY_INTEGER) {
		fr_redis_reply_free(reply);
		if (reply->integer) return CACHE_OK;	/* Affected */
		return CACHE_MISS;
	}

	REDEBUG("Bad result type, expected integer, got %s",
		fr_int2str(redis_reply_types, reply->type, "<UNKNOWN>"));
	fr_redis_reply_free(reply);

	return CACHE_ERROR;
}

extern cache_driver_t rlm_cache_redis;
cache_driver_t rlm_cache_redis = {
	.name		= "rlm_cache_redis",
	.instantiate	= mod_instantiate,
	.inst_size	= sizeof(rlm_cache_redis_t),
	.free		= cache_entry_free,

	.find		= cache_entry_find,
	.insert		= cache_entry_insert,
	.expire		= cache_entry_expire,
};
예제 #10
0
static int cliSendCommand(int argc, char **argv, int repeat) {
    char *command = argv[0];
    size_t *argvlen;
    int j, output_raw;

    if (!strcasecmp(command,"help") || !strcasecmp(command,"?")) {
        cliOutputHelp(--argc, ++argv);
        return REDIS_OK;
    }

    if (context == NULL) return REDIS_ERR;

    output_raw = 0;
    if (!strcasecmp(command,"info") ||
        (argc == 2 && !strcasecmp(command,"cluster") &&
                      (!strcasecmp(argv[1],"nodes") ||
                       !strcasecmp(argv[1],"info"))) ||
        (argc == 2 && !strcasecmp(command,"client") &&
                       !strcasecmp(argv[1],"list")))

    {
        output_raw = 1;
    }

    if (!strcasecmp(command,"shutdown")) config.shutdown = 1;
    if (!strcasecmp(command,"monitor")) config.monitor_mode = 1;
    if (!strcasecmp(command,"subscribe") ||
        !strcasecmp(command,"psubscribe")) config.pubsub_mode = 1;

    /* Setup argument length */
    argvlen = malloc(argc*sizeof(size_t));
    for (j = 0; j < argc; j++)
        argvlen[j] = sdslen(argv[j]);

    while(repeat--) {
        redisAppendCommandArgv(context,argc,(const char**)argv,argvlen);
        while (config.monitor_mode) {
            if (cliReadReply(output_raw) != REDIS_OK) exit(1);
            fflush(stdout);
        }

        if (config.pubsub_mode) {
            if (config.output != OUTPUT_RAW)
                printf("Reading messages... (press Ctrl-C to quit)\n");
            while (1) {
                if (cliReadReply(output_raw) != REDIS_OK) exit(1);
            }
        }

        if (cliReadReply(output_raw) != REDIS_OK) {
            free(argvlen);
            return REDIS_ERR;
        } else {
            /* Store database number when SELECT was successfully executed. */
            if (!strcasecmp(command,"select") && argc == 2) {
                config.dbnum = atoi(argv[1]);
                cliRefreshPrompt();
            }
        }
        if (config.interval) usleep(config.interval);
        fflush(stdout); /* Make it grep friendly */
    }

    free(argvlen);
    return REDIS_OK;
}
예제 #11
0
파일: redis-fast.c 프로젝트: hotfics/misc
int main(int argc, char *argv[]) {
  int rc=-1, i, opt, n=10000;
  void *reply;

  while ( (opt = getopt(argc, argv, "v+n:s:p:")) != -1) {
    switch (opt) {
      case 'v': verbose++; break;
      case 'n': n=atoi(optarg); break;
      case 's': redis_host=strdup(optarg); break;
      case 'p': redis_port=atoi(optarg); break;
      default: usage(argv[0]); break;
    }
  }

  /* connect to redis */
  redisContext *c = redisConnect(redis_host,redis_port);
  if (c && c->err) {
    fprintf(stderr,"redisConnect: %s\n", c->errstr);
    goto done;
  }

  struct timeval tv_a, tv_b;

  char big_str[100];
  for(i=0; i < sizeof(big_str); i++) big_str[i] = 'a'+(i%10);
  big_str[sizeof(big_str)-1] = '\0';

  /*************************************************************
   * big string push
   ************************************************************/
  gettimeofday(&tv_a,NULL);
  for(i=0; i < n; i++) {
    reply = redisCommand(c, "LPUSH list %s", big_str);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
  }
  gettimeofday(&tv_b,NULL);
  print_result(n,"big string push", tv_a, tv_b);

  reply = redisCommand(c, "DEL list");
  if (reply) freeReplyObject(reply);
  else fprintf(stderr,"redisCommand: %s\n", c->errstr);

  /*************************************************************
   * big string push/trim 
   ************************************************************/
  gettimeofday(&tv_a,NULL);
  for(i=0; i < n; i++) {
    reply = redisCommand(c, "LPUSH list %s", big_str);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
    reply = redisCommand(c, "LTRIM list 0 %u", n/2);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
  }
  gettimeofday(&tv_b,NULL);
  print_result(n,"big string push/trim", tv_a, tv_b);

  reply = redisCommand(c, "DEL list");
  if (reply) freeReplyObject(reply);
  else fprintf(stderr,"redisCommand: %s\n", c->errstr);

  /*************************************************************
   * pipelined big string push/trim 
   ************************************************************/
  gettimeofday(&tv_a,NULL);
  for(i=0; i < n; i++) {
    redisAppendCommand(c, "LPUSH list %s", big_str);
    redisAppendCommand(c, "LTRIM list 0 %u", n/2);
    redisGetReply(c, &reply);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
    redisGetReply(c, &reply);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
  }
  gettimeofday(&tv_b,NULL);
  print_result(n,"pipelined big string push/trim", tv_a, tv_b);

  reply = redisCommand(c, "DEL list");
  if (reply) freeReplyObject(reply);
  else fprintf(stderr,"redisCommand: %s\n", c->errstr);

  /*************************************************************
   * pipelined big string push/trim with precomputed arg len
   ************************************************************/
  char half_n[10];
  sprintf(half_n, "%u", n/2);
  size_t half_n_len = strlen(half_n);
  gettimeofday(&tv_a,NULL);
  for(i=0; i < n; i++) {
    const char *cmds[] = { "LPUSH", "list", big_str };
    size_t len[] = { 5, 4, sizeof(big_str) };
    redisAppendCommandArgv(c, 3, cmds, len);

    const char *cmds2[] = { "LTRIM", "list", "0", half_n};
    size_t len2[] = { 5, 4, 1, half_n_len };
    redisAppendCommandArgv(c, 4, cmds2, len2);

    redisGetReply(c, &reply);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
    redisGetReply(c, &reply);
    if (reply) freeReplyObject(reply);
    else fprintf(stderr,"redisCommand: %s\n", c->errstr);
  }
  gettimeofday(&tv_b,NULL);
  print_result(n,"pipelined big string push/trim precomputed arg len", tv_a, tv_b);

  /*
  reply = redisCommand(c, "DEL list");
  if (reply) freeReplyObject(reply);
  else fprintf(stderr,"redisCommand: %s\n", c->errstr);
  */




 done:
  return rc;
}
예제 #12
0
파일: rdd.c 프로젝트: Redsmin/rdd
u32 rddRedisInsert(redisContext*rd,char*rdd)
{   rddRedisDelete(rd,rdd);
    const char * const redisSetCmd[5] = { "SET", "RPUSH", "SADD", "ZADD", "HMSET" };
    u32 nb=0;
    char **keys = rddGetAllKeys(rdd,&nb);

    for(u32 c=0; c<nb; c++)
    {   struct keynfo k;
        keyGetNfo(keys[c],&k);

        int argnb = (*k.nb) + 2;

        const char ** cargv = (const char**) malloc( argnb*(sizeof(char*)) );
        size_t *cargl = (size_t*)malloc( argnb*(sizeof(size_t*)) );

        cargv[0] = redisSetCmd[*k.type];
        cargl[0] = strlen(cargv[0]);

        cargv[1] = (const char *)k.name;
        cargl[1] = strlen(cargv[1]);

        if(*k.type == 3)	// zset, need invert args...
        {   for(u32 n=0; n<(*(k.nb)); n+=2)
            {   cargv[n+2] = (const char *)(k.data[n+1]); // score
                cargl[n+2] = k.sizes[n+1];
                cargv[n+3] = (const char *)(k.data[n]); // data
                cargl[n+3] = k.sizes[n];
            }
        } else {

            for(u32 n=0; n<(*(k.nb)); n++)
            {   cargv[n+2] = (const char *)(k.data[n]);
                cargl[n+2] = k.sizes[n];
            }
        }

        redisAppendCommandArgv(rd, argnb, cargv, cargl);

        free(k.data);
        free(cargv);
        free(cargl);
    }

    for(u32 c=0; c<nb; c++)
    {   struct keynfo k;
        keyGetNfo(keys[c],&k);
        time_t now = time(NULL);
        if(*k.ttl != 0)
        {   u32 ttl = *k.ttl - now;
            redisCommand(rd,"EXPIRE %s %u",k.name,ttl);
        }
        free(k.data);
    }

    free(keys);

    redisReply * reply;
    for(u32 c=0; c<nb; c++)
    {   redisGetReply(rd,(void**)&reply);
        freeReplyObject(reply);
    }
    return 1;
}