Add `maxBy()`, `minBy()`. Remove ZTS relevant code.

This commit is contained in:
CismonX 2018-05-01 17:35:19 +08:00
parent 5f200100a8
commit 283fdafd56
4 changed files with 76 additions and 28 deletions

View File

@ -46,14 +46,6 @@ PHP_MINIT_FUNCTION(collections)
return SUCCESS;
}
PHP_RINIT_FUNCTION(collections)
{
#if defined(COMPILE_DL_COLLECTIONS) && defined(ZTS)
ZEND_TSRMLS_CACHE_UPDATE();
#endif
return SUCCESS;
}
PHP_MINFO_FUNCTION(collections)
{
php_info_print_table_start();
@ -67,7 +59,7 @@ zend_module_entry collections_module_entry = {
NULL,
PHP_MINIT(collections),
NULL,
PHP_RINIT(collections),
NULL,
NULL,
PHP_MINFO(collections),
PHP_COLLECTIONS_VERSION,
@ -75,8 +67,5 @@ zend_module_entry collections_module_entry = {
};
#ifdef COMPILE_DL_COLLECTIONS
#ifdef ZTS
ZEND_TSRMLS_CACHE_DEFINE()
#endif
ZEND_GET_MODULE(collections)
#endif

View File

@ -113,6 +113,11 @@
/// Unused global variable.
zval rv;
static zend_always_inline int bucket_compare_numeric(Bucket* op1, Bucket* op2)
{
return numeric_compare_function(&op1->val, &op2->val);
}
int count_collection(zval* obj, zend_long* count)
{
zend_array* current = COLLECTION_FETCH(obj);
@ -963,15 +968,35 @@ PHP_METHOD(Collection, mapValuesTo)
PHP_METHOD(Collection, max)
{
zend_array* current = COLLECTION_FETCH_CURRENT();
zval* retval = zend_hash_minmax(current, numeric_compare_function, 1);
if (retval)
RETURN_ZVAL(retval, 0, 0);
zval* max = zend_hash_minmax(current, bucket_compare_numeric, 1);
if (max)
RETURN_ZVAL(max, 0, 0);
RETVAL_NULL();
}
PHP_METHOD(Collection, maxBy)
{
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
zend_array* current = COLLECTION_FETCH_CURRENT();
ARRAY_NEW_EX(max_by, current);
INIT_FCI(2);
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
CALLBACK_KEYVAL_INVOKE(params, bucket);
zend_hash_index_add(max_by, bucket - current->arData, &retval);
ZEND_HASH_FOREACH_END();
zval* max = zend_hash_minmax(max_by, bucket_compare_numeric, 1);
if (max) {
zend_ulong offset = *(zend_ulong*)(max + 1);
zval* ret = &(current->arData + offset)->val;
RETVAL_ZVAL(ret, 1, 0);
} else
RETVAL_NULL();
zend_hash_destroy(max_by);
efree(max_by);
}
PHP_METHOD(Collection, maxWith)
@ -982,15 +1007,35 @@ PHP_METHOD(Collection, maxWith)
PHP_METHOD(Collection, min)
{
zend_array* current = COLLECTION_FETCH_CURRENT();
zval* retval = zend_hash_minmax(current, numeric_compare_function, 0);
if (retval)
RETURN_ZVAL(retval, 0, 0);
zval* min = zend_hash_minmax(current, bucket_compare_numeric, 0);
if (min)
RETURN_ZVAL(min, 0, 0);
RETVAL_NULL();
}
PHP_METHOD(Collection, minBy)
{
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
zend_array* current = COLLECTION_FETCH_CURRENT();
ARRAY_NEW_EX(min_by, current);
INIT_FCI(2);
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
CALLBACK_KEYVAL_INVOKE(params, bucket);
zend_hash_index_add(min_by, bucket - current->arData, &retval);
ZEND_HASH_FOREACH_END();
zval* min = zend_hash_minmax(min_by, bucket_compare_numeric, 0);
if (max) {
zend_ulong offset = *(zend_ulong*)(min + 1);
zval* ret = &(current->arData + offset)->val;
RETVAL_ZVAL(ret, 1, 0);
} else
RETVAL_NULL();
zend_hash_destroy(min_by);
efree(min_by);
}
PHP_METHOD(Collection, minWith)

View File

@ -39,12 +39,4 @@ void collection_offset_unset(zval* object, zval* offset);
extern const zend_function_entry collection_methods[];
extern const zend_function_entry pair_methods[];
#ifdef ZTS
#include "TSRM.h"
#endif
#if defined(ZTS) && defined(COMPILE_DL_COLLECTIONS)
ZEND_TSRMLS_CACHE_EXTERN()
#endif
#endif // !PHP_COLLECTIONS_FE_H

22
tests/028-min-max-by.phpt Normal file
View File

@ -0,0 +1,22 @@
--TEST--
Test Collection::minBy() and Collection::maxBy().
--FILE--
<?php
$array = [
[1.2, 3.1, 1.5],
[3.2, 7.6, 4.7],
[1.5, 1.4, 6.3]
];
$collection = Collection::init($array);
$result = $collection->maxBy(function ($value) {
return $value[0];
});
if ($result != $array[1])
echo 'Collection::maxBy() failed.', PHP_EOL;
$result = $collection->minBy(function ($value) {
return $value[2];
});
if ($result != $array[0])
echo 'Collection::minBy() failed.', PHP_EOL;
?>
--EXPECT--