is "make test" showing problems? (i am just currious).
I will try to review the patch later today (atm i am sick).

andrey

Cristiano Duarte wrote:
Hi all,

I needed to intersect an array with database records indexed by the primary
key, with an array with keys and there is no php function that will do it
internally. The database array looks like:
$records = array ( 2587 => array('Name', 'Address', 'zip'), ...);


And the array with PKS:
$pks = array_flip(array ( 234, 897, 2587, 6788));

And the intersection would be:
$result = array_intersect_key($records, $pks);

This last action should be done 10.000 times or more, so a pure PHP
implementation takes too long, then I made the following patch to PHP-5.0.0
and PHP-4.3.8 that implements the intersection only comparing the array
keys.


If someone would like to commit it, maybe it would be useful to other users.

Regards,

Cristiano Duarte


***********************Patch for PHP 5.0.0


--- array.c 2004-07-11 18:15:04.000000000 -0300
+++ /home/aluno/php-5.0.0-new/ext/standard/array.c 2004-07-20
13:58:47.000000000 -0300
@@ -84,6 +84,7 @@
#define INTERSECT_NORMAL 0
#define INTERSECT_ASSOC 1
+#define INTERSECT_KEY 2
#define INTERSECT_COMP_DATA_INTERNAL 0
#define INTERSECT_COMP_DATA_USER 1
#define INTERSECT_COMP_KEY_INTERNAL 0
@@ -2797,7 +2798,8 @@
php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d.
This should never happen. Please report as a bug", data_compare_type);
return;
}
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if ((behavior == INTERSECT_ASSOC)
+ ||(behavior == INTERSECT_KEY)) {
intersect_key_compare_func = array_key_compare;
if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL
&&
@@ -2910,7 +2912,7 @@
*list = NULL;
if (behavior == INTERSECT_NORMAL) {
zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
intersect_data_compare_func TSRMLS_CC);
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY))
{
zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
intersect_key_compare_func TSRMLS_CC);
}
}
@@ -2926,7 +2928,8 @@
/* go through the lists and look for common values */
while (*ptrs[0]) {
- if (behavior == INTERSECT_ASSOC
+ if ((behavior == INTERSECT_ASSOC
+ || behavior == INTERSECT_KEY)
&&
key_compare_type == INTERSECT_COMP_KEY_USER) {
@@ -2938,11 +2941,11 @@
while (*ptrs[i] && (0 < (c = intersect_data_compare_func(ptrs[0],
ptrs[i] TSRMLS_CC)))) {
ptrs[i]++;
}
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
while (*ptrs[i] && (0 < (c = intersect_key_compare_func(ptrs[0],
ptrs[i] TSRMLS_CC)))) {
ptrs[i]++;
}
- if (!c && *ptrs[i]) { /* this means that ptrs[i] is not NULL so we can
compare */
+ if ((!c && *ptrs[i]) && (behavior == INTERSECT_ASSOC)) { /* this means
that ptrs[i] is not NULL so we can compare */
/* and "c==0" is from last operation */
if (data_compare_type == INTERSECT_COMP_DATA_USER) {
BG(user_compare_func_name) = args[arr_argc];
@@ -2996,7 +2999,7 @@
if (0 <= intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)) {
break;
}
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
/* no need of looping because indexes are unique */
break;
}
@@ -3012,7 +3015,7 @@
if (intersect_data_compare_func(ptrs[0]-1, ptrs[0] TSRMLS_CC)) {
break;
}
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if (behavior == INTERSECT_ASSOC || behavior == INTERSECT_KEY) {
/* no need of looping because indexes are unique */
break;
}
@@ -3053,6 +3056,25 @@
/* {{{ proto array array_intersect_assoc(array arr1, array arr2 [,
array ...])
Returns the entries of arr1 that have values which are present in all
the other arguments. Keys are used to do more restrictive check */
+PHP_FUNCTION(array_intersect_key)
+{
+ php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
+ INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_INTERNAL);
+}
+/* }}} */
+
+
+/* {{{ proto array array_uintersect_assoc(array arr1, array arr2 [,
array ...], callback data_compare_func)
+ Returns the entries of arr1 that have values which are present in all
the other arguments. Keys are used to do more restrictive check. Data is
compared by using an user-supplied callback. */
+PHP_FUNCTION(array_uintersect_key)
+{
+ php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY,
+ INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_USER);
+}
+/* }}} */
+
+/* {{{ proto array array_intersect_assoc(array arr1, array arr2 [,
array ...])
+ Returns the entries of arr1 that have values which are present in all
the other arguments. Keys are used to do more restrictive check */
PHP_FUNCTION(array_intersect_assoc)
{
php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_ASSOC,
--- basic_functions.c 2004-06-27 18:49:47.000000000 -0300
+++ /home/aluno/php-5.0.0-new/ext/standard/basic_functions.c 2004-07-20
14:15:00.000000000 -0300
@@ -780,6 +780,8 @@
PHP_FE(array_unique, NULL)
PHP_FE(array_intersect, NULL)
PHP_FE(array_uintersect, NULL)
+ PHP_FE(array_intersect_key, NULL)
+ PHP_FE(array_uintersect_key, NULL)
PHP_FE(array_intersect_assoc, NULL)
PHP_FE(array_uintersect_assoc, NULL)
PHP_FE(array_intersect_uassoc, NULL)
--- php_array.h 2004-01-08 15:32:51.000000000 -0200
+++ /home/aluno/php-5.0.0-new/ext/standard/php_array.h 2004-07-20
14:15:21.000000000 -0300
@@ -77,6 +77,8 @@
PHP_FUNCTION(array_unique);
PHP_FUNCTION(array_intersect);
PHP_FUNCTION(array_uintersect);
+PHP_FUNCTION(array_intersect_key);
+PHP_FUNCTION(array_uintersect_key);
PHP_FUNCTION(array_intersect_assoc);
PHP_FUNCTION(array_uintersect_assoc);
PHP_FUNCTION(array_intersect_uassoc);



***********************Patch for PHP 4.3.8

--- array.c 2004-04-01 16:07:01.000000000 -0300
+++ /home/aluno/php-4.3.8-new/ext/standard/array.c 2004-07-20
14:06:48.000000000 -0300
@@ -81,6 +81,7 @@
#define INTERSECT_NORMAL 0
#define INTERSECT_ASSOC 1
+#define INTERSECT_KEY 2
PHP_MINIT_FUNCTION(array)
{
@@ -2579,7 +2580,7 @@
*list = NULL;
if (behavior == INTERSECT_NORMAL) {
zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
array_data_compare TSRMLS_CC);
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if ((behavior == INTERSECT_ASSOC) || (behavior == INTERSECT_KEY))
{
zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *),
array_key_compare TSRMLS_CC);
}
}
@@ -2594,17 +2595,20 @@
if (behavior == INTERSECT_NORMAL) {
while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i]
TSRMLS_CC))))
ptrs[i]++;
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if ((behavior == INTERSECT_ASSOC)
+ || (behavior == INTERSECT_KEY)) {
while (*ptrs[i] && (0 < (c = array_key_compare(ptrs[0], ptrs[i]
TSRMLS_CC))))
ptrs[i]++;
- if (!c && *ptrs[i]) { /* this means that ptrs[i] is not NULL so we can
compare */
- /* and "c==0" is from last operation */
- if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
- c = 1;
- /* we are going to the break */
- } else {
- /* continue looping */
- }
+ if (behavior == INTERSECT_ASSOC) {
+ if (!c && *ptrs[i]) { /* this means that ptrs[i] is not NULL so we can
compare */
+ /* and "c==0" is from last operation */
+ if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
+ c = 1;
+ /* we are going to the break */
+ } else {
+ /* continue looping */
+ }
+ }
}
}
if (!*ptrs[i]) {
@@ -2639,7 +2643,8 @@
if (behavior == INTERSECT_NORMAL) {
if (0 <= array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC))
break;
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if ((behavior == INTERSECT_ASSOC)
+ || (behavior == INTERSECT_KEY)) {
/* no need of looping because indexes are unique */
break;
}
@@ -2653,7 +2658,8 @@
if (behavior == INTERSECT_NORMAL) {
if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
break;
- } else if (behavior == INTERSECT_ASSOC) {
+ } else if ((behavior == INTERSECT_ASSOC)
+ || (behavior == INTERSECT_KEY)) {
/* no need of looping because indexes are unique */
break;
}
@@ -2688,6 +2694,15 @@
/* }}} */
+/* {{{ proto array array_intersect_key(array arr1, array arr2 [,
array ...])
+ Returns the entries of arr1 that have keys which are present in all the
other arguments. */
+PHP_FUNCTION(array_intersect_key)
+{
+ php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU,
INTERSECT_KEY);
+}
+/* }}} */
+
+
static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior)
{
zval ***args = NULL;
--- basic_functions.c 2004-05-24 14:02:31.000000000 -0300
+++ /home/aluno/php-4.3.8-new/ext/standard/basic_functions.c 2004-07-20
14:11:50.000000000 -0300
@@ -838,6 +838,7 @@
PHP_FE(array_rand, NULL)
PHP_FE(array_unique, NULL)
PHP_FE(array_intersect, NULL)
+ PHP_FE(array_intersect_key, NULL)
PHP_FE(array_intersect_assoc, NULL)
PHP_FE(array_diff, NULL)
PHP_FE(array_diff_assoc, NULL)
--- php_array.h 2002-12-31 14:35:32.000000000 -0200
+++ /home/aluno/php-4.3.8-new/ext/standard/php_array.h 2004-07-20
14:04:38.000000000 -0300
@@ -75,6 +75,7 @@
PHP_FUNCTION(array_rand);
PHP_FUNCTION(array_unique);
PHP_FUNCTION(array_intersect);
+PHP_FUNCTION(array_intersect_key);
PHP_FUNCTION(array_intersect_assoc);
PHP_FUNCTION(array_diff);
PHP_FUNCTION(array_diff_assoc);



-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to