Skip to content

Commit 139fc95

Browse files
author
wxxiong6
authored
Update arraylist.c
1 parent 8da42e9 commit 139fc95

File tree

1 file changed

+121
-97
lines changed

1 file changed

+121
-97
lines changed

arraylist.c

Lines changed: 121 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@
2525
#include "php.h"
2626
#include "ext/standard/info.h"
2727
#include "zend_exceptions.h"
28-
2928
#include "php_arraylist.h"
3029

3130
#ifndef ARRAY_LIST_SIZE
32-
#define ARRAY_LIST_SIZE 16
31+
#define ARRAY_LIST_SIZE 8
3332
#endif
3433

3534
/* For compatibility with older PHP versions */
@@ -40,11 +39,13 @@
4039
#endif
4140

4241
zend_class_entry *array_list_ce;
42+
zend_object_handlers handler_ArrayList;
4343

4444
typedef struct _arraylist { /* {{{ */
45-
zend_long size; //数组大小
46-
zend_long key; //数组当前使用key
47-
zval *elements; //数组元素
45+
size_t nSize;
46+
size_t nNumUsed;
47+
size_t nNextIndex;
48+
zval *elements;
4849
} arraylist;
4950
/* }}} */
5051

@@ -65,67 +66,6 @@ static inline arraylist_object *arraylist_from_obj(zend_object *obj) /* {{{ */ {
6566
#define Z_ARRAYLIST_P(zv) arraylist_from_obj(Z_OBJ_P((zv)))
6667

6768

68-
69-
70-
71-
72-
static void destruct(arraylist *array)/* {{{ */
73-
{
74-
if (array->size > 0)
75-
{
76-
efree(array->elements);
77-
array->elements = NULL;
78-
array->size = 0;
79-
array->key = 0;
80-
}
81-
}
82-
/* }}} */
83-
84-
static void arraylist_init(arraylist *array, zend_long size) /* {{{ */
85-
{
86-
87-
array->size = 0; /* reset size in case ecalloc() fails */
88-
array->key = 0;
89-
array->elements = NULL;
90-
array->elements = (zval *)ecalloc(size, sizeof(zval));
91-
array->size = size;
92-
}
93-
/* }}} */
94-
95-
static void resize(arraylist *array)
96-
{
97-
if (array->key == array->size)
98-
{
99-
zend_long oldSize = array->size == 1? 2 : array->size;
100-
zend_long newSize = oldSize + (oldSize >> 1);
101-
zval *elements;
102-
elements = (zval *)ecalloc(newSize, sizeof(zval));
103-
zend_long i = 0;
104-
for (; i < array->size; i++)
105-
{
106-
elements[i] = array->elements[i];
107-
}
108-
efree(array->elements);
109-
array->elements = NULL;
110-
array->elements = elements;
111-
array->size = newSize;
112-
113-
}
114-
}
115-
116-
static void arraylist_add(arraylist *array, zval *val) /* {{{ */
117-
{
118-
if (!array)
119-
{
120-
return ;
121-
}
122-
resize(array);
123-
ZVAL_COPY(&array->elements[array->key], val);
124-
array->key++;
125-
}
126-
/* }}} */
127-
128-
12969
/* {{{ arginfo
13070
*/
13171
ZEND_BEGIN_ARG_INFO_EX(arginfo_arraylist__construct, 0, 0, 1)
@@ -144,13 +84,21 @@ ZEND_BEGIN_ARG_INFO(arginfo_arraylist_void, 0)
14484
ZEND_END_ARG_INFO()
14585
/* }}} */
14686

87+
static void arraylist_init(arraylist *array, zend_long size) /* {{{ */
88+
{
89+
array->elements = NULL;
90+
array->elements = (zval *)ecalloc(size, sizeof(zval));
91+
array->nSize = size;
92+
array->nNumUsed = 0;
93+
array->nNextIndex = 0;
94+
}
95+
/* }}} */
14796

14897
/* {{{ void arraylist::__construct()
14998
*/
15099
PHP_METHOD(arraylist, __construct)
151100
{
152101
zend_long size = ARRAY_LIST_SIZE;
153-
154102
zval *object = getThis();
155103
arraylist_object *intern;
156104
intern = Z_ARRAYLIST_P(object);
@@ -160,28 +108,62 @@ PHP_METHOD(arraylist, __construct)
160108
Z_PARAM_LONG(size)
161109
ZEND_PARSE_PARAMETERS_END();
162110

163-
164-
165111
arraylist_init(&intern->array, size);
112+
113+
}
114+
/* }}} */
166115

116+
static void arraylist_resize(arraylist *array) /* {{{ */
117+
{
118+
if (array->nNumUsed == array->nSize)
119+
{
120+
zend_long oldSize = array->nSize == 1? 2 : array->nSize;
121+
zend_long newSize = oldSize + (oldSize >> 1);
122+
zval *elements;
123+
elements = (zval *)ecalloc(newSize, sizeof(zval));
124+
zend_long i = 0;
125+
for (; i < array->nSize; i++)
126+
{
127+
elements[i] = array->elements[i];
128+
}
129+
efree(array->elements);
130+
array->elements = NULL;
131+
array->elements = elements;
132+
array->nSize = newSize;
133+
}
167134
}
168135
/* }}} */
169136

137+
static void arraylist_add(arraylist *array, zval *val) /* {{{ */
138+
{
139+
if (!array)
140+
{
141+
return ;
142+
}
143+
144+
// if (&array->elements[array->nNextIndex] != NULL) {
145+
// printf("ptr = %p, size=%zu \n", intern, intern->array.nSize);
146+
php_debug_zval_dump(&array->elements[array->nNextIndex], 1);
147+
ZVAL_COPY(&array->elements[array->nNextIndex], val);
148+
Z_TRY_ADDREF(array->elements[array->nNextIndex]);
149+
array->nNextIndex++;
150+
array->nNumUsed++;
151+
// }
152+
}
153+
154+
170155
/* {{{ string arraylist::add( [ $val ] )
171156
*/
172157
PHP_METHOD(arraylist, add)
173158
{
174-
175159
zval *object = getThis();
176160
arraylist_object *intern;
177-
size_t var_len;
178161
zval *val;
179162

180163
ZEND_PARSE_PARAMETERS_START(1, 1)
181164
Z_PARAM_ZVAL(val)
182165
ZEND_PARSE_PARAMETERS_END();
183166

184-
185167
intern = Z_ARRAYLIST_P(object);
186168
arraylist_add(&intern->array, val);
187169

@@ -200,12 +182,16 @@ PHP_METHOD(arraylist, get)
200182
Z_PARAM_LONG(key)
201183
ZEND_PARSE_PARAMETERS_END();
202184

203-
204185
intern = Z_ARRAYLIST_P(object);
205186

206-
if (key <= intern->array.size)
187+
if (key <= intern->array.nSize)
207188
{
208-
RETURN_ZVAL(&intern->array.elements[key], 0, 1);
189+
if (&intern->array.elements[key] != NULL)
190+
{
191+
RETURN_ZVAL(&intern->array.elements[key], 1, 1);
192+
} else {
193+
RETURN_NULL();
194+
}
209195
}
210196
else
211197
{
@@ -217,26 +203,22 @@ PHP_METHOD(arraylist, count)
217203
{
218204
zval *object = getThis();
219205
arraylist_object *intern;
220-
221206
if (zend_parse_parameters_none() == FAILURE) {
222207
return;
223208
}
224-
225209
intern = Z_ARRAYLIST_P(object);
226-
RETURN_LONG(intern->array.key);
210+
RETURN_LONG(intern->array.nNumUsed);
227211
}
228212

229213
PHP_METHOD(arraylist, getSize)
230214
{
231215
zval *object = getThis();
232216
arraylist_object *intern;
233-
234217
if (zend_parse_parameters_none() == FAILURE) {
235218
return;
236219
}
237-
238220
intern = Z_ARRAYLIST_P(object);
239-
RETURN_LONG(intern->array.size);
221+
RETURN_LONG(intern->array.nSize);
240222
}
241223

242224
/* {{{ proto object arraylist::toArray()
@@ -250,12 +232,10 @@ PHP_METHOD(arraylist, toArray)
250232
}
251233

252234
intern = Z_ARRAYLIST_P(getThis());
253-
254-
if (intern->array.size > 0) {
235+
if (intern->array.nNumUsed > 0) {
255236
int i = 0;
256-
257-
array_init_size(return_value, intern->array.size);
258-
for (; i < intern->array.size; i++) {
237+
array_init_size(return_value, intern->array.nNumUsed);
238+
for (; i < intern->array.nNumUsed; i++) {
259239
if (!Z_ISUNDEF(intern->array.elements[i])) {
260240
zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]);
261241
Z_TRY_ADDREF(intern->array.elements[i]);
@@ -269,17 +249,56 @@ PHP_METHOD(arraylist, toArray)
269249
}
270250
/* }}} */
271251

252+
static void arraylist_object_free_storage(zend_object *object)/* {{{ */
253+
{
254+
arraylist_object *intern = arraylist_from_obj(object);
255+
arraylist *array = &intern->array;
256+
if (array->nSize > 0)
257+
{
258+
int i = 0;
259+
for (; i < array->nSize; i++)
260+
{
261+
zval_ptr_dtor(&array->elements[i]);
262+
}
263+
efree(array->elements);
264+
array->elements = NULL;
265+
array->nNumUsed = 0;
266+
array->nNextIndex = 0;
267+
}
268+
zend_object_std_dtor(&intern->std);
269+
}
270+
/* }}} */
271+
272+
static void arraylist_destruct(arraylist_object *intern)/* {{{ */
273+
{
274+
// arraylist_object *intern = arraylist_from_obj(object);
275+
arraylist *array = &intern->array;
276+
if (array->nSize > 0)
277+
{
278+
int i = 0;
279+
for (; i < array->nSize; i++)
280+
{
281+
zval_ptr_dtor(&array->elements[i]);
282+
}
283+
efree(array->elements);
284+
array->elements = NULL;
285+
array->nNumUsed = 0;
286+
array->nNextIndex = 0;
287+
}
288+
zend_object_std_dtor(&intern->std);
289+
}
290+
/* }}} */
291+
272292
PHP_METHOD(arraylist, __destruct)
273293
{
274294
zval *object = getThis();
275295
arraylist_object *intern;
276-
277296
if (zend_parse_parameters_none() == FAILURE) {
278297
return;
279298
}
280-
281299
intern = Z_ARRAYLIST_P(object);
282-
destruct(&intern->array);
300+
301+
arraylist_destruct(intern);
283302
}
284303

285304
/* {{{ arraylist_functions[] 扩展函数
@@ -292,13 +311,13 @@ static const zend_function_entry arraylist_functions[] = {
292311
/* {{{ arraylist__methods[] 扩展类方法
293312
*/
294313
static const zend_function_entry arraylist_methods[] = {
295-
PHP_ME(arraylist, __construct, arginfo_arraylist__construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
296-
PHP_ME(arraylist, add, arginfo_arraylist_add, ZEND_ACC_PUBLIC)
297-
PHP_ME(arraylist, get, arginfo_arraylist_get, ZEND_ACC_PUBLIC)
298-
PHP_ME(arraylist, count, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
299-
PHP_ME(arraylist, toArray, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
300-
PHP_ME(arraylist, getSize, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
301-
PHP_ME(arraylist, __destruct, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
314+
PHP_ME(arraylist, __construct, arginfo_arraylist__construct, ZEND_ACC_PUBLIC)
315+
PHP_ME(arraylist, add, arginfo_arraylist_add, ZEND_ACC_PUBLIC)
316+
PHP_ME(arraylist, get, arginfo_arraylist_get, ZEND_ACC_PUBLIC)
317+
PHP_ME(arraylist, count, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
318+
PHP_ME(arraylist, toArray, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
319+
PHP_ME(arraylist, getSize, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
320+
PHP_ME(arraylist, __destruct, arginfo_arraylist_void, ZEND_ACC_PUBLIC)
302321
PHP_FE_END
303322
};
304323
/* }}} */
@@ -358,10 +377,15 @@ PHP_MINIT_FUNCTION(arraylist) /* {{{ */ {
358377
sizeof(PHP_ARRAYLIST_VERSION)-1,
359378
CONST_CS|CONST_PERSISTENT
360379
);
361-
362380
INIT_CLASS_ENTRY(ce, "ArrayList", arraylist_methods); //注册类及类方法
363381
array_list_ce = zend_register_internal_class(&ce);
364382

383+
memcpy(&handler_ArrayList, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
384+
handler_ArrayList.offset = XtOffsetOf(arraylist_object, std);
385+
handler_ArrayList.free_obj = arraylist_object_free_storage;
386+
387+
388+
365389
return SUCCESS;
366390
}
367391
/* }}} */

0 commit comments

Comments
 (0)