Skip to content

Commit

Permalink
ZEND_HASH_FOREACH_PTR
Browse files Browse the repository at this point in the history
  • Loading branch information
yatsukhnenko committed Aug 15, 2017
1 parent e672f40 commit 658ee37
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 61 deletions.
57 changes: 19 additions & 38 deletions cluster_library.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ extern zend_class_entry *redis_cluster_exception_ce;
static void cluster_dump_nodes(redisCluster *c) {
redisClusterNode *p;
for(zend_hash_internal_pointer_reset(c->nodes);
zend_hash_has_more_elements(c->nodes)==SUCCESS;
zend_hash_move_forward(c->nodes))
{
if ((p = zend_hash_get_current_data_ptr(c->nodes)) == NULL) {
ZEND_HASH_FOREACH_PTR(c->nodes, p) {
if (p == NULL) {
continue;
}
Expand All @@ -25,7 +22,7 @@ static void cluster_dump_nodes(redisCluster *c) {
p->slot);
php_printf("\n");
}
} ZEND_HASH_FOREACH_END();
}
static void cluster_log(char *fmt, ...)
Expand Down Expand Up @@ -939,30 +936,24 @@ PHP_REDIS_API int cluster_map_keyspace(redisCluster *c TSRMLS_DC) {
int mapped=0;

// Iterate over seeds until we can get slots
for(zend_hash_internal_pointer_reset(c->seeds);
!mapped && zend_hash_has_more_elements(c->seeds) == SUCCESS;
zend_hash_move_forward(c->seeds))
{
// Grab the redis_sock for this seed
if ((seed = zend_hash_get_current_data_ptr(c->seeds)) == NULL) {
continue;
}

ZEND_HASH_FOREACH_PTR(c->seeds, seed) {
// Attempt to connect to this seed node
if (redis_sock_connect(seed TSRMLS_CC) != 0) {
if (seed == NULL || redis_sock_connect(seed TSRMLS_CC) != 0) {
continue;
}

// Parse out cluster nodes. Flag mapped if we are valid
slots = cluster_get_slots(seed TSRMLS_CC);
if(slots) mapped = !cluster_map_slots(c, slots);

// Bin anything mapped, if we failed somewhere
if(!mapped && slots) {
memset(c->master, 0, sizeof(redisClusterNode*)*REDIS_CLUSTER_SLOTS);
if (slots) {
mapped = !cluster_map_slots(c, slots);
// Bin anything mapped, if we failed somewhere
if (!mapped) {
memset(c->master, 0, sizeof(redisClusterNode*)*REDIS_CLUSTER_SLOTS);
}
}
redis_sock_disconnect(seed TSRMLS_CC);
}
if (mapped) break;
} ZEND_HASH_FOREACH_END();

// Clean up slots reply if we got one
if(slots) cluster_free_reply(slots, 1);
Expand Down Expand Up @@ -1081,13 +1072,11 @@ static int cluster_check_response(redisCluster *c, REDIS_REPLY_TYPE *reply_type
PHP_REDIS_API void cluster_disconnect(redisCluster *c TSRMLS_DC) {
redisClusterNode *node;

for(zend_hash_internal_pointer_reset(c->nodes);
(node = zend_hash_get_current_data_ptr(c->nodes)) != NULL;
zend_hash_move_forward(c->nodes))
{
ZEND_HASH_FOREACH_PTR(c->nodes, node) {
if (node == NULL) break;
redis_sock_disconnect(node->sock TSRMLS_CC);
node->sock->lazy_connect = 1;
}
} ZEND_HASH_FOREACH_END();
}

/* This method attempts to write our command at random to the master and any
Expand Down Expand Up @@ -1219,17 +1208,9 @@ static int cluster_sock_write(redisCluster *c, const char *cmd, size_t sz,
if(direct) return -1;

/* Fall back by attempting the request against every known node */
for(zend_hash_internal_pointer_reset(c->nodes);
zend_hash_has_more_elements(c->nodes)==SUCCESS;
zend_hash_move_forward(c->nodes))
{
/* Grab node */
if ((seed_node = zend_hash_get_current_data_ptr(c->nodes)) == NULL) {
continue;
}

ZEND_HASH_FOREACH_PTR(c->nodes, seed_node) {
/* Skip this node if it's the one that failed, or if it's a slave */
if(seed_node->sock == redis_sock || seed_node->slave) continue;
if (seed_node == NULL || seed_node->sock == redis_sock || seed_node->slave) continue;

/* Connect to this node if we haven't already */
CLUSTER_LAZY_CONNECT(seed_node->sock);
Expand All @@ -1240,7 +1221,7 @@ static int cluster_sock_write(redisCluster *c, const char *cmd, size_t sz,
c->cmd_sock = seed_node->sock;
return 0;
}
}
} ZEND_HASH_FOREACH_END();

/* We were unable to write to any node in our cluster */
return -1;
Expand Down
13 changes: 11 additions & 2 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ typedef struct {
) { \
_val = zend_hash_get_current_data_ex(ht, &_hpos); \

#define ZEND_HASH_FOREACH_PTR(ht, _ptr) do { \
HashPosition _hpos; \
for (zend_hash_internal_pointer_reset_ex(ht, &_hpos); \
zend_hash_has_more_elements_ex(ht, &_hpos) == SUCCESS; \
zend_hash_move_forward_ex(ht, &_hpos) \
) { \
_ptr = zend_hash_get_current_data_ptr_ex(ht, &_hpos); \

#define ZEND_HASH_FOREACH_END() \
} \
} while(0)
Expand Down Expand Up @@ -126,15 +134,16 @@ zend_hash_get_current_data(HashTable *ht)
}

static zend_always_inline void *
zend_hash_get_current_data_ptr(HashTable *ht)
zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos)
{
void **ptr;

if (zend_hash_get_current_data_ex(ht, (void **)&ptr, NULL) == SUCCESS) {
if (zend_hash_get_current_data_ex(ht, (void **)&ptr, pos) == SUCCESS) {
return *ptr;
}
return NULL;
}
#define zend_hash_get_current_data_ptr(ht) zend_hash_get_current_data_ptr_ex(ht, NULL)

static int (*_zend_hash_index_find)(const HashTable *, ulong, void **) = &zend_hash_index_find;
#define zend_hash_index_find(ht, h) inline_zend_hash_index_find(ht, h)
Expand Down
27 changes: 11 additions & 16 deletions redis_cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,10 +1037,8 @@ PHP_METHOD(RedisCluster, keys) {
c->readonly = CLUSTER_IS_ATOMIC(c);

/* Iterate over our known nodes */
for(zend_hash_internal_pointer_reset(c->nodes);
(node = zend_hash_get_current_data_ptr(c->nodes)) != NULL;
zend_hash_move_forward(c->nodes))
{
ZEND_HASH_FOREACH_PTR(c->nodes, node) {
if (node == NULL) break;
if (cluster_send_slot(c, node->slot, cmd, cmd_len, TYPE_MULTIBULK
TSRMLS_CC)<0)
{
Expand Down Expand Up @@ -1072,7 +1070,7 @@ PHP_METHOD(RedisCluster, keys) {

/* Free response, don't free data */
cluster_free_reply(resp, 0);
}
} ZEND_HASH_FOREACH_END();

efree(cmd);

Expand Down Expand Up @@ -1969,10 +1967,8 @@ PHP_METHOD(RedisCluster, _masters) {

array_init(z_ret);

for(zend_hash_internal_pointer_reset(c->nodes);
(node = zend_hash_get_current_data_ptr(c->nodes)) != NULL;
zend_hash_move_forward(c->nodes))
{
ZEND_HASH_FOREACH_PTR(c->nodes, node) {
if (node == NULL) break;
host = node->sock->host;
port = node->sock->port;

Expand All @@ -1985,7 +1981,7 @@ PHP_METHOD(RedisCluster, _masters) {
add_next_index_stringl(z_sub, host, strlen(host));
add_next_index_long(z_sub, port);
add_next_index_zval(z_ret, z_sub);
}
} ZEND_HASH_FOREACH_END();

RETVAL_ZVAL(z_ret, 1, 0);
}
Expand Down Expand Up @@ -2073,18 +2069,17 @@ PHP_METHOD(RedisCluster, watch) {
}

// Iterate over each node we'll be sending commands to
for(zend_hash_internal_pointer_reset(ht_dist);
zend_hash_get_current_key(ht_dist, NULL, &slot) == HASH_KEY_IS_LONG;
zend_hash_move_forward(ht_dist))
{
ZEND_HASH_FOREACH_PTR(ht_dist, dl) {
// Grab the clusterDistList pointer itself
if ((dl = zend_hash_get_current_data_ptr(ht_dist)) == NULL) {
if (dl == NULL) {
zend_throw_exception(redis_cluster_exception_ce,
"Internal error in a PHP HashTable", 0 TSRMLS_CC);
cluster_dist_free(ht_dist);
efree(z_args);
efree(cmd.c);
RETURN_FALSE;
} else if (zend_hash_get_current_key(ht_dist, NULL, &slot) != HASH_KEY_IS_LONG) {
break;
}

// Construct our watch command for this node
Expand All @@ -2104,7 +2099,7 @@ PHP_METHOD(RedisCluster, watch) {

// Zero out our command buffer
cmd.len = 0;
}
} ZEND_HASH_FOREACH_END();

// Cleanup
cluster_dist_free(ht_dist);
Expand Down
8 changes: 3 additions & 5 deletions redis_cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,11 @@
/* Reset anything flagged as MULTI */
#define CLUSTER_RESET_MULTI(c) \
redisClusterNode *_node; \
for(zend_hash_internal_pointer_reset(c->nodes); \
(_node = zend_hash_get_current_data_ptr(c->nodes)) != NULL; \
zend_hash_move_forward(c->nodes)) \
{ \
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; \

Expand Down

0 comments on commit 658ee37

Please sign in to comment.