Skip to content

Commit 336aa67

Browse files
committed
Switch to namespaced Assoc/List \unique functions
1 parent c9e6b9b commit 336aa67

13 files changed

+371
-80
lines changed

Diff for: bench.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ function generate_values(int $n) {
99
return $values;
1010
}
1111

12-
function bench_array_unique_identical(int $n, int $iterations) {
12+
function bench_assoc_unique_identical(int $n, int $iterations) {
1313
$values = generate_values($n);
1414
$start = hrtime(true);
1515
$sum = 0;
1616
for ($i = 0; $i < $iterations; $i++) {
17-
$sum += array_sum(array_unique($values, ARRAY_UNIQUE_IDENTICAL));
17+
$sum += array_sum(Assoc\unique($values));
1818
}
1919
$end = hrtime(true);
2020
printf("%30s n=%8d iterations=%8d time=%.3f sum=%d\n", __FUNCTION__, $n, $iterations, ($end - $start)/1e9, $sum);
@@ -31,5 +31,5 @@ function bench_array_unique_identical(int $n, int $iterations) {
3131
];
3232

3333
foreach ($sizes as [$n, $iterations]) {
34-
bench_array_unique_identical($n, $iterations);
34+
bench_assoc_unique_identical($n, $iterations);
3535
}

Diff for: ext/standard/array.c

+62-37
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#include "zend_exceptions.h"
4343
#include "ext/spl/spl_array.h"
4444
#include "ext/random/php_random.h"
45-
#include "Zend/zend_strictmap.h"
45+
#include "zend_strictmap.h"
4646

4747
/* {{{ defines */
4848

@@ -4560,42 +4560,6 @@ PHP_FUNCTION(array_unique)
45604560
return;
45614561
}
45624562

4563-
if (sort_type == PHP_ARRAY_UNIQUE_IDENTICAL) {
4564-
zend_long num_key;
4565-
zend_string *str_key;
4566-
zval *val;
4567-
zend_strictmap seen;
4568-
4569-
zend_strictmap_init(&seen);
4570-
4571-
array_init(return_value);
4572-
4573-
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, str_key, val) {
4574-
zval dummy;
4575-
ZVAL_TRUE(&dummy);
4576-
zval *val_deref = val;
4577-
ZVAL_DEREF(val_deref);
4578-
bool added = zend_strictmap_insert(&seen, val_deref, &dummy);
4579-
4580-
if (added) {
4581-
/* First occurrence of the value */
4582-
if (UNEXPECTED(Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1)) {
4583-
ZVAL_DEREF(val);
4584-
}
4585-
Z_TRY_ADDREF_P(val);
4586-
4587-
if (str_key) {
4588-
zend_hash_add_new(Z_ARRVAL_P(return_value), str_key, val);
4589-
} else {
4590-
zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, val);
4591-
}
4592-
}
4593-
} ZEND_HASH_FOREACH_END();
4594-
4595-
zend_strictmap_dtor(&seen);
4596-
return;
4597-
}
4598-
45994563
cmp = php_get_data_compare_func_unstable(sort_type, 0);
46004564

46014565
RETVAL_ARR(zend_array_dup(Z_ARRVAL_P(array)));
@@ -6492,3 +6456,64 @@ PHP_FUNCTION(array_combine)
64926456
} ZEND_HASH_FOREACH_END();
64936457
}
64946458
/* }}} */
6459+
6460+
static zend_always_inline void list_assoc_unique(INTERNAL_FUNCTION_PARAMETERS, bool preserve_keys)
6461+
{
6462+
zval *array;
6463+
6464+
ZEND_PARSE_PARAMETERS_START(1, 1)
6465+
Z_PARAM_ARRAY(array)
6466+
ZEND_PARSE_PARAMETERS_END();
6467+
6468+
if (Z_ARRVAL_P(array)->nNumOfElements <= 1) {
6469+
ZVAL_COPY(return_value, array);
6470+
return;
6471+
}
6472+
6473+
zend_long num_key;
6474+
zend_string *str_key;
6475+
zval *val;
6476+
zend_strictmap seen;
6477+
6478+
zend_strictmap_init(&seen);
6479+
6480+
array_init(return_value);
6481+
6482+
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, str_key, val) {
6483+
zval dummy;
6484+
ZVAL_TRUE(&dummy);
6485+
zval *val_deref = val;
6486+
ZVAL_DEREF(val_deref);
6487+
bool added = zend_strictmap_insert(&seen, val_deref, &dummy);
6488+
6489+
if (added) {
6490+
/* First occurrence of the value */
6491+
if (UNEXPECTED(Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1)) {
6492+
ZVAL_DEREF(val);
6493+
}
6494+
Z_TRY_ADDREF_P(val);
6495+
6496+
if (preserve_keys) {
6497+
if (str_key) {
6498+
zend_hash_add_new(Z_ARRVAL_P(return_value), str_key, val);
6499+
} else {
6500+
zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, val);
6501+
}
6502+
} else {
6503+
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), val);
6504+
}
6505+
}
6506+
} ZEND_HASH_FOREACH_END();
6507+
6508+
zend_strictmap_dtor(&seen);
6509+
}
6510+
6511+
ZEND_FUNCTION(List_unique)
6512+
{
6513+
list_assoc_unique(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* preserve_keys */ false);
6514+
}
6515+
6516+
ZEND_FUNCTION(Assoc_unique)
6517+
{
6518+
list_assoc_unique(INTERNAL_FUNCTION_PARAM_PASSTHRU, /* preserve_keys */ true);
6519+
}

