[PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc

2008-01-28 Thread Marcus Boerger
helly   Mon Jan 28 22:43:21 2008 UTC

  Modified files:  
/php-src/ext/splspl_observer.c 
/php-src/ext/spl/internal   splobjectstorage.inc 
  Log:
  - Make SplObjectStorage implement ArrayAccess
  
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_observer.c?r1=1.22&r2=1.23&diff_format=u
Index: php-src/ext/spl/spl_observer.c
diff -u php-src/ext/spl/spl_observer.c:1.22 php-src/ext/spl/spl_observer.c:1.23
--- php-src/ext/spl/spl_observer.c:1.22 Sun Jan 27 18:04:54 2008
+++ php-src/ext/spl/spl_observer.c  Mon Jan 28 22:43:21 2008
@@ -16,7 +16,7 @@
+--+
  */
 
-/* $Id: spl_observer.c,v 1.22 2008/01/27 18:04:54 helly Exp $ */
+/* $Id: spl_observer.c,v 1.23 2008/01/28 22:43:21 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -288,6 +288,25 @@
intern->index = 0;
 } /* }}} */
 
+/* {{{ proto mixed SplObjectStorage::offsetGet($object) U
+ Returns associated information for a stored object */
+SPL_METHOD(SplObjectStorage, offsetGet)
+{
+   zval *obj;
+   spl_SplObjectStorageElement *element;
+   spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+   
+   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == 
FAILURE) {
+   return;
+   }
+   element = spl_object_storage_get(intern, obj TSRMLS_CC);
+   if (!element) {
+   zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC, "Object not found");
+   } else {
+   RETURN_ZVAL(element->inf,1, 0);
+   }
+} /* }}} */
+
 /* {{{ proto bool SplObjectStorage::contains($obj) U
  Determine whethe an object is contained in the storage */
 SPL_METHOD(SplObjectStorage, contains)
@@ -565,20 +584,39 @@
ZEND_ARG_INFO(0, info)
 ZEND_END_ARG_INFO();
 
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1)
+   ZEND_ARG_INFO(0, object)
+ZEND_END_ARG_INFO()
+
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2)
+   ZEND_ARG_INFO(0, object)
+   ZEND_ARG_INFO(0, info)
+ZEND_END_ARG_INFO()
+
 static const zend_function_entry spl_funcs_SplObjectStorage[] = {
SPL_ME(SplObjectStorage,  attach,  arginfo_attach,0)
SPL_ME(SplObjectStorage,  detach,  arginfo_Object,0)
SPL_ME(SplObjectStorage,  contains,arginfo_Object,0)
+   SPL_ME(SplObjectStorage,  getInfo, NULL,  0)
+   SPL_ME(SplObjectStorage,  setInfo, arginfo_setInfo,   0)
+   /* Countable */
SPL_ME(SplObjectStorage,  count,   NULL,  0)
+   /* Iterator */
SPL_ME(SplObjectStorage,  rewind,  NULL,  0)
SPL_ME(SplObjectStorage,  valid,   NULL,  0)
SPL_ME(SplObjectStorage,  key, NULL,  0)
SPL_ME(SplObjectStorage,  current, NULL,  0)
SPL_ME(SplObjectStorage,  next,NULL,  0)
+   /* Serializable */
SPL_ME(SplObjectStorage,  unserialize, arginfo_Serialized,0)
SPL_ME(SplObjectStorage,  serialize,   NULL,  0)
-   SPL_ME(SplObjectStorage,  getInfo, NULL,  0)
-   SPL_ME(SplObjectStorage,  setInfo, arginfo_setInfo,   0)
+   /* ArrayAccess */
+   SPL_MA(SplObjectStorage, offsetExists, SplObjectStorage, contains, 
arginfo_offsetGet, 0)
+   SPL_MA(SplObjectStorage, offsetSet,SplObjectStorage, attach,   
arginfo_offsetSet, 0)
+   SPL_MA(SplObjectStorage, offsetUnset,  SplObjectStorage, detach,   
arginfo_offsetGet, 0)
+   SPL_ME(SplObjectStorage, offsetGet,arginfo_offsetGet, 0)
{NULL, NULL, NULL}
 };
 
@@ -595,6 +633,7 @@
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable);
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator);
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Serializable);
+   REGISTER_SPL_IMPLEMENTS(SplObjectStorage, ArrayAccess);
 
