#ifndef REDIS_CLUSTER_H #define REDIS_CLUSTER_H #include "cluster_library.h" #include #include /* Get attached object context */ #define GET_CONTEXT() PHPREDIS_ZVAL_GET_OBJECT(redisCluster, getThis()) /* Command building/processing is identical for every command */ #define CLUSTER_BUILD_CMD(name, c, cmd, cmd_len, slot) \ redis_##name##_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, c->flags, &cmd, \ &cmd_len, &slot) /* Append information required to handle MULTI commands to the tail of our MULTI * linked list. */ #define CLUSTER_ENQUEUE_RESPONSE(c, slot, cb, ctx) \ clusterFoldItem *_item; \ _item = emalloc(sizeof(clusterFoldItem)); \ _item->callback = cb; \ _item->slot = slot; \ _item->ctx = ctx; \ _item->next = NULL; \ if(c->multi_head == NULL) { \ c->multi_head = _item; \ c->multi_curr = _item; \ } else { \ c->multi_curr->next = _item; \ c->multi_curr = _item; \ } \ /* Simple macro to free our enqueued callbacks after we EXEC */ #define CLUSTER_FREE_QUEUE(c) \ clusterFoldItem *_item = c->multi_head, *_tmp; \ while(_item) { \ _tmp = _item->next; \ efree(_item); \ _item = _tmp; \ } \ c->multi_head = c->multi_curr = NULL; \ /* Reset anything flagged as MULTI */ #define CLUSTER_RESET_MULTI(c) \ redisClusterNode *_node; \ ZEND_HASH_FOREACH_PTR(c->nodes, _node) { \ if (_node == NULL) break; \ _node->sock->watching = 0; \ _node->sock->mode = ATOMIC; \ } ZEND_HASH_FOREACH_END(); \ c->flags->watching = 0; \ c->flags->mode = ATOMIC; \ /* Simple 1-1 command -> response macro */ #define CLUSTER_PROCESS_CMD(cmdname, resp_func, readcmd) \ redisCluster *c = GET_CONTEXT(); \ c->readonly = CLUSTER_IS_ATOMIC(c) && readcmd; \ char *cmd; int cmd_len; short slot; void *ctx=NULL; \ if(redis_##cmdname##_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,c->flags, &cmd, \ &cmd_len, &slot, &ctx)==FAILURE) { \ RETURN_FALSE; \ } \ if(cluster_send_command(c,slot,cmd,cmd_len)<0 || c->err!=NULL) {\ efree(cmd); \ RETURN_FALSE; \ } \ efree(cmd); \ if(c->flags->mode == MULTI) { \ CLUSTER_ENQUEUE_RESPONSE(c, slot, resp_func, ctx); \ RETURN_ZVAL(getThis(), 1, 0); \ } \ resp_func(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, ctx); /* More generic processing, where only the keyword differs */ #define CLUSTER_PROCESS_KW_CMD(kw, cmdfunc, resp_func, readcmd) \ redisCluster *c = GET_CONTEXT(); \ c->readonly = CLUSTER_IS_ATOMIC(c) && readcmd; \ char *cmd; int cmd_len; short slot; void *ctx=NULL; \ if(cmdfunc(INTERNAL_FUNCTION_PARAM_PASSTHRU, c->flags, kw, &cmd, &cmd_len,\ &slot,&ctx)==FAILURE) { \ RETURN_FALSE; \ } \ if(cluster_send_command(c,slot,cmd,cmd_len)<0 || c->err!=NULL) { \ efree(cmd); \ RETURN_FALSE; \ } \ efree(cmd); \ if(c->flags->mode == MULTI) { \ CLUSTER_ENQUEUE_RESPONSE(c, slot, resp_func, ctx); \ RETURN_ZVAL(getThis(), 1, 0); \ } \ resp_func(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, ctx); /* Create cluster context */ zend_object *create_cluster_context(zend_class_entry *class_type); /* Free cluster context struct */ void free_cluster_context(zend_object *object); /* RedisCluster method implementation */ PHP_METHOD(RedisCluster, __construct); PHP_METHOD(RedisCluster, acl); PHP_METHOD(RedisCluster, close); PHP_METHOD(RedisCluster, get); PHP_METHOD(RedisCluster, set); PHP_METHOD(RedisCluster, mget); PHP_METHOD(RedisCluster, mset); PHP_METHOD(RedisCluster, msetnx); PHP_METHOD(RedisCluster, mset); PHP_METHOD(RedisCluster, del); PHP_METHOD(RedisCluster, unlink); PHP_METHOD(RedisCluster, dump); PHP_METHOD(RedisCluster, setex); PHP_METHOD(RedisCluster, psetex); PHP_METHOD(RedisCluster, setnx); PHP_METHOD(RedisCluster, getset); PHP_METHOD(RedisCluster, exists); PHP_METHOD(RedisCluster, keys); PHP_METHOD(RedisCluster, type); PHP_METHOD(RedisCluster, persist); PHP_METHOD(RedisCluster, lpop); PHP_METHOD(RedisCluster, rpop); PHP_METHOD(RedisCluster, spop); PHP_METHOD(RedisCluster, rpush); PHP_METHOD(RedisCluster, lpush); PHP_METHOD(RedisCluster, blpop); PHP_METHOD(RedisCluster, brpop); PHP_METHOD(RedisCluster, rpushx); PHP_METHOD(RedisCluster, lpushx); PHP_METHOD(RedisCluster, linsert); PHP_METHOD(RedisCluster, lindex); PHP_METHOD(RedisCluster, lrem); PHP_METHOD(RedisCluster, brpoplpush); PHP_METHOD(RedisCluster, rpoplpush); PHP_METHOD(RedisCluster, llen); PHP_METHOD(RedisCluster, scard); PHP_METHOD(RedisCluster, smembers); PHP_METHOD(RedisCluster, sismember); PHP_METHOD(RedisCluster, sadd); PHP_METHOD(RedisCluster, saddarray); PHP_METHOD(RedisCluster, srem); PHP_METHOD(RedisCluster, sunion); PHP_METHOD(RedisCluster, sunionstore); PHP_METHOD(RedisCluster, sinter); PHP_METHOD(RedisCluster, sinterstore); PHP_METHOD(RedisCluster, sdiff); PHP_METHOD(RedisCluster, sdiffstore); PHP_METHOD(RedisCluster, strlen); PHP_METHOD(RedisCluster, ttl); PHP_METHOD(RedisCluster, pttl); PHP_METHOD(RedisCluster, zcard); PHP_METHOD(RedisCluster, zscore); PHP_METHOD(RedisCluster, zcount); PHP_METHOD(RedisCluster, zrem); PHP_METHOD(RedisCluster, zremrangebyscore); PHP_METHOD(RedisCluster, zrank); PHP_METHOD(RedisCluster, zrevrank); PHP_METHOD(RedisCluster, zadd); PHP_METHOD(RedisCluster, zincrby); PHP_METHOD(RedisCluster, hlen); PHP_METHOD(RedisCluster, hget); PHP_METHOD(RedisCluster, hkeys); PHP_METHOD(RedisCluster, hvals); PHP_METHOD(RedisCluster, hmget); PHP_METHOD(RedisCluster, hmset); PHP_METHOD(RedisCluster, hdel); PHP_METHOD(RedisCluster, hgetall); PHP_METHOD(RedisCluster, hexists); PHP_METHOD(RedisCluster, hincrby); PHP_METHOD(RedisCluster, hincrbyfloat); PHP_METHOD(RedisCluster, hset); PHP_METHOD(RedisCluster, hsetnx); PHP_METHOD(RedisCluster, hstrlen); PHP_METHOD(RedisCluster, incr); PHP_METHOD(RedisCluster, decr); PHP_METHOD(RedisCluster, incrby); PHP_METHOD(RedisCluster, decrby); PHP_METHOD(RedisCluster, incrbyfloat); PHP_METHOD(RedisCluster, expire); PHP_METHOD(RedisCluster, expireat); PHP_METHOD(RedisCluster, pexpire); PHP_METHOD(RedisCluster, pexpireat); PHP_METHOD(RedisCluster, append); PHP_METHOD(RedisCluster, getbit); PHP_METHOD(RedisCluster, setbit); PHP_METHOD(RedisCluster, bitop); PHP_METHOD(RedisCluster, bitpos); PHP_METHOD(RedisCluster, bitcount); PHP_METHOD(RedisCluster, lget); PHP_METHOD(RedisCluster, getrange); PHP_METHOD(RedisCluster, ltrim); PHP_METHOD(RedisCluster, lrange); PHP_METHOD(RedisCluster, zremrangebyrank); PHP_METHOD(RedisCluster, publish); PHP_METHOD(RedisCluster, lset); PHP_METHOD(RedisCluster, rename); PHP_METHOD(RedisCluster, renamenx); PHP_METHOD(RedisCluster, pfcount); PHP_METHOD(RedisCluster, pfadd); PHP_METHOD(RedisCluster, pfmerge); PHP_METHOD(RedisCluster, restore); PHP_METHOD(RedisCluster, setrange); PHP_METHOD(RedisCluster, smove); PHP_METHOD(RedisCluster, srandmember); PHP_METHOD(RedisCluster, zpopmin); PHP_METHOD(RedisCluster, zpopmax); PHP_METHOD(RedisCluster, bzpopmax); PHP_METHOD(RedisCluster, bzpopmin); PHP_METHOD(RedisCluster, zrange); PHP_METHOD(RedisCluster, zrevrange); PHP_METHOD(RedisCluster, zrangebyscore); PHP_METHOD(RedisCluster, zrevrangebyscore); PHP_METHOD(RedisCluster, zrangebylex); PHP_METHOD(RedisCluster, zrevrangebylex); PHP_METHOD(RedisCluster, zlexcount); PHP_METHOD(RedisCluster, zremrangebylex); PHP_METHOD(RedisCluster, zunionstore); PHP_METHOD(RedisCluster, zinterstore); PHP_METHOD(RedisCluster, sort); PHP_METHOD(RedisCluster, object); PHP_METHOD(RedisCluster, subscribe); PHP_METHOD(RedisCluster, psubscribe); PHP_METHOD(RedisCluster, unsubscribe); PHP_METHOD(RedisCluster, punsubscribe); PHP_METHOD(RedisCluster, eval); PHP_METHOD(RedisCluster, evalsha); PHP_METHOD(RedisCluster, info); PHP_METHOD(RedisCluster, cluster); PHP_METHOD(RedisCluster, client); PHP_METHOD(RedisCluster, config); PHP_METHOD(RedisCluster, pubsub); PHP_METHOD(RedisCluster, script); PHP_METHOD(RedisCluster, slowlog); PHP_METHOD(RedisCluster, command); PHP_METHOD(RedisCluster, geoadd); PHP_METHOD(RedisCluster, geohash); PHP_METHOD(RedisCluster, geopos); PHP_METHOD(RedisCluster, geodist); PHP_METHOD(RedisCluster, georadius); PHP_METHOD(RedisCluster, georadius_ro); PHP_METHOD(RedisCluster, georadiusbymember); PHP_METHOD(RedisCluster, georadiusbymember_ro); /* SCAN and friends */ PHP_METHOD(RedisCluster, scan); PHP_METHOD(RedisCluster, zscan); PHP_METHOD(RedisCluster, hscan); PHP_METHOD(RedisCluster, sscan); /* STREAMS */ PHP_METHOD(RedisCluster, xack); PHP_METHOD(RedisCluster, xadd); PHP_METHOD(RedisCluster, xclaim); PHP_METHOD(RedisCluster, xdel); PHP_METHOD(RedisCluster, xgroup); PHP_METHOD(RedisCluster, xinfo); PHP_METHOD(RedisCluster, xlen); PHP_METHOD(RedisCluster, xpending); PHP_METHOD(RedisCluster, xrange); PHP_METHOD(RedisCluster, xread); PHP_METHOD(RedisCluster, xreadgroup); PHP_METHOD(RedisCluster, xrevrange); PHP_METHOD(RedisCluster, xtrim); /* Transactions */ PHP_METHOD(RedisCluster, multi); PHP_METHOD(RedisCluster, exec); PHP_METHOD(RedisCluster, discard); PHP_METHOD(RedisCluster, watch); PHP_METHOD(RedisCluster, unwatch); /* Commands we direct to a node */ PHP_METHOD(RedisCluster, save); PHP_METHOD(RedisCluster, bgsave); PHP_METHOD(RedisCluster, flushdb); PHP_METHOD(RedisCluster, flushall); PHP_METHOD(RedisCluster, dbsize); PHP_METHOD(RedisCluster, bgrewriteaof); PHP_METHOD(RedisCluster, lastsave); PHP_METHOD(RedisCluster, role); PHP_METHOD(RedisCluster, time); PHP_METHOD(RedisCluster, randomkey); PHP_METHOD(RedisCluster, ping); PHP_METHOD(RedisCluster, echo); PHP_METHOD(RedisCluster, rawcommand); /* Introspection */ PHP_METHOD(RedisCluster, getmode); PHP_METHOD(RedisCluster, getlasterror); PHP_METHOD(RedisCluster, clearlasterror); PHP_METHOD(RedisCluster, getoption); PHP_METHOD(RedisCluster, setoption); PHP_METHOD(RedisCluster, _prefix); PHP_METHOD(RedisCluster, _serialize); PHP_METHOD(RedisCluster, _unserialize); PHP_METHOD(RedisCluster, _masters); PHP_METHOD(RedisCluster, _redir); #endif