Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

use object handlers (2-3x speedup of basic ops)

  • Loading branch information...
commit 47cf7e3274a6cd3b76337c32e7d00c9cb49da1c0 1 parent 1cae895
@tony2001 authored
Showing with 523 additions and 417 deletions.
  1. +36 −345 judy_arrayaccess.c
  2. +480 −70 php_judy.c
  3. +7 −2 php_judy.h
View
381 judy_arrayaccess.c
@@ -20,379 +20,70 @@
#include "judy_arrayaccess.h"
/* {{{ proto int Judy::offsetSet(mixed offset, mixed value)
- set the value at the given offset in the Judy Array */
+ Set the value at the given offset in the Judy Array */
PHP_METHOD(judy, offsetSet)
{
- JUDY_METHOD_GET_OBJECT
+ zval *offset, *value;
- if (intern->type == TYPE_BITSET)
- {
- zval *zindex;
- Word_t index;
- zend_bool value;
- int Rc_int;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &value) == FAILURE) {
+ RETURN_FALSE;
+ }
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!b", &zindex, &value) == FAILURE) {
- RETURN_FALSE;
- }
-
- if (zindex && Z_TYPE_P(zindex) != IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "index parameter expected to be integer, %s given", zend_zval_type_name(zindex));
- RETURN_FALSE;
- }
-
- if (!zindex || Z_LVAL_P(zindex) <= -1) {
- if (intern->array) {
- if (!zindex && intern->next_empty_is_valid) {
- index = intern->next_empty++;
- } else {
- index = -1;
- J1L(Rc_int, intern->array, index);
-
- if (Rc_int == 1) {
- index += 1;
- if (!zindex) {
- intern->next_empty = index + 1;
- intern->next_empty_is_valid = 1;
- }
- } else {
- RETURN_FALSE;
- }
- }
- } else {
- if (intern->next_empty_is_valid) {
- index = intern->next_empty++;
- } else {
- index = 0;
- }
- }
- } else {
- index = Z_LVAL_P(zindex);
- intern->next_empty_is_valid = 0;
- }
-
- if (value == 1) {
- J1S(Rc_int, intern->array, index);
- } else {
- J1U(Rc_int, intern->array, index);
- }
- RETURN_BOOL(Rc_int);
- } else if (intern->type == TYPE_INT_TO_INT) {
- zval *zindex;
- Word_t index;
- long value;
- Pvoid_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!l", &zindex, &value) == FAILURE) {
- RETURN_FALSE;
- }
-
- if (zindex && Z_TYPE_P(zindex) != IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "index parameter expected to be integer, %s given", zend_zval_type_name(zindex));
- RETURN_FALSE;
- }
-
- if (!zindex || Z_LVAL_P(zindex) <= -1) {
- if (intern->array) {
- if (!zindex && intern->next_empty_is_valid) {
- index = intern->next_empty++;
- } else {
- index = -1;
- JLL(PValue, intern->array, index);
-
- if (PValue != NULL && PValue != PJERR) {
- index += 1;
- if (!zindex) {
- intern->next_empty = index + 1;
- intern->next_empty_is_valid = 1;
- }
- } else {
- RETURN_FALSE;
- }
- }
- } else {
- if (intern->next_empty_is_valid) {
- index = intern->next_empty++;
- } else {
- index = 0;
- }
- }
- } else {
- index = Z_LVAL_P(zindex);
- intern->next_empty_is_valid = 0;
- }
-
- JLI(PValue, intern->array, index);
- if (PValue != NULL && PValue != PJERR) {
- *PValue = (void *)value;
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- } else if (intern->type == TYPE_INT_TO_MIXED) {
- zval *zindex;
- Word_t index;
- zval *value;
- Pvoid_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!z", &zindex, &value) == FAILURE) {
- RETURN_FALSE;
- }
-
- if (zindex && Z_TYPE_P(zindex) != IS_LONG) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "index parameter expected to be integer, %s given", zend_zval_type_name(zindex));
- RETURN_FALSE;
- }
-
- if (!zindex || Z_LVAL_P(zindex) <= -1) {
- if (intern->array){
- if (!zindex && intern->next_empty_is_valid) {
- index = intern->next_empty++;
- } else {
- index = -1;
- JLL(PValue, intern->array, index);
-
- if (PValue != NULL && PValue != PJERR) {
- index += 1;
- if (!zindex) {
- intern->next_empty = index + 1;
- intern->next_empty_is_valid = 1;
- }
- } else {
- RETURN_FALSE;
- }
- }
- } else {
- if (intern->next_empty_is_valid) {
- index = intern->next_empty++;
- } else {
- index = 0;
- }
- }
- } else {
- index = Z_LVAL_P(zindex);
- intern->next_empty_is_valid = 0;
- }
-
- JLI(PValue, intern->array, index);
- if (PValue != NULL && PValue != PJERR) {
- if (*PValue != NULL) {
- zval *old_value = (zval *)*PValue;
- zval_ptr_dtor(&old_value);
- }
- *PValue = value;
- Z_ADDREF_P(value);
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- } else if (intern->type == TYPE_STRING_TO_INT) {
- uint8_t *key;
- int key_length;
- Word_t *value;
- PWord_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &key, &key_length, &value) == FAILURE) {
- RETURN_FALSE;
- }
-
- JSLI(PValue, intern->array, key);
- if (PValue != NULL && PValue != PJERR) {
- *PValue = value;
- intern->counter++;
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- } else if (intern->type == TYPE_STRING_TO_MIXED) {
- uint8_t *key;
- int key_length;
- zval *value;
- Pvoid_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &key, &key_length, &value) == FAILURE) {
- RETURN_FALSE;
- }
-
- JSLI(PValue, intern->array, key);
- if (PValue != NULL && PValue != PJERR) {
- if (*PValue != NULL) {
- zval *old_value = (zval *)*PValue;
- zval_ptr_dtor(&old_value);
- }
- *PValue = value;
- Z_ADDREF_P(value);
- intern->counter++;
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
- }
+ if (judy_object_write_dimension_helper(getThis(), offset, value TSRMLS_CC) == SUCCESS) {
+ RETURN_TRUE;
+ }
RETURN_FALSE;
}
/* }}} */
-/* {{{ proto int Judy::offsetSet(mixed offset)
- set the value at the given offset in the Judy Array */
+/* {{{ proto int Judy::offsetUnset(mixed offset)
+ Unset the given offset in the Judy Array */
PHP_METHOD(judy, offsetUnset)
{
- int Rc_int;
-
- JUDY_METHOD_GET_OBJECT
+ zval *offset;
- if (intern->type == TYPE_BITSET) {
- Word_t index;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ RETURN_FALSE;
+ }
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
- RETURN_FALSE;
- }
-
- J1U(Rc_int, intern->array, index);
- } else if (intern->type == TYPE_INT_TO_INT || intern->type == TYPE_INT_TO_MIXED) {
- Word_t index;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
- RETURN_FALSE;
- }
-
- if (intern->type == TYPE_INT_TO_INT) {
- JLD(Rc_int, intern->array, index);
- } else {
- Pvoid_t *PValue;
- JLG(PValue, intern->array, index);
- if (PValue != NULL && PValue != PJERR) {
- zval *value = (zval *)*PValue;
- zval_ptr_dtor(&value);
- JLD(Rc_int, intern->array, index);
- }
- }
- if (Rc_int == 1)
- intern->counter--;
- } else if (intern->type == TYPE_STRING_TO_INT || intern->type == TYPE_STRING_TO_MIXED) {
- uint8_t *key;
- int key_length;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_length) == FAILURE) {
- RETURN_FALSE;
- }
-
- if (intern->type == TYPE_STRING_TO_INT) {
- JSLD(Rc_int, intern->array, key);
- } else {
- Pvoid_t *PValue;
- JSLG(PValue, intern->array, key);
- if (PValue != NULL && PValue != PJERR) {
- zval *value = (zval *)*PValue;
- zval_ptr_dtor(&value);
- JSLD(Rc_int, intern->array, key);
- }
- }
- if (Rc_int == 1)
- intern->counter--;
- }
-
- RETURN_BOOL(Rc_int);
+ if (judy_object_unset_dimension_helper(getThis(), offset TSRMLS_CC) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ RETURN_FALSE;
}
/* }}} */
/* {{{ proto mixed Judy::offsetGet(mixed offset)
- set the value at the given offset in the Judy Array */
+ Fetch the given offset in the Judy Array */
PHP_METHOD(judy, offsetGet)
{
- JUDY_METHOD_GET_OBJECT
-
- if (intern->type == TYPE_BITSET) {
- Word_t index;
- int Rc_int;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
- RETURN_FALSE;
- }
-
- J1T(Rc_int, intern->array, index);
- RETURN_BOOL(Rc_int);
- } else if (intern->type == TYPE_INT_TO_INT || intern->type == TYPE_INT_TO_MIXED) {
- Word_t index;
- Word_t *PValue;
+ zval *offset, *result;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
- RETURN_FALSE;
- }
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ RETURN_FALSE;
+ }
- JLG(PValue, intern->array, index);
- if (PValue != NULL && PValue != PJERR) {
- if (intern->type == TYPE_INT_TO_INT) {
- RETURN_LONG(*PValue);
- } else {
- RETURN_ZVAL(*((zval **)PValue), 1, 0);
- }
- }
- } else if (intern->type == TYPE_STRING_TO_INT || intern->type == TYPE_STRING_TO_MIXED) {
- uint8_t *key;
- int key_length;
- Word_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_length) == FAILURE) {
- RETURN_FALSE;
- }
-
- JSLG(PValue, intern->array, key);
- if (PValue != NULL && PValue != PJERR) {
- if (intern->type == TYPE_STRING_TO_INT) {
- RETURN_LONG(*PValue);
- } else {
- RETURN_ZVAL(*((zval **)PValue), 1 ,0);
- }
- }
- }
-
- RETURN_NULL();
+ result = judy_object_read_dimension_helper(getThis(), offset TSRMLS_CC);
+ if (!result) {
+ RETURN_FALSE;
+ }
+ RETURN_ZVAL(result, 1, 0);
}
/* }}} */
/* {{{ proto int Judy::offsetExists(mixed offset)
- set the value at the given offset in the Judy Array */
+ Check if the the given offset exists in the Judy Array */
PHP_METHOD(judy, offsetExists)
{
- JUDY_METHOD_GET_OBJECT
-
- if (intern->type == TYPE_BITSET) {
- Word_t index;
- int Rc_int;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
- RETURN_FALSE;
- }
-
- J1T(Rc_int, intern->array, index);
- RETURN_BOOL(Rc_int);
- } else if (intern->type == TYPE_INT_TO_INT || intern->type == TYPE_INT_TO_MIXED) {
- Word_t index;
- Word_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) {
- RETURN_FALSE;
- }
-
- JLG(PValue, intern->array, index);
- if (PValue != NULL && PValue != PJERR) {
- RETURN_TRUE;
- }
- } else if (intern->type == TYPE_STRING_TO_INT || intern->type == TYPE_STRING_TO_MIXED) {
- uint8_t *key;
- int key_length;
- Word_t *PValue;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_length) == FAILURE) {
- RETURN_FALSE;
- }
+ zval *offset;
- JSLG(PValue, intern->array, key);
- if (PValue != NULL && PValue != PJERR) {
- RETURN_TRUE;
- }
- }
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (judy_object_has_dimension_helper(getThis(), offset, 0 TSRMLS_CC)) {
+ RETURN_TRUE;
+ }
RETURN_FALSE;
}
/* }}} */
View
550 php_judy.c
@@ -27,10 +27,9 @@
ZEND_DECLARE_MODULE_GLOBALS(judy)
- /* declare judy class entry */
- zend_class_entry *judy_ce;
-
- zend_object_handlers judy_handlers;
+/* declare judy class entry */
+zend_class_entry *judy_ce;
+zend_object_handlers judy_handlers;
/* {{{ php_judy_init_globals
*/
@@ -104,10 +103,419 @@ PHPAPI zend_class_entry *php_judy_ce(void)
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("judy.string.maxlength", "65536", PHP_INI_ALL, OnUpdateLong, max_length, zend_judy_globals, judy_globals)
PHP_INI_END()
- /* }}} */
+/* }}} */
- /* {{{ PHP_MINIT_FUNCTION
- */
+#define CHECK_ARRAY_AND_ARG_TYPE(_index_, _string_key_, _return_) \
+ switch (intern->type) { \
+ case TYPE_BITSET: \
+ case TYPE_INT_TO_INT: \
+ case TYPE_INT_TO_MIXED: \
+ if (Z_TYPE_P(offset) != IS_LONG) { \
+ zval tmp = *offset; \
+ zval_copy_ctor(&tmp); \
+ INIT_PZVAL(&tmp); \
+ convert_to_long(&tmp); \
+ _index_ = Z_LVAL(tmp); \
+ } else { \
+ _index_ = Z_LVAL_P(offset); \
+ } \
+ /* avoid zval_dtor() */ \
+ _string_key_ = offset; \
+ break; \
+ case TYPE_STRING_TO_INT: \
+ case TYPE_STRING_TO_MIXED: \
+ if (Z_TYPE_P(offset) != IS_STRING) { \
+ *_string_key_ = *offset; \
+ zval_copy_ctor(_string_key_); \
+ INIT_PZVAL(_string_key_); \
+ convert_to_string(_string_key_); \
+ } else { \
+ _string_key_ = offset; \
+ } \
+ break; \
+ default: \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid Judy Array type, please report"); \
+ _return_; \
+ }
+
+zval *judy_object_read_dimension_helper(zval *object, zval *offset TSRMLS_DC) /* {{{ */
+{
+ long index = 0;
+ Word_t j_index;
+ Pvoid_t *PValue = NULL;
+ zval *result;
+ zval string_key, *pstring_key = &string_key;
+ judy_object *intern = (judy_object *) zend_object_store_get_object(object TSRMLS_CC);
+
+ if (intern->array == NULL) {
+ return NULL;
+ }
+
+ CHECK_ARRAY_AND_ARG_TYPE(index, pstring_key, return NULL);
+
+ j_index = index;
+
+ if (intern->type == TYPE_BITSET) {
+ int Rc_int;
+
+ J1T(Rc_int, intern->array, j_index);
+ MAKE_STD_ZVAL(result);
+ Z_SET_REFCOUNT_P(result, 0);
+ Z_UNSET_ISREF_P(result);
+ ZVAL_BOOL(result, Rc_int);
+ return result;
+ }
+
+ switch(intern->type) {
+ case TYPE_INT_TO_INT:
+ case TYPE_INT_TO_MIXED:
+ JLG(PValue, intern->array, j_index);
+ break;
+ case TYPE_STRING_TO_INT:
+ case TYPE_STRING_TO_MIXED:
+ JSLG(PValue, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ break;
+ }
+
+ if (PValue != NULL && PValue != PJERR) {
+ MAKE_STD_ZVAL(result);
+ Z_SET_REFCOUNT_P(result, 0);
+ Z_UNSET_ISREF_P(result);
+
+ if (intern->type == TYPE_INT_TO_INT || intern->type == TYPE_STRING_TO_INT) {
+ ZVAL_LONG(result, (long)*PValue);
+ } else if (intern->type == TYPE_INT_TO_MIXED || intern->type == TYPE_STRING_TO_MIXED) {
+ ZVAL_ZVAL(result, *(zval **)PValue, 1, 0);
+ }
+ if (pstring_key != offset) {
+ zval_dtor(pstring_key);
+ }
+ return result;
+ }
+ if (pstring_key != offset) {
+ zval_dtor(pstring_key);
+ }
+ return NULL;
+}
+/* }}} */
+
+static zval *judy_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */
+{
+ return judy_object_read_dimension_helper(object, offset TSRMLS_CC);
+}
+/* }}} */
+
+int judy_object_write_dimension_helper(zval *object, zval *offset, zval *value TSRMLS_DC) /* {{{ */
+{
+ long dummy;
+ zval string_key, *pstring_key = &string_key;
+ judy_object *intern = (judy_object *) zend_object_store_get_object(object TSRMLS_CC);
+
+ if (offset) {
+ CHECK_ARRAY_AND_ARG_TYPE(dummy, pstring_key, return FAILURE);
+ (void)dummy;
+ }
+
+ if (intern->type == TYPE_BITSET) {
+ Word_t index;
+ int Rc_int;
+
+ if (!offset || Z_LVAL_P(offset) <= -1) {
+ if (intern->array) {
+ if (!offset && intern->next_empty_is_valid) {
+ index = intern->next_empty++;
+ } else {
+ index = -1;
+ J1L(Rc_int, intern->array, index);
+
+ if (Rc_int == 1) {
+ index += 1;
+ if (!offset) {
+ intern->next_empty = index + 1;
+ intern->next_empty_is_valid = 1;
+ }
+ } else {
+ return FAILURE;
+ }
+ }
+ } else {
+ if (intern->next_empty_is_valid) {
+ index = intern->next_empty++;
+ } else {
+ index = 0;
+ }
+ }
+ } else {
+ index = Z_LVAL_P(offset);
+ intern->next_empty_is_valid = 0;
+ }
+
+ if (zend_is_true(value)) {
+ J1S(Rc_int, intern->array, index);
+ } else {
+ J1U(Rc_int, intern->array, index);
+ }
+ return Rc_int ? SUCCESS : FAILURE;
+ } else if (intern->type == TYPE_INT_TO_INT) {
+ Word_t index;
+ Pvoid_t *PValue;
+
+ if (!offset || Z_LVAL_P(offset) <= -1) {
+ if (intern->array) {
+ if (!offset && intern->next_empty_is_valid) {
+ index = intern->next_empty++;
+ } else {
+ index = -1;
+ JLL(PValue, intern->array, index);
+
+ if (PValue != NULL && PValue != PJERR) {
+ index += 1;
+ if (!offset) {
+ intern->next_empty = index + 1;
+ intern->next_empty_is_valid = 1;
+ }
+ } else {
+ return FAILURE;
+ }
+ }
+ } else {
+ if (intern->next_empty_is_valid) {
+ index = intern->next_empty++;
+ } else {
+ index = 0;
+ }
+ }
+ } else {
+ index = Z_LVAL_P(offset);
+ intern->next_empty_is_valid = 0;
+ }
+
+ JLI(PValue, intern->array, index);
+ if (PValue != NULL && PValue != PJERR) {
+ *PValue = (void *)Z_LVAL_P(value);
+ return SUCCESS;
+ }
+ return FAILURE;
+ } else if (intern->type == TYPE_INT_TO_MIXED) {
+ Word_t index;
+ Pvoid_t *PValue;
+
+ if (!offset || Z_LVAL_P(offset) <= -1) {
+ if (intern->array){
+ if (!offset && intern->next_empty_is_valid) {
+ index = intern->next_empty++;
+ } else {
+ index = -1;
+ JLL(PValue, intern->array, index);
+
+ if (PValue != NULL && PValue != PJERR) {
+ index += 1;
+ if (!offset) {
+ intern->next_empty = index + 1;
+ intern->next_empty_is_valid = 1;
+ }
+ } else {
+ return FAILURE;
+ }
+ }
+ } else {
+ if (intern->next_empty_is_valid) {
+ index = intern->next_empty++;
+ } else {
+ index = 0;
+ }
+ }
+ } else {
+ index = Z_LVAL_P(offset);
+ intern->next_empty_is_valid = 0;
+ }
+
+ JLI(PValue, intern->array, index);
+ if (PValue != NULL && PValue != PJERR) {
+ if (*PValue != NULL) {
+ zval *old_value = (zval *)*PValue;
+ zval_ptr_dtor(&old_value);
+ }
+ *PValue = value;
+ Z_ADDREF_P(value);
+ return SUCCESS;
+ }
+ return FAILURE;
+ } else if (intern->type == TYPE_STRING_TO_INT) {
+ PWord_t *PValue;
+ int res;
+
+ JSLI(PValue, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ if (PValue != NULL && PValue != PJERR) {
+ *PValue = (void *)Z_LVAL_P(value);
+ intern->counter++;
+ res = SUCCESS;
+ } else {
+ res = FAILURE;
+ }
+ if (pstring_key != offset) {
+ zval_dtor(pstring_key);
+ }
+ return res;
+ } else if (intern->type == TYPE_STRING_TO_MIXED) {
+ Pvoid_t *PValue;
+ int res;
+
+ JSLI(PValue, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ if (PValue != NULL && PValue != PJERR) {
+ if (*PValue != NULL) {
+ zval *old_value = (zval *)*PValue;
+ zval_ptr_dtor(&old_value);
+ }
+ *PValue = value;
+ Z_ADDREF_P(value);
+ intern->counter++;
+ res = SUCCESS;
+ } else {
+ res = FAILURE;
+ }
+ if (pstring_key != offset) {
+ zval_dtor(pstring_key);
+ }
+ return res;
+ }
+ return FAILURE;
+}
+/* }}} */
+
+static void judy_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) /* {{{ */
+{
+ judy_object_write_dimension_helper(object, offset, value TSRMLS_CC);
+}
+/* }}} */
+
+int judy_object_has_dimension_helper(zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */
+{
+ long index = 0;
+ Word_t j_index;
+ Pvoid_t *PValue = NULL;
+ zval string_key, *pstring_key = &string_key;
+ judy_object *intern = (judy_object *) zend_object_store_get_object(object TSRMLS_CC);
+
+ if (intern->array == NULL) {
+ return 0;
+ }
+
+ CHECK_ARRAY_AND_ARG_TYPE(index, pstring_key, return 0);
+
+ j_index = index;
+
+ if (intern->type == TYPE_BITSET) {
+ int Rc_int;
+
+ J1T(Rc_int, intern->array, j_index);
+ return Rc_int;
+ }
+
+ switch(intern->type) {
+ case TYPE_INT_TO_INT:
+ case TYPE_INT_TO_MIXED:
+ JLG(PValue, intern->array, j_index);
+ break;
+ case TYPE_STRING_TO_INT:
+ case TYPE_STRING_TO_MIXED:
+ JSLG(PValue, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ if (pstring_key != offset) {
+ zval_dtor(pstring_key);
+ }
+ break;
+ }
+
+ if (PValue != NULL && PValue != PJERR) {
+ if (!check_empty) {
+ return 1;
+ } else if (intern->type == TYPE_INT_TO_INT || intern->type == TYPE_STRING_TO_INT) {
+ if (*PValue) {
+ return 1;
+ }
+ return 0;
+ } else if (intern->type == TYPE_INT_TO_MIXED || intern->type == TYPE_STRING_TO_MIXED) {
+ if (*PValue && zend_is_true((zval *)*PValue)) {
+ return 1;
+ }
+ return 0;
+ }
+ }
+ return 0;
+}
+/* }}} */
+
+static int judy_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */
+{
+ return judy_object_has_dimension_helper(object, offset, check_empty TSRMLS_CC);
+}
+/* }}} */
+
+int judy_object_unset_dimension_helper(zval *object, zval *offset TSRMLS_DC) /* {{{ */
+{
+ int Rc_int = 0;
+ long index = 0;
+ Word_t j_index;
+ zval string_key, *pstring_key = &string_key;
+ judy_object *intern = (judy_object *) zend_object_store_get_object(object TSRMLS_CC);
+
+ if (intern->array == NULL) {
+ return FAILURE;
+ }
+
+ CHECK_ARRAY_AND_ARG_TYPE(index, pstring_key, return FAILURE);
+
+ j_index = index;
+
+ if (intern->type == TYPE_BITSET) {
+ J1U(Rc_int, intern->array, j_index);
+ } else if (intern->type == TYPE_INT_TO_INT || intern->type == TYPE_INT_TO_MIXED) {
+ if (intern->type == TYPE_INT_TO_INT) {
+ JLD(Rc_int, intern->array, j_index);
+ } else {
+ Pvoid_t *PValue;
+
+ JLG(PValue, intern->array, j_index);
+ if (PValue != NULL && PValue != PJERR) {
+ zval *value = (zval *)*PValue;
+ zval_ptr_dtor(&value);
+ JLD(Rc_int, intern->array, j_index);
+ }
+ }
+ if (Rc_int == 1) {
+ intern->counter--;
+ }
+ } else if (intern->type == TYPE_STRING_TO_INT || intern->type == TYPE_STRING_TO_MIXED) {
+ if (intern->type == TYPE_STRING_TO_INT) {
+ JSLD(Rc_int, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ } else {
+ Pvoid_t *PValue;
+ JSLG(PValue, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ if (PValue != NULL && PValue != PJERR) {
+ zval *value = (zval *)*PValue;
+ zval_ptr_dtor(&value);
+ JSLD(Rc_int, intern->array, (uint8_t *)Z_STRVAL_P(pstring_key));
+ }
+ }
+ if (Rc_int == 1) {
+ intern->counter--;
+ }
+ if (pstring_key != offset) {
+ zval_dtor(pstring_key);
+ }
+ }
+ return Rc_int ? SUCCESS : FAILURE;
+}
+/* }}} */
+
+static void judy_object_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{{ */
+{
+ judy_object_unset_dimension_helper(object, offset TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ PHP_MINIT_FUNCTION
+*/
PHP_MINIT_FUNCTION(judy)
{
zend_class_entry ce;
@@ -129,9 +537,13 @@ PHP_MINIT_FUNCTION(judy)
/* set some internal handlers */
judy_handlers.clone_obj = judy_object_clone;
judy_handlers.count_elements = judy_object_count;
+ judy_handlers.read_dimension = judy_object_read_dimension;
+ judy_handlers.write_dimension = judy_object_write_dimension;
+ judy_handlers.unset_dimension = judy_object_unset_dimension;
+ judy_handlers.has_dimension = judy_object_has_dimension;
/* implements some interface to provide access to judy object as an array */
- zend_class_implements(judy_ce TSRMLS_CC, 1, zend_ce_arrayaccess, zend_ce_iterator);
+ zend_class_implements(judy_ce TSRMLS_CC, 1, zend_ce_arrayaccess);
judy_ce->get_iterator = judy_get_iterator;
@@ -184,7 +596,7 @@ PHP_METHOD(judy, __construct)
JUDY_METHOD_GET_OBJECT
- JUDY_METHOD_ERROR_HANDLING;
+ JUDY_METHOD_ERROR_HANDLING;
if (intern->type) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Judy Array already instantiated");
@@ -805,87 +1217,85 @@ PHP_METHOD(judy, offsetExists);
/* {{{ Judy function parameters
*/
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_type, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_type, 0, 0, 1)
ZEND_ARG_INFO(0, array)
ZEND_END_ARG_INFO()
- /* }}} */
+/* }}} */
- /* {{{ Judy class methods parameters
- */
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_count, 0, 0, 0)
+/* {{{ Judy class methods parameters
+*/
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_count, 0, 0, 0)
ZEND_ARG_INFO(0, index_start)
ZEND_ARG_INFO(0, index_end)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_byCount, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_byCount, 0, 0, 1)
ZEND_ARG_INFO(0, nth_index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_first, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_first, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_next, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_next, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_last, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_last, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_prev, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_prev, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_firstEmpty, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_firstEmpty, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_nextEmpty, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_nextEmpty, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_lastEmpty, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_lastEmpty, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_prevEmpty, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_prevEmpty, 0, 0, 1)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
- /* }}} */
+/* }}} */
- /* {{{ Judy class methods parameters the Array Access Interface
- */
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetSet, 0, 0, 2)
+/* {{{ Judy class methods parameters the Array Access Interface
+*/
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetSet, 0, 0, 2)
ZEND_ARG_INFO(0, offset)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetUnset, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetUnset, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetGet, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetGet, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()
- ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetExists, 0, 0, 1)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_judy_offsetExists, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()
- /* }}} */
-
- /* {{{ judy_functions[]
- *
- * Every user visible function must have an entry in judy_functions[].
- */
- const zend_function_entry judy_functions[] = {
- /* PHP JUDY FUNCTIONS */
- PHP_FE(judy_version, NULL)
- PHP_FE(judy_type, arginfo_judy_type)
+/* }}} */
- /* NULL TEMRINATED VECTOR */
- {NULL, NULL, NULL}
- };
+/* {{{ judy_functions[]
+ *
+ * Every user visible function must have an entry in judy_functions[].
+ */
+const zend_function_entry judy_functions[] = {
+ /* PHP JUDY FUNCTIONS */
+ PHP_FE(judy_version, NULL)
+ PHP_FE(judy_type, arginfo_judy_type)
+ {NULL, NULL, NULL}
+};
/* }}} */
/* {{{ judy_class_methodss[]
@@ -895,32 +1305,32 @@ ZEND_END_ARG_INFO()
const zend_function_entry judy_class_methods[] = {
/* PHP JUDY METHODS */
PHP_ME(judy, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(judy, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
- PHP_ME(judy, getType, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(judy, free, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(judy, memoryUsage, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(judy, count, arginfo_judy_count, ZEND_ACC_PUBLIC)
- PHP_ME(judy, byCount, arginfo_judy_byCount, ZEND_ACC_PUBLIC)
- PHP_ME(judy, first, arginfo_judy_first, ZEND_ACC_PUBLIC)
- PHP_ME(judy, next, arginfo_judy_next, ZEND_ACC_PUBLIC)
- PHP_ME(judy, last, arginfo_judy_last, ZEND_ACC_PUBLIC)
- PHP_ME(judy, prev, arginfo_judy_prev, ZEND_ACC_PUBLIC)
- PHP_ME(judy, firstEmpty, arginfo_judy_firstEmpty, ZEND_ACC_PUBLIC)
- PHP_ME(judy, nextEmpty, arginfo_judy_nextEmpty, ZEND_ACC_PUBLIC)
- PHP_ME(judy, lastEmpty, arginfo_judy_lastEmpty, ZEND_ACC_PUBLIC)
- PHP_ME(judy, prevEmpty, arginfo_judy_prevEmpty, ZEND_ACC_PUBLIC)
-
- /* PHP JUDY METHODS / ARRAYACCESS INTERFACE */
- PHP_ME(judy, offsetSet, arginfo_judy_offsetSet, ZEND_ACC_PUBLIC)
- PHP_ME(judy, offsetUnset, arginfo_judy_offsetUnset, ZEND_ACC_PUBLIC)
- PHP_ME(judy, offsetGet, arginfo_judy_offsetGet, ZEND_ACC_PUBLIC)
- PHP_ME(judy, offsetExists, arginfo_judy_offsetExists, ZEND_ACC_PUBLIC)
-
- /* PHP JUDY METHODS ALIAS */
- PHP_MALIAS(judy, size, count, NULL, ZEND_ACC_PUBLIC)
-
- /* NULL TEMRINATED VECTOR */
- {NULL, NULL, NULL}
+ PHP_ME(judy, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR)
+ PHP_ME(judy, getType, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, free, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, memoryUsage, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, count, arginfo_judy_count, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, byCount, arginfo_judy_byCount, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, first, arginfo_judy_first, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, next, arginfo_judy_next, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, last, arginfo_judy_last, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, prev, arginfo_judy_prev, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, firstEmpty, arginfo_judy_firstEmpty, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, nextEmpty, arginfo_judy_nextEmpty, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, lastEmpty, arginfo_judy_lastEmpty, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, prevEmpty, arginfo_judy_prevEmpty, ZEND_ACC_PUBLIC)
+
+ /* PHP JUDY METHODS / ARRAYACCESS INTERFACE */
+ PHP_ME(judy, offsetSet, arginfo_judy_offsetSet, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, offsetUnset, arginfo_judy_offsetUnset, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, offsetGet, arginfo_judy_offsetGet, ZEND_ACC_PUBLIC)
+ PHP_ME(judy, offsetExists, arginfo_judy_offsetExists, ZEND_ACC_PUBLIC)
+
+ /* PHP JUDY METHODS ALIAS */
+ PHP_MALIAS(judy, size, count, NULL, ZEND_ACC_PUBLIC)
+
+ /* NULL TEMRINATED VECTOR */
+ {NULL, NULL, NULL}
};
/* }}} */
@@ -928,7 +1338,7 @@ const zend_function_entry judy_class_methods[] = {
*/
zend_module_entry judy_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
- STANDARD_MODULE_HEADER,
+ STANDARD_MODULE_HEADER,
#endif
PHP_JUDY_EXTNAME,
judy_functions,
View
9 php_judy.h
@@ -85,8 +85,8 @@ typedef struct _judy_object {
zend_bool next_empty_is_valid;
} judy_object;
-/* Max length, this must be a constant for it to work in
- * declarings as we cannot use runtime decided values at
+/* Max length, this must be a constant for it to work in
+ * declarings as we cannot use runtime decided values at
* compile time ofcourse
*
* TODO: This needs to be handled better
@@ -96,6 +96,11 @@ typedef struct _judy_object {
zend_object_value judy_object_new(zend_class_entry *ce TSRMLS_DC);
zend_object_value judy_object_new_ex(zend_class_entry *ce, judy_object **ptr TSRMLS_DC);
+zval *judy_object_read_dimension_helper(zval *object, zval *offset TSRMLS_DC);
+int judy_object_write_dimension_helper(zval *object, zval *offset, zval *value TSRMLS_DC);
+int judy_object_has_dimension_helper(zval *object, zval *offset, int check_empty TSRMLS_DC);
+int judy_object_unset_dimension_helper(zval *object, zval *offset TSRMLS_DC);
+
/* {{{ REGISTER_JUDY_CLASS_CONST_LONG */
#define REGISTER_JUDY_CLASS_CONST_LONG(const_name, value) \
zend_declare_class_constant_long(judy_ce, const_name, sizeof(const_name)-1, (long) value TSRMLS_CC);
Please sign in to comment.
Something went wrong with that request. Please try again.