return SUCCESS;
 }
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/internal/splobjectstorage.inc?r1=1.5&r2=1.6&diff_format=u
Index: php-src/ext/spl/internal/splobjectstorage.inc
diff -u php-src/ext/spl/internal/splobjectstorage.inc:1.5 
php-src/ext/spl/internal/splobjectstorage.inc:1.6
--- php-src/ext/spl/internal/splobjectstorage.inc:1.5   Sun Jan 27 18:04:54 2008
+++ php-src/ext/spl/internal/splobjectstorage.inc   Mon Jan 28 22:43:21 2008
@@ -20,7 +20,7 @@
  * here therefore has a complexity of O(n) while the actual implementation has
  * complexity O(1).
  */
-class SplObjectStorage implements Iterator, Countable
+class SplObjectStorage implements Iterator, Countable, ArrayAccess
 {
private $storage = array();
private $index = 0;
@@ -88,9 +88,9 @@
return count($this->storage);
}
 
-   /** @param obj object to look for
+   /** @pa

Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Marcus Boerger
Hello Andrei,

  it would only help if the schema used is always the same so that it is
trustably unique. The following two lines achieve that:

  char *key;
  spprintf(&key, 0, "%s::%d", Z_OBJCE_P(obj)->name, obj->value.obj.handle);

Yep would help in a few edge cases and allow O(1) implementation of
ObjectStorage.

regards
marcus

Thursday, August 11, 2005, 1:30:14 AM, you wrote:

> What we really need is a get_hash_t handler on the object, so that each 
> object knows how to hash itself. This can also come in handy when using 
> objects as array keys.

> -Andrei

> On Aug 10, 2005, at 3:39 PM, Marcus Boerger wrote:

>> Hello Andrey,
>>
>>   wrong assumption. That is only the handle but only the handle+handler
>> combination is unique.
>>
>> marcus
>>
>> Thursday, August 11, 2005, 12:32:07 AM, you wrote:
>>
>>> Marcus Boerger wrote:
 Hello Andrey,

   thanks! I wanted to do it earlier but had no idea how to sole the 
 problem.
 I actually right from the beginning wanted to do all three in there. 
 Anyway
 you might also want to see t he last slides of my last presentation 
 (the one
 from OSCON) which you can find here: http://talks.somabo.de/

 best regards
 marcus

 Thursday, August 11, 2005, 12:04:37 AM, you wrote:


>   Wonderful idea Helly!


> Andrey


>>
>>> However, I think you are wrong that it cannot be implemented in user 
>>> land with O(1)
>>> complexity. The following one-liner should give you a hint why I 
>>> think it is possible.
>>
>>> [EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ 
>>> ob_start();
>>> var_dump($obj); $v=ob_get_contents();
>>> ob_end_clean();var_dump(substr($v, 7, strpos($v, "
>>> ", 11) - 7));} get_hash_key(new a);'
>>> string(4) "a)#1"
>>
>>> The string is unique per object. ) and # are noise but they are not a 
>>> problem.
>>
>>> Best wishes,
>>> Andrey
>>
>>
>>
>> Best regards,
>>  Marcus
>>
>> -- 
>> PHP CVS Mailing List (http://www.php.net/)
>> To unsubscribe, visit: http://www.php.net/unsub.php




Best regards,
 Marcus

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Andrei Zmievski
What we really need is a get_hash_t handler on the object, so that each 
object knows how to hash itself. This can also come in handy when using 
objects as array keys.


-Andrei

On Aug 10, 2005, at 3:39 PM, Marcus Boerger wrote:


Hello Andrey,

  wrong assumption. That is only the handle but only the handle+handler
combination is unique.

marcus

Thursday, August 11, 2005, 12:32:07 AM, you wrote:


Marcus Boerger wrote:

Hello Andrey,

  thanks! I wanted to do it earlier but had no idea how to sole the 
problem.
I actually right from the beginning wanted to do all three in there. 
Anyway
you might also want to see t he last slides of my last presentation 
(the one

from OSCON) which you can find here: http://talks.somabo.de/

best regards
marcus

Thursday, August 11, 2005, 12:04:37 AM, you wrote:



  Wonderful idea Helly!




Andrey





However, I think you are wrong that it cannot be implemented in user 
land with O(1)
complexity. The following one-liner should give you a hint why I 
think it is possible.


[EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ 
ob_start();

var_dump($obj); $v=ob_get_contents();
ob_end_clean();var_dump(substr($v, 7, strpos($v, "
", 11) - 7));} get_hash_key(new a);'
string(4) "a)#1"


The string is unique per object. ) and # are noise but they are not a 
problem.



Best wishes,
Andrey




Best regards,
 Marcus

--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Marcus Boerger
Hello Andrey,

  wrong assumption. That is only the handle but only the handle+handler
combination is unique.

marcus

Thursday, August 11, 2005, 12:32:07 AM, you wrote:

> Marcus Boerger wrote:
>> Hello Andrey,
>> 
>>   thanks! I wanted to do it earlier but had no idea how to sole the problem.
>> I actually right from the beginning wanted to do all three in there. Anyway
>> you might also want to see t he last slides of my last presentation (the one
>> from OSCON) which you can find here: http://talks.somabo.de/
>> 
>> best regards
>> marcus
>> 
>> Thursday, August 11, 2005, 12:04:37 AM, you wrote:
>> 
>> 
>>>   Wonderful idea Helly!
>> 
>> 
>>>Andrey
>> 
>> 

> However, I think you are wrong that it cannot be implemented in user land 
> with O(1)
> complexity. The following one-liner should give you a hint why I think it is 
> possible.

> [EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ 
> ob_start();
> var_dump($obj); $v=ob_get_contents();
> ob_end_clean();var_dump(substr($v, 7, strpos($v, " 
> ", 11) - 7));} get_hash_key(new a);'
> string(4) "a)#1"

> The string is unique per object. ) and # are noise but they are not a problem.

> Best wishes,
> Andrey



Best regards,
 Marcus

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Andrey Hristov

Marcus Boerger wrote:

Hello Andrey,

  thanks! I wanted to do it earlier but had no idea how to sole the problem.
I actually right from the beginning wanted to do all three in there. Anyway
you might also want to see t he last slides of my last presentation (the one
from OSCON) which you can find here: http://talks.somabo.de/

best regards
marcus

Thursday, August 11, 2005, 12:04:37 AM, you wrote:



  Wonderful idea Helly!




Andrey





However, I think you are wrong that it cannot be implemented in user land with 
O(1)
complexity. The following one-liner should give you a hint why I think it is 
possible.

[EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ ob_start(); 
var_dump($obj); $v=ob_get_contents(); ob_end_clean();var_dump(substr($v, 7, strpos($v, " 
", 11) - 7));} get_hash_key(new a);'

string(4) "a)#1"

The string is unique per object. ) and # are noise but they are not a problem.

Best wishes,
Andrey

--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Marcus Boerger
Hello Andrey,

  thanks! I wanted to do it earlier but had no idea how to sole the problem.
I actually right from the beginning wanted to do all three in there. Anyway
you might also want to see t he last slides of my last presentation (the one
from OSCON) which you can find here: http://talks.somabo.de/

best regards
marcus

Thursday, August 11, 2005, 12:04:37 AM, you wrote:

>Wonderful idea Helly!

> Andrey

> Marcus Boerger wrote:
>> helly Wed Aug 10 17:56:02 2005 EDT
>> 
>>   Added files: 
>> /php-src/ext/spl/internal splobjectstorage.inc 
>> /php-src/ext/spl/testsobserver_002.phpt 
>> 
>>   Modified files:  
>> /php-src/ext/spl  spl_observer.c 
>>   Log:
>>   - Implement SplObjectStorage as announced during OSCON
>>   # This class starts naming of new classes in Spl by prefix Spl as dicussed.
>>   # The class reduces object storage complexity from O(n) to O(1) which is
>>   # not possible in user space.
>>   
>>   
>> 
>> 
>> 
>> 
>> http://cvs.php.net/diff.php/php-src/ext/spl/spl_observer.c?r1=1.2&r2=1.3&ty=u
>> Index: php-src/ext/spl/spl_observer.c
>> diff -u php-src/ext/spl/spl_observer.c:1.2 php-src/ext/spl/spl_observer.c:1.3
>> --- php-src/ext/spl/spl_observer.c:1.2Wed Aug  3 10:07:53 2005
>> +++ php-src/ext/spl/spl_observer.cWed Aug 10 17:56:00 2005
>> @@ -16,7 +16,7 @@
>>
>> +--+
>>   */
>>  
>> -/* $Id: spl_observer.c,v 1.2 2005/08/03 14:07:53 sniper Exp $ */
>> +/* $Id: spl_observer.c,v 1.3 2005/08/10 21:56:00 helly Exp $ */
>>  
>>  #ifdef HAVE_CONFIG_H
>>  # include "config.h"
>> @@ -32,6 +32,8 @@
>>  #include "spl_functions.h"
>>  #include "spl_engine.h"
>>  #include "spl_observer.h"
>> +#include "spl_iterators.h"
>> +#include "spl_array.h"
>>  
>>  SPL_METHOD(Observer, update);
>>  SPL_METHOD(Subject, attach);
>> @@ -65,14 +67,197 @@
>>   {NULL, NULL, NULL}
>>  };
>>  
>> -PHPAPI zend_class_entry  *spl_ce_Observer;
>> -PHPAPI zend_class_entry  *spl_ce_Subject;
>> +PHPAPI zend_class_entry *spl_ce_Observer;
>> +PHPAPI zend_class_entry *spl_ce_Subject;
>> +PHPAPI zend_class_entry *spl_ce_SplObjectStorage;
>> +PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
>> +
>> +typedef struct _spl_SplObjectStorage {
>> + zend_object   std;
>> + HashTable storage;
>> + long  index;
>> + HashPosition  pos;
>> +} spl_SplObjectStorage;
>> +
>> +/* storage is an assoc aray of [zend_object_value]=>[zval*] */
>> +
>> +void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
>> +{
>> + spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object;
>> +
>> + zend_hash_destroy(intern->std.properties);
>> + FREE_HASHTABLE(intern->std.properties);
>> +
>> + zend_hash_destroy(&intern->storage);
>> +
>> + efree(object);
>> +} /* }}} */
>> +
>> +static zend_object_value spl_object_storage_new_ex(zend_class_entry
>> *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */
>> +{
>> + zend_object_value retval;
>> + spl_SplObjectStorage *intern;
>> + zval *tmp;
>> +
>> + intern = emalloc(sizeof(spl_SplObjectStorage));
>> + memset(intern, 0, sizeof(spl_SplObjectStorage));
>> + intern->std.ce = class_type;
>> + *obj = intern;
>> +
>> + ALLOC_HASHTABLE(intern->std.properties);
>> + zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
>> + zend_hash_copy(intern->std.properties,
>> &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void
>> *) &tmp, sizeof(zval *));
>> +
>> + zend_hash_init(&intern->storage, 0, NULL, ZVAL_PTR_DTOR, 0);
>> +
>> + retval.handle = zend_objects_store_put(intern, NULL,
>> (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage,
>> NULL TSRMLS_CC);
>> + retval.handlers = &spl_handler_SplObjectStorage;
>> + return retval;
>> +}
>> +/* }}} */
>> +
>> +/* {{{ spl_array_object_new */
>> +static zend_object_value spl_SplObjectStorage_new(zend_class_entry 
>> *class_type TSRMLS_DC)
>> +{
>> + spl_SplObjectStorage *tmp;
>> + return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC);
>> +}
>> +/* }}} */
>> +
>> +/* {{{ proto void SplObjectStorage::attach($obj)
>> + Attaches an object to the storage if not yet contained */
>> +SPL_METHOD(SplObjectStorage, attach)
>> +{
>> + zval *obj;
>> + spl_SplObjectStorage *intern =
>> (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
>> +
>> + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == 
>> FAILURE) {
>> + return;
>> + }
>> + 
>> + zend_hash_update(&intern->storage, (char*)&obj->value.obj,
>> sizeof(obj->value.obj), &obj, sizeof(zval**), NULL);
>> + obj->refcount++;
>> +} /* }}} */
>> +
>> +/* {{{ proto void SplObjectStorage::detach($obj)
>> + D

Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Andrey Hristov

  Wonderful idea Helly!

Andrey

Marcus Boerger wrote:

helly   Wed Aug 10 17:56:02 2005 EDT

  Added files: 
/php-src/ext/spl/internal	splobjectstorage.inc 
/php-src/ext/spl/tests	observer_002.phpt 

  Modified files:  
/php-src/ext/spl	spl_observer.c 
  Log:

  - Implement SplObjectStorage as announced during OSCON
  # This class starts naming of new classes in Spl by prefix Spl as dicussed.
  # The class reduces object storage complexity from O(n) to O(1) which is
  # not possible in user space.
  
  





http://cvs.php.net/diff.php/php-src/ext/spl/spl_observer.c?r1=1.2&r2=1.3&ty=u
Index: php-src/ext/spl/spl_observer.c
diff -u php-src/ext/spl/spl_observer.c:1.2 php-src/ext/spl/spl_observer.c:1.3
--- php-src/ext/spl/spl_observer.c:1.2  Wed Aug  3 10:07:53 2005
+++ php-src/ext/spl/spl_observer.c  Wed Aug 10 17:56:00 2005
@@ -16,7 +16,7 @@
+--+
  */
 
