diff options
author | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2018-01-29 23:25:33 +0300 |
---|---|---|
committer | Pavlo Yatsukhnenko <yatsukhnenko@gmail.com> | 2018-01-29 23:37:36 +0300 |
commit | 9cd059117a91c4011181b7499ccf21c844d0f0f1 (patch) | |
tree | 5645575989ca20d6b13902e5691f3b4ef46670f5 | |
parent | 2828c2f187900a5ddc450ce857b467d9e0b483ac (diff) |
Refactor RedisArray
Change type of returning value from `char *` to `zend_string *` for
`ra_extract_key` and `ra_call_extractor` functions.
Store keys as `zend_string *` in RedisArray::mset.
-rw-r--r-- | redis_array.c | 17 | ||||
-rw-r--r-- | redis_array_impl.c | 69 |
2 files changed, 40 insertions, 46 deletions
diff --git a/redis_array.c b/redis_array.c index 684d54ca..7fbbc6b4 100644 --- a/redis_array.c +++ b/redis_array.c @@ -1059,9 +1059,9 @@ PHP_METHOD(RedisArray, mset) RedisArray *ra; int *pos, argc, *argc_each; HashTable *h_keys; - char *key, **keys, kbuf[40]; - int key_len, *key_lens; - zend_string *zkey; + char *key, kbuf[40]; + int key_len; + zend_string **keys, *zkey; ulong idx; if ((ra = redis_array_get(getThis() TSRMLS_CC)) == NULL) { @@ -1084,8 +1084,7 @@ PHP_METHOD(RedisArray, mset) } argv = emalloc(argc * sizeof(zval*)); pos = emalloc(argc * sizeof(int)); - keys = emalloc(argc * sizeof(char*)); - key_lens = emalloc(argc * sizeof(int)); + keys = ecalloc(argc, sizeof(zend_string *)); argc_each = emalloc(ra->count * sizeof(int)); memset(argc_each, 0, ra->count * sizeof(int)); @@ -1106,8 +1105,7 @@ PHP_METHOD(RedisArray, mset) } argc_each[pos[i]]++; /* count number of keys per node */ - keys[i] = estrndup(key, key_len); - key_lens[i] = (int)key_len; + keys[i] = zend_string_init(key, key_len, 0); argv[i] = data; i++; } ZEND_HASH_FOREACH_END(); @@ -1134,7 +1132,7 @@ PHP_METHOD(RedisArray, mset) } else { ZVAL_ZVAL(z_tmp, argv[i], 1, 0); } - add_assoc_zval_ex(&z_argarray, keys[i], key_lens[i], z_tmp); + add_assoc_zval_ex(&z_argarray, ZSTR_VAL(keys[i]), ZSTR_LEN(keys[i]), z_tmp); found++; } @@ -1167,12 +1165,11 @@ PHP_METHOD(RedisArray, mset) /* Free any keys that we needed to allocate memory for, because they weren't strings */ for(i = 0; i < argc; i++) { - efree(keys[i]); + zend_string_release(keys[i]); } /* cleanup */ efree(keys); - efree(key_lens); efree(argv); efree(pos); efree(argc_each); diff --git a/redis_array_impl.c b/redis_array_impl.c index fbaa6bbd..3aca8c76 100644 --- a/redis_array_impl.c +++ b/redis_array_impl.c @@ -378,10 +378,10 @@ ra_make_array(HashTable *hosts, zval *z_fun, zval *z_dist, HashTable *hosts_prev /* call userland key extraction function */ -char * -ra_call_extractor(RedisArray *ra, const char *key, int key_len, int *out_len TSRMLS_DC) +zend_string * +ra_call_extractor(RedisArray *ra, const char *key, int key_len TSRMLS_DC) { - char *out = NULL; + zend_string *out = NULL; zval z_ret, z_argv; /* check that we can call the extractor function */ @@ -400,8 +400,11 @@ ra_call_extractor(RedisArray *ra, const char *key, int key_len, int *out_len TSR call_user_function(EG(function_table), NULL, &ra->z_fun, &z_ret, 1, &z_argv); if (Z_TYPE(z_ret) == IS_STRING) { - *out_len = Z_STRLEN(z_ret); - out = estrndup(Z_STRVAL(z_ret), *out_len); +#if (PHP_MAJOR_VERSION < 7) + out = zend_string_init(Z_STRVAL(z_ret), Z_STRLEN(z_ret), 0); +#else + out = zval_get_string(&z_ret); +#endif } zval_dtor(&z_argv); @@ -409,20 +412,18 @@ ra_call_extractor(RedisArray *ra, const char *key, int key_len, int *out_len TSR return out; } -static char * -ra_extract_key(RedisArray *ra, const char *key, int key_len, int *out_len TSRMLS_DC) { - +static zend_string * +ra_extract_key(RedisArray *ra, const char *key, int key_len TSRMLS_DC) +{ char *start, *end; - *out_len = key_len; if (Z_TYPE(ra->z_fun) != IS_NULL) { - return ra_call_extractor(ra, key, key_len, out_len TSRMLS_CC); + return ra_call_extractor(ra, key, key_len TSRMLS_CC); } else if ((start = strchr(key, '{')) == NULL || (end = strchr(start + 1, '}')) == NULL) { - return estrndup(key, key_len); + return zend_string_init(key, key_len, 0); } /* found substring */ - *out_len = end - start - 1; - return estrndup(start + 1, *out_len); + return zend_string_init(start + 1, end - start - 1, 0); } /* call userland key distributor function */ @@ -455,39 +456,35 @@ ra_call_distributor(RedisArray *ra, const char *key, int key_len TSRMLS_DC) } zval * -ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos TSRMLS_DC) { - uint32_t hash; - char *out; - int pos, out_len; +ra_find_node(RedisArray *ra, const char *key, int key_len, int *out_pos TSRMLS_DC) +{ + int pos; + zend_string *out; /* extract relevant part of the key */ - out = ra_extract_key(ra, key, key_len, &out_len TSRMLS_CC); - if(!out) return NULL; + if ((out = ra_extract_key(ra, key, key_len TSRMLS_CC)) == NULL) { + return NULL; + } - if (Z_TYPE(ra->z_dist) != IS_NULL) { - pos = ra_call_distributor(ra, key, key_len TSRMLS_CC); - if (pos < 0 || pos >= ra->count) { - efree(out); - return NULL; - } - } else { - uint64_t h64; + if (Z_TYPE(ra->z_dist) == IS_NULL) { + int i; unsigned long ret = 0xffffffff; - size_t i; /* hash */ - for (i = 0; i < out_len; ++i) { - CRC32(ret, (unsigned char)out[i]); + for (i = 0; i < ZSTR_LEN(out); ++i) { + CRC32(ret, ZSTR_VAL(out)[i]); } - hash = (ret ^ 0xffffffff); /* get position on ring */ - h64 = hash; - h64 *= ra->count; - h64 /= 0xffffffff; - pos = (int)h64; + pos = (int)((ret ^ 0xffffffff) * ra->count / 0xffffffff); + } else { + pos = ra_call_distributor(ra, key, key_len TSRMLS_CC); + if (pos < 0 || pos >= ra->count) { + zend_string_release(out); + return NULL; + } } - efree(out); + zend_string_release(out); if(out_pos) *out_pos = pos; |