Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:11411 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 64828 invoked by uid 1010); 21 Jul 2004 07:39:14 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 64746 invoked from network); 21 Jul 2004 07:39:14 -0000 Received: from unknown (HELO iko.gotobg.net) (80.168.8.116) by pb1.pair.com with SMTP; 21 Jul 2004 07:39:14 -0000 Received: from pd95e98cf.dip.t-dialin.net ([217.94.152.207] helo=[192.168.0.32]) by iko.gotobg.net with asmtp (Exim 4.34) id 1BnBh4-0006zZ-QX; Wed, 21 Jul 2004 10:39:15 +0300 Message-ID: <40FE3918.1000804@hristov.com> Date: Wed, 21 Jul 2004 09:36:24 +0000 User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8a2) Gecko/20040627 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Cristiano Duarte CC: internals@lists.php.net References: <20040720192358.26985.qmail@pb1.pair.com> In-Reply-To: <20040720192358.26985.qmail@pb1.pair.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - iko.gotobg.net X-AntiAbuse: Original Domain - lists.php.net X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - hristov.com X-Source: X-Source-Args: X-Source-Dir: Subject: Re: [PHP-DEV] array_intersect_key From: php@hristov.com (Andrey Hristov) 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); >