-/* $Id: spl_observer.c,v 1.2 2005/08/03 14:07:53 sniper Exp $ */

+/* $Id: spl_observer.c,v 1.3 2005/08/10 21:56:00 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H

 # include "config.h"
@@ -32,6 +32,8 @@
 #include "spl_functions.h"
 #include "spl_engine.h"
 #include "spl_observer.h"
+#include "spl_iterators.h"
+#include "spl_array.h"
 
 SPL_METHOD(Observer, update);

 SPL_METHOD(Subject, attach);
@@ -65,14 +67,197 @@
{NULL, NULL, NULL}
 };
 
-PHPAPI zend_class_entry  *spl_ce_Observer;

-PHPAPI zend_class_entry  *spl_ce_Subject;
+PHPAPI zend_class_entry *spl_ce_Observer;
+PHPAPI zend_class_entry *spl_ce_Subject;
+PHPAPI zend_class_entry *spl_ce_SplObjectStorage;
+PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
+
+typedef struct _spl_SplObjectStorage {
+   zend_object   std;
+   HashTable storage;
+   long  index;
+   HashPosition  pos;
+} spl_SplObjectStorage;
+
+/* storage is an assoc aray of [zend_object_value]=>[zval*] */
+
+void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
+{
+   spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object;
+
+   zend_hash_destroy(intern->std.properties);
+   FREE_HASHTABLE(intern->std.properties);
+
+   zend_hash_destroy(&intern->storage);
+
+   efree(object);
+} /* }}} */
+
+static zend_object_value spl_object_storage_new_ex(zend_class_entry 
*class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */
+{
+   zend_object_value retval;
+   spl_SplObjectStorage *intern;
+   zval *tmp;
+
+   intern = emalloc(sizeof(spl_SplObjectStorage));
+   memset(intern, 0, sizeof(spl_SplObjectStorage));
+   intern->std.ce = class_type;
+   *obj = intern;
+
+   ALLOC_HASHTABLE(intern->std.properties);
+   zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+   zend_hash_copy(intern->std.properties, &class_type->default_properties, 
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+
+   zend_hash_init(&intern->storage, 0, NULL, ZVAL_PTR_DTOR, 0);
+
+   retval.handle = zend_objects_store_put(intern, NULL, 
(zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL 
TSRMLS_CC);
+   retval.handlers = &spl_handler_SplObjectStorage;
+   return retval;
+}
+/* }}} */
+
+/* {{{ spl_array_object_new */
+static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type 
TSRMLS_DC)
+{
+   spl_SplObjectStorage *tmp;
+   return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto void SplObjectStorage::attach($obj)
+ Attaches an object to the storage if not yet contained */
+SPL_METHOD(SplObjectStorage, attach)
+{
+   zval *obj;
+   spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == 
FAILURE) {
+   return;
+   }
+   
+   zend_hash_update(&intern->storage, (char*)&obj->value.obj, 
sizeof(obj->value.obj), &obj, sizeof(zval**), NULL);
+   obj->refcount++;
+} /* }}} */
+
+/* {{{ proto void SplObjectStorage::detach($obj)
+ Detaches an object from the storage */
+SPL_METHOD(SplObjectStorage, detach)
+{
+   zval *obj;
+   spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == 
FAILURE) {
+   return;
+   }
+   
+   zend_hash_del(&intern->storage, (char*)&obj->value.obj, 
sizeof(obj->value.obj));
+   zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
+   intern->index = 0;
+} /* }}} */
+
+/* {{{ proto bool SplObjectStorage::contains($obj)
+ Determine whethe an object is contained in the storage */
+SPL_METHOD(SplObjectStorage, contains)
+{

[PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt

2005-08-10 Thread Marcus Boerger
helly   Wed Aug 10 17:56:02 2005 EDT

  Added files: 
/php-src/ext/spl/internal   splobjectstorage.inc 
/php-src/ext/spl/tests  observer_002.phpt 

  Modified files:  
/php-src/ext/splspl_observer.c 
  Log:
  - Implement SplObjectStorage as announced during OSCON
  # This class starts naming of new classes in Spl by prefix Spl as dicussed.
  # The class reduces object storage complexity from O(n) to O(1) which is
  # not possible in user space.
  
  http://cvs.php.net/diff.php/php-src/ext/spl/spl_observer.c?r1=1.2&r2=1.3&ty=u
Index: php-src/ext/spl/spl_observer.c
diff -u php-src/ext/spl/spl_observer.c:1.2 php-src/ext/spl/spl_observer.c:1.3
--- php-src/ext/spl/spl_observer.c:1.2  Wed Aug  3 10:07:53 2005
+++ php-src/ext/spl/spl_observer.c  Wed Aug 10 17:56:00 2005
@@ -16,7 +16,7 @@
+--+
  */
 
-/* $Id: spl_observer.c,v 1.2 2005/08/03 14:07:53 sniper Exp $ */
+/* $Id: spl_observer.c,v 1.3 2005/08/10 21:56:00 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -32,6 +32,8 @@
 #include "spl_functions.h"
 #include "spl_engine.h"
 #include "spl_observer.h"
+#include "spl_iterators.h"
+#include "spl_array.h"
 
 SPL_METHOD(Observer, update);
 SPL_METHOD(Subject, attach);
@@ -65,14 +67,197 @@
{NULL, NULL, NULL}
 };
 
-PHPAPI zend_class_entry  *spl_ce_Observer;
-PHPAPI zend_class_entry  *spl_ce_Subject;
+PHPAPI zend_class_entry *spl_ce_Observer;
+PHPAPI zend_class_entry *spl_ce_Subject;
+PHPAPI zend_class_entry *spl_ce_SplObjectStorage;
+PHPAPI zend_object_handlers spl_handler_SplObjectStorage;
+
+typedef struct _spl_SplObjectStorage {
+   zend_object   std;
+   HashTable storage;
+   long  index;
+   HashPosition  pos;
+} spl_SplObjectStorage;
+
+/* storage is an assoc aray of [zend_object_value]=>[zval*] */
+
+void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
+{
+   spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object;
+
+   zend_hash_destroy(intern->std.properties);
+   FREE_HASHTABLE(intern->std.properties);
+
+   zend_hash_destroy(&intern->storage);
+
+   efree(object);
+} /* }}} */
+
+static zend_object_value spl_object_storage_new_ex(zend_class_entry 
*class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */
+{
+   zend_object_value retval;
+   spl_SplObjectStorage *intern;
+   zval *tmp;
+
+   intern = emalloc(sizeof(spl_SplObjectStorage));
+   memset(intern, 0, sizeof(spl_SplObjectStorage));
+   intern->std.ce = class_type;
+   *obj = intern;
+
+   ALLOC_HASHTABLE(intern->std.properties);
+   zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+   zend_hash_copy(intern->std.properties, &class_type->default_properties, 
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+
+   zend_hash_init(&intern->storage, 0, NULL, ZVAL_PTR_DTOR, 0);
+
+   retval.handle = zend_objects_store_put(intern, NULL, 
(zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL 
TSRMLS_CC);
+   retval.handlers = &spl_handler_SplObjectStorage;
+   return retval;
+}
+/* }}} */
+
+/* {{{ spl_array_object_new */
+static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type 
TSRMLS_DC)
+{
+   spl_SplObjectStorage *tmp;
+   return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto void SplObjectStorage::attach($obj)
+ Attaches an object to the storage if not yet contained */
+SPL_METHOD(SplObjectStorage, attach)
+{
+   zval *obj;
+   spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == 
FAILURE) {
+   return;
+   }
+   
+   zend_hash_update(&intern->storage, (char*)&obj->value.obj, 
sizeof(obj->value.obj), &obj, sizeof(zval**), NULL);
+   obj->refcount++;
+} /* }}} */
+
+/* {{{ proto void SplObjectStorage::detach($obj)
+ Detaches an object from the storage */
+SPL_METHOD(SplObjectStorage, detach)
+{
+   zval *obj;
+   spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == 
FAILURE) {
+   return;
+   }
+   
+   zend_hash_del(&intern->storage, (char*)&obj->value.obj, 
sizeof(obj->value.obj));
+   zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
+   intern->index = 0;
+} /* }}} */
+
+/* {{{ proto bool SplObjectStorage::contains($obj)
+ Determine whethe an object is contained in the storage */
+SPL_METHOD(SplObjectStorage, contains)
+{
+   zval *obj;
+   spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_C