Refactor code. Fix test.

This commit is contained in:
CismonX 2018-09-15 22:34:25 +08:00
parent db57bc126d
commit e2b2fc0150
2 changed files with 11 additions and 19 deletions

View File

@ -25,13 +25,8 @@
#define PAIR_FIRST(obj) OBJ_PROP_NUM(obj, 0) #define PAIR_FIRST(obj) OBJ_PROP_NUM(obj, 0)
#define PAIR_SECOND(obj) OBJ_PROP_NUM(obj, 1) #define PAIR_SECOND(obj) OBJ_PROP_NUM(obj, 1)
#define REMOVE_DUPLICATE (1 << 0) #define IS_COLLECTION(val) \
#define RETAIN_DUPLICATE (0 << 0) Z_TYPE(val) == IS_OBJECT && Z_OBJCE(val) == collections_collection_ce
#define ELEMENT_SUBTRACT (1 << 1)
#define ELEMENT_INTERSECT (0 << 1)
#define IS_COLLECTION_P(val) \
Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val) == collections_collection_ce
#define IS_PAIR(val) \ #define IS_PAIR(val) \
Z_TYPE(val) == IS_OBJECT && Z_OBJCE(val) == collections_pair_ce Z_TYPE(val) == IS_OBJECT && Z_OBJCE(val) == collections_pair_ce
@ -81,7 +76,7 @@
#define ELEMENTS_VALIDATE(elements, err, err_then) \ #define ELEMENTS_VALIDATE(elements, err, err_then) \
zend_array* elements##_arr; \ zend_array* elements##_arr; \
if (IS_COLLECTION_P(elements)) { \ if (IS_COLLECTION(*elements)) { \
(elements##_arr) = Z_COLLECTION_P(elements); \ (elements##_arr) = Z_COLLECTION_P(elements); \
} else if (UNEXPECTED(Z_TYPE_P(elements) == IS_ARRAY)) { \ } else if (UNEXPECTED(Z_TYPE_P(elements) == IS_ARRAY)) { \
(elements##_arr) = Z_ARRVAL_P(elements); \ (elements##_arr) = Z_ARRVAL_P(elements); \
@ -511,9 +506,8 @@ static zend_always_inline void array_distinct(zend_array* ht, Bucket* ref, compa
} }
} }
static zend_always_inline uint32_t advance_idx(zend_array* ht, Bucket* ref, static zend_always_inline uint32_t advance_idx(zend_array* ht, Bucket* ref, uint32_t offset,
uint32_t offset, uint32_t max_offset, equal_check_func_t eql, uint32_t max_offset, equal_check_func_t eql, zend_bool del_dup, zend_bool packed)
zend_bool del_dup, zend_bool packed)
{ {
for (++offset; offset < max_offset; ++offset) { for (++offset; offset < max_offset; ++offset) {
if (!eql(&ref[offset].val, &ref[offset - 1].val)) { if (!eql(&ref[offset].val, &ref[offset - 1].val)) {
@ -545,15 +539,13 @@ static zend_always_inline void tail_cleanup(zend_array* ht,
} }
static zend_always_inline void array_slice_by(zend_array* ht, zend_array* other, static zend_always_inline void array_slice_by(zend_array* ht, zend_array* other,
zend_long flags) zend_bool del_dup, zend_bool subtract)
{ {
zend_bool packed = HT_IS_PACKED(ht); zend_bool packed = HT_IS_PACKED(ht);
uint32_t num_this = zend_hash_num_elements(ht); uint32_t num_this = zend_hash_num_elements(ht);
if (UNEXPECTED(num_this == 0)) { if (UNEXPECTED(num_this == 0)) {
return; return;
} }
zend_bool del_dup = flags & REMOVE_DUPLICATE;
zend_bool subtract = flags & ELEMENT_SUBTRACT;
uint32_t num_other = zend_hash_num_elements(other); uint32_t num_other = zend_hash_num_elements(other);
if (UNEXPECTED(num_other == 0)) { if (UNEXPECTED(num_other == 0)) {
if (!subtract) { if (!subtract) {
@ -1999,7 +1991,7 @@ PHP_METHOD(Collection, intersectValues)
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
zend_array* current = THIS_COLLECTION; zend_array* current = THIS_COLLECTION;
ARRAY_CLONE(intersected, current); ARRAY_CLONE(intersected, current);
array_slice_by(intersected, elements_arr, REMOVE_DUPLICATE | ELEMENT_INTERSECT); array_slice_by(intersected, elements_arr, 1, 0);
RETVAL_NEW_COLLECTION(intersected); RETVAL_NEW_COLLECTION(intersected);
} }
@ -2520,7 +2512,7 @@ PHP_METHOD(Collection, removeAll)
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
zend_array* current = THIS_COLLECTION; zend_array* current = THIS_COLLECTION;
SEPARATE_CURRENT_COLLECTION(current); SEPARATE_CURRENT_COLLECTION(current);
array_slice_by(current, elements_arr, RETAIN_DUPLICATE | ELEMENT_SUBTRACT); array_slice_by(current, elements_arr, 0, 1);
} }
PHP_METHOD(Collection, removeWhile) PHP_METHOD(Collection, removeWhile)
@ -2552,7 +2544,7 @@ PHP_METHOD(Collection, retainAll)
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
zend_array* current = THIS_COLLECTION; zend_array* current = THIS_COLLECTION;
SEPARATE_CURRENT_COLLECTION(current); SEPARATE_CURRENT_COLLECTION(current);
array_slice_by(current, elements_arr, RETAIN_DUPLICATE | ELEMENT_INTERSECT); array_slice_by(current, elements_arr, 0, 0);
} }
PHP_METHOD(Collection, retainWhile) PHP_METHOD(Collection, retainWhile)
@ -2998,7 +2990,7 @@ PHP_METHOD(Collection, subtract)
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return); ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
zend_array* current = THIS_COLLECTION; zend_array* current = THIS_COLLECTION;
ARRAY_CLONE(subtracted, current); ARRAY_CLONE(subtracted, current);
array_slice_by(subtracted, elements_arr, REMOVE_DUPLICATE | ELEMENT_SUBTRACT); array_slice_by(subtracted, elements_arr, 1, 1);
RETVAL_NEW_COLLECTION(subtracted); RETVAL_NEW_COLLECTION(subtracted);
} }

View File

@ -12,7 +12,7 @@ sort($array);
$idx = mt_rand(0, count($array) - 1); $idx = mt_rand(0, count($array) - 1);
$which = $array[$idx]; $which = $array[$idx];
$from = mt_rand(0, $idx); $from = mt_rand(0, $idx);
$to = mt_rand($idx, count($array)); $to = mt_rand($idx + 1, count($array));
$collection = Collection::init($array); $collection = Collection::init($array);
if ($collection->binarySearch($which, 0, $from, $to) != $idx) { if ($collection->binarySearch($which, 0, $from, $to) != $idx) {
echo 'Collection::binarySearch() failed.', PHP_EOL; echo 'Collection::binarySearch() failed.', PHP_EOL;