Diff for: ext/standard/basic_functions.stub.php

+18-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
/** @generate-class-entries */
44

5+
namespace {
6+
57
/* array.c */
68

79
/**
@@ -87,11 +89,6 @@
8789
*/
8890
const SORT_FLAG_CASE = UNKNOWN;
8991

90-
/**
91-
* @var int
92-
* @cvalue PHP_ARRAY_UNIQUE_IDENTICAL
93-
*/
94-
const ARRAY_UNIQUE_IDENTICAL = UNKNOWN;
9592

9693
/**
9794
* @var int
@@ -3536,3 +3533,19 @@ function sapi_windows_set_ctrl_handler(?callable $handler, bool $add = true): bo
35363533

35373534
function sapi_windows_generate_ctrl_event(int $event, int $pid = 0): bool {}
35383535
#endif
3536+
3537+
}
3538+
3539+
namespace List {
3540+
/**
3541+
* @compile-time-eval
3542+
*/
3543+
function unique(array $array): array {}
3544+
}
3545+
3546+
namespace Assoc {
3547+
/**
3548+
* @compile-time-eval
3549+
*/
3550+
function unique(array $array): array {}
3551+
}

Diff for: ext/standard/basic_functions_arginfo.h

+9-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: ext/standard/php_array.h

-4
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,8 @@ PHPAPI bool php_array_pick_keys(const php_random_algo *algo, php_random_status *
5454
#define PHP_SORT_ASC 4
5555
#define PHP_SORT_LOCALE_STRING 5
5656
#define PHP_SORT_NATURAL 6
57-
//#define PHP_DONT_USE 7
5857
#define PHP_SORT_FLAG_CASE 8
5958

60-
// Must not clash with the PHP_SORT_ flags
61-
#define PHP_ARRAY_UNIQUE_IDENTICAL 7
62-
6359
#define PHP_COUNT_NORMAL 0
6460
#define PHP_COUNT_RECURSIVE 1
6561

Diff for: ext/standard/tests/array/array_unique_identical.phpt renamed to ext/standard/tests/array/assoc_unique.phpt

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
--TEST--
2-
Test array_unique() with ARRAY_UNIQUE_IDENTICAL
2+
Test Assoc\unique()
33
--FILE--
44
<?php
55

6-
var_dump(array_unique(['1234', '1234'], ARRAY_UNIQUE_IDENTICAL));
7-
var_dump(array_unique(['1234', 1234, 1234.0, '1234', 1234, 1234.0], ARRAY_UNIQUE_IDENTICAL));
8-
var_dump(array_unique([0, '0', 0.0, '0.0', '', null, null], ARRAY_UNIQUE_IDENTICAL));
6+
var_dump(Assoc\unique(['1234', '1234']));
7+
var_dump(Assoc\unique(['1234', 1234, 1234.0, '1234', 1234, 1234.0]));
8+
var_dump(Assoc\unique([0, '0', 0.0, '0.0', '', null, null]));
99

1010
$a = (object)[];
1111
$b = (object)[];
1212
$a2 = [$a];
1313
$b2 = [$b];
1414
$a3 = (object)['foo' => $a];
1515
$b3 = (object)['foo' => $b];
16-
var_dump(array_unique([$a, $b, $a2, $b2, $a3, $b3], ARRAY_UNIQUE_IDENTICAL));
16+
var_dump(Assoc\unique([$a, $b, $a2, $b2, $a3, $b3]));
1717

1818
?>
1919
--EXPECT--

Diff for: ext/standard/tests/array/array_unique_identical_enums.phpt renamed to ext/standard/tests/array/assoc_unique_enums.phpt

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
array_unique() with ARRAY_UNIQUE_IDENTICAL and enums
2+
Assoc\unique() and enums
33
--FILE--
44
<?php
55

@@ -11,43 +11,43 @@ enum Foo {
1111
$bar = Foo::Bar;
1212
$bar2 = Foo::Bar;
1313

14-
var_dump(array_unique([
14+
var_dump(Assoc\unique([
1515
Foo::Bar,
1616
Foo::Baz,
1717
Foo::Baz,
1818
Foo::Bar,
19-
], ARRAY_UNIQUE_IDENTICAL));
19+
]));
2020

21-
var_dump(array_unique([
21+
var_dump(Assoc\unique([
2222
Foo::Bar,
2323
Foo::Bar,
2424
Foo::Baz,
25-
], ARRAY_UNIQUE_IDENTICAL));
25+
]));
2626

27-
var_dump(array_unique([
27+
var_dump(Assoc\unique([
2828
'a' => Foo::Bar,
2929
'b' => Foo::Baz,
3030
'c' => Foo::Bar,
31-
], ARRAY_UNIQUE_IDENTICAL));
31+
]));
3232

33-
var_dump(array_unique([
33+
var_dump(Assoc\unique([
3434
&$bar,
3535
Foo::Bar,
3636
&$bar2,
3737
Foo::Baz,
38-
], ARRAY_UNIQUE_IDENTICAL));
38+
]));
3939

4040
$value2 = "hello";
4141
$value3 = 0;
4242
$value4 = &$value2;
43-
var_dump(array_unique([
43+
var_dump(Assoc\unique([
4444
0,
4545
&$value4,
4646
&$value2,
4747
"hello",
4848
&$value3,
4949
$value4
50-
], ARRAY_UNIQUE_IDENTICAL));
50+
]));
5151

5252
?>
5353
--EXPECT--

Diff for: ext/standard/tests/array/array_unique_identical_nan.phpt renamed to ext/standard/tests/array/assoc_unique_nan.phpt

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
--TEST--
2-
array_unique() with ARRAY_UNIQUE_IDENTICAL preserves NAN
2+
Assoc\unique() preserves NAN
33
--FILE--
44
<?php
55

6-
var_dump(array_unique([
6+
var_dump(Assoc\unique([
77
NAN,
88
NAN,
9-
], ARRAY_UNIQUE_IDENTICAL));
9+
]));
1010

11-
var_dump(array_unique([
11+
var_dump(Assoc\unique([
1212
'foo' => NAN,
1313
'bar' => NAN,
14-
], ARRAY_UNIQUE_IDENTICAL));
14+
]));
1515

16-
var_dump(array_unique([
16+
var_dump(Assoc\unique([
1717
[NAN],
1818
1.0,
1919
[NAN],
20-
], ARRAY_UNIQUE_IDENTICAL));
20+
]));
2121

22-
var_dump(array_unique([
22+
var_dump(Assoc\unique([
2323
1.0,
2424
NAN,
2525
1.0,
2626
NAN,
2727
1.0,
28-
], ARRAY_UNIQUE_IDENTICAL));
28+
]));
2929

30-
var_dump(array_unique([
30+
var_dump(Assoc\unique([
3131
1.0,
3232
NAN,
3333
1.0,
34-
], ARRAY_UNIQUE_IDENTICAL));
34+
]));
3535

3636
?>
3737
--EXPECT--

Diff for: ext/standard/tests/array/array_unique_identical_recursion.phpt renamed to ext/standard/tests/array/assoc_unique_recursion.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
--TEST--
2-
Test array_unique() with ARRAY_UNIQUE_IDENTICAL and recursion
2+
Test Assoc\unique() and recursion
33
--FILE--
44
<?php
55

66
$a = [];
77
$b = [&$a];
88
$a[0] = &$b;
9-
array_unique([$a, $b], ARRAY_UNIQUE_IDENTICAL);
9+
Assoc\unique([$a, $b]);
1010

1111
?>
1212
--EXPECTF--

0 commit comments

Comments
 (0)