Skip to content

Commit 2f7ec2f

Browse files
authored
Added Map::find(), ArrayList::find(), supports ArrayList::offsetUnset() (#5405)
* Added Map::find(), ArrayList::find(), supports ArrayList::offsetUnset() * fix * fix tests
1 parent 936402e commit 2f7ec2f

11 files changed

+163
-56
lines changed

ext-src/php_swoole_thread.h

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ struct ArrayItem {
133133
void store(zval *zvalue);
134134
void fetch(zval *return_value);
135135
void release();
136+
bool equals(zval *zvalue);
136137

137138
~ArrayItem() {
138139
if (value.str) {
@@ -252,6 +253,7 @@ struct ZendArray : ThreadResource {
252253
void keys(zval *return_value);
253254
void values(zval *return_value);
254255
void toArray(zval *return_value);
256+
void find(zval *search, zval *return_value);
255257

256258
void intkey_offsetGet(zend_long index, zval *return_value) {
257259
lock_.lock_rd();
@@ -288,29 +290,10 @@ struct ZendArray : ThreadResource {
288290
lock_.unlock();
289291
}
290292

291-
bool index_offsetGet(zval *zkey, zval *return_value) {
292-
zend_long index = zval_get_long(zkey);
293-
bool out_of_range = true;
294-
lock_.lock_rd();
295-
if (index_exists(index)) {
296-
out_of_range = false;
297-
ArrayItem *item = (ArrayItem *) zend_hash_index_find_ptr(&ht, index);
298-
if (item) {
299-
item->fetch(return_value);
300-
}
301-
}
302-
lock_.unlock();
303-
return !out_of_range;
304-
}
305-
306-
bool index_offsetSet(zval *zkey, zval *zvalue);
307-
308-
void index_offsetExists(zval *zkey, zval *return_value) {
309-
zend_long index = zval_get_long(zkey);
310-
lock_.lock_rd();
311-
RETVAL_BOOL(index_exists(index));
312-
lock_.unlock();
313-
}
293+
bool index_offsetGet(zend_long index, zval *return_value);
294+
bool index_offsetSet(zend_long index, zval *zvalue);
295+
void index_offsetUnset(zend_long index);
296+
void index_offsetExists(zend_long index, zval *return_value);
314297

315298
static void incr_update(ArrayItem *item, zval *zvalue, zval *return_value);
316299
static ArrayItem *incr_create(zval *zvalue, zval *return_value);

ext-src/stubs/php_swoole_thread_arraylist.stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public function offsetGet(mixed $key): mixed {}
66
public function offsetExists(mixed $key): bool {}
77
public function offsetSet(mixed $key, mixed $value): void {}
88
public function offsetUnset(mixed $key): void {}
9+
public function find(mixed $value): int {}
910
public function count(): int {}
1011
public function incr(mixed $key, mixed $value = 1): mixed {}
1112
public function decr(mixed $key, mixed $value = 1): mixed {}

ext-src/stubs/php_swoole_thread_arraylist_arginfo.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 70c2427e37953ac2ceefe4c972cbd8b9845b43ab */
2+
* Stub hash: 1ca9dca970881ea647b0ebc5431e857cdb973eb8 */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_ArrayList___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, array, IS_ARRAY, 1, "null")
@@ -22,6 +22,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_of
2222
ZEND_ARG_TYPE_INFO(0, key, IS_MIXED, 0)
2323
ZEND_END_ARG_INFO()
2424

25+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_find, 0, 1, IS_LONG, 0)
26+
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
27+
ZEND_END_ARG_INFO()
28+
2529
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_ArrayList_count, 0, 0, IS_LONG, 0)
2630
ZEND_END_ARG_INFO()
2731

ext-src/stubs/php_swoole_thread_map.stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public function offsetGet(mixed $key): mixed {}
66
public function offsetExists(mixed $key): bool {}
77
public function offsetSet(mixed $key, mixed $value): void {}
88
public function offsetUnset(mixed $key): void {}
9+
public function find(mixed $value): mixed {}
910
public function count(): int {}
1011
public function keys(): array {}
1112
public function values(): array {}

ext-src/stubs/php_swoole_thread_map_arginfo.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 40e24b68b9e9d7f7192a8f91e4b31b3020e9faca */
2+
* Stub hash: 39226ea3aff361cc9530c65fe7de5a0e276a65fe */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Thread_Map___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, array, IS_ARRAY, 1, "null")
@@ -22,6 +22,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_offsetUn
2222
ZEND_ARG_TYPE_INFO(0, key, IS_MIXED, 0)
2323
ZEND_END_ARG_INFO()
2424

25+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_find, 0, 1, IS_MIXED, 0)
26+
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
27+
ZEND_END_ARG_INFO()
28+
2529
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Thread_Map_count, 0, 0, IS_LONG, 0)
2630
ZEND_END_ARG_INFO()
2731

ext-src/swoole_thread.cc

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ void php_swoole_thread_minit(int module_number) {
112112
swoole_thread_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NOT_SERIALIZABLE;
113113
SW_SET_CLASS_CLONEABLE(swoole_thread, sw_zend_class_clone_deny);
114114
SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_thread, sw_zend_class_unset_property_deny);
115-
SW_SET_CLASS_CUSTOM_OBJECT(
116-
swoole_thread, thread_create_object, thread_free_object, ThreadObject, std);
115+
SW_SET_CLASS_CUSTOM_OBJECT(swoole_thread, thread_create_object, thread_free_object, ThreadObject, std);
117116

118117
zend_declare_property_long(swoole_thread_ce, ZEND_STRL("id"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
119118
zend_declare_class_constant_long(
@@ -499,6 +498,26 @@ void ArrayItem::store(zval *zvalue) {
499498
}
500499
}
501500

501+
bool ArrayItem::equals(zval *zvalue) {
502+
if (Z_TYPE_P(zvalue) != type) {
503+
return false;
504+
}
505+
switch (type) {
506+
case IS_LONG:
507+
return Z_LVAL_P(zvalue) == value.lval;
508+
case IS_DOUBLE:
509+
return Z_DVAL_P(zvalue) == value.dval;
510+
case IS_TRUE:
511+
case IS_FALSE:
512+
case IS_NULL:
513+
return true;
514+
case IS_STRING:
515+
return zend_string_equals(value.str, Z_STR_P(zvalue));
516+
default:
517+
return false;
518+
}
519+
}
520+
502521
void ArrayItem::fetch(zval *return_value) {
503522
switch (type) {
504523
case IS_LONG:
@@ -695,8 +714,21 @@ void ZendArray::intkey_update(zval *zkey, zval *zvalue, zval *return_value) {
695714
lock_.unlock();
696715
}
697716

698-
bool ZendArray::index_offsetSet(zval *zkey, zval *zvalue) {
699-
zend_long index = ZVAL_IS_NULL(zkey) ? -1 : zval_get_long(zkey);
717+
bool ZendArray::index_offsetGet(zend_long index, zval *return_value) {
718+
bool out_of_range = true;
719+
lock_.lock_rd();
720+
if (index_exists(index)) {
721+
out_of_range = false;
722+
ArrayItem *item = (ArrayItem *) zend_hash_index_find_ptr(&ht, index);
723+
if (item) {
724+
item->fetch(return_value);
725+
}
726+
}
727+
lock_.unlock();
728+
return !out_of_range;
729+
}
730+
731+
bool ZendArray::index_offsetSet(zend_long index, zval *zvalue) {
700732
auto item = new ArrayItem(zvalue);
701733
bool success = true;
702734
lock_.lock();
@@ -734,6 +766,33 @@ bool ZendArray::index_incr(zval *zkey, zval *zvalue, zval *return_value) {
734766
return success;
735767
}
736768

769+
void ZendArray::index_offsetExists(zend_long index, zval *return_value) {
770+
lock_.lock_rd();
771+
RETVAL_BOOL(index_exists(index));
772+
lock_.unlock();
773+
}
774+
775+
void ZendArray::index_offsetUnset(zend_long index) {
776+
lock_.lock();
777+
zend_long i = index;
778+
zend_long n = zend_hash_num_elements(&ht);
779+
HT_FLAGS(&ht) |= HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS;
780+
ArrayItem *item = (ArrayItem *) zend_hash_index_find_ptr(&ht, index);
781+
delete item;
782+
while (i < n - 1) {
783+
#if PHP_VERSION_ID >= 80200
784+
Z_PTR(ht.arPacked[i]) = Z_PTR(ht.arPacked[i + 1]);
785+
#else
786+
Z_PTR(ht.arData[i].val) = Z_PTR(ht.arData[i + 1].val);
787+
#endif
788+
i++;
789+
}
790+
ht.nNumUsed--;
791+
ht.nNumOfElements--;
792+
ht.nNextFreeElement--;
793+
lock_.unlock();
794+
}
795+
737796
bool ZendArray::index_decr(zval *zkey, zval *zvalue, zval *return_value) {
738797
INIT_DECR_VALUE(zvalue);
739798
return index_incr(zkey, &rvalue, return_value);
@@ -810,6 +869,26 @@ void ZendArray::toArray(zval *return_value) {
810869
lock_.unlock();
811870
}
812871

872+
void ZendArray::find(zval *search, zval *return_value) {
873+
lock_.lock_rd();
874+
zend_string *key;
875+
zend_ulong index;
876+
void *tmp;
877+
ZEND_HASH_FOREACH_KEY_PTR(&ht, index, key, tmp) {
878+
ArrayItem *item = (ArrayItem *) tmp;
879+
if (item->equals(search)) {
880+
if (key) {
881+
RETVAL_STRINGL(ZSTR_VAL(key), ZSTR_LEN(key));
882+
} else {
883+
RETVAL_LONG(index);
884+
}
885+
break;
886+
}
887+
}
888+
ZEND_HASH_FOREACH_END();
889+
lock_.unlock();
890+
}
891+
813892
ZendArray *ZendArray::from(zend_array *src) {
814893
zend_string *key;
815894
zend_ulong index;

ext-src/swoole_thread_arraylist.cc

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static PHP_METHOD(swoole_thread_arraylist, offsetGet);
3737
static PHP_METHOD(swoole_thread_arraylist, offsetExists);
3838
static PHP_METHOD(swoole_thread_arraylist, offsetSet);
3939
static PHP_METHOD(swoole_thread_arraylist, offsetUnset);
40+
static PHP_METHOD(swoole_thread_arraylist, find);
4041
static PHP_METHOD(swoole_thread_arraylist, count);
4142
static PHP_METHOD(swoole_thread_arraylist, incr);
4243
static PHP_METHOD(swoole_thread_arraylist, decr);
@@ -91,6 +92,7 @@ static const zend_function_entry swoole_thread_arraylist_methods[] = {
9192
PHP_ME(swoole_thread_arraylist, offsetExists, arginfo_class_Swoole_Thread_ArrayList_offsetExists, ZEND_ACC_PUBLIC)
9293
PHP_ME(swoole_thread_arraylist, offsetSet, arginfo_class_Swoole_Thread_ArrayList_offsetSet, ZEND_ACC_PUBLIC)
9394
PHP_ME(swoole_thread_arraylist, offsetUnset, arginfo_class_Swoole_Thread_ArrayList_offsetUnset, ZEND_ACC_PUBLIC)
95+
PHP_ME(swoole_thread_arraylist, find, arginfo_class_Swoole_Thread_ArrayList_find, ZEND_ACC_PUBLIC)
9496
PHP_ME(swoole_thread_arraylist, incr, arginfo_class_Swoole_Thread_ArrayList_incr, ZEND_ACC_PUBLIC)
9597
PHP_ME(swoole_thread_arraylist, decr, arginfo_class_Swoole_Thread_ArrayList_decr, ZEND_ACC_PUBLIC)
9698
PHP_ME(swoole_thread_arraylist, clean, arginfo_class_Swoole_Thread_ArrayList_clean, ZEND_ACC_PUBLIC)
@@ -105,11 +107,8 @@ void php_swoole_thread_arraylist_minit(int module_number) {
105107
swoole_thread_arraylist_ce->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NOT_SERIALIZABLE;
106108
SW_SET_CLASS_CLONEABLE(swoole_thread_arraylist, sw_zend_class_clone_deny);
107109
SW_SET_CLASS_UNSET_PROPERTY_HANDLER(swoole_thread_arraylist, sw_zend_class_unset_property_deny);
108-
SW_SET_CLASS_CUSTOM_OBJECT(swoole_thread_arraylist,
109-
arraylist_create_object,
110-
arraylist_free_object,
111-
ThreadArrayListObject,
112-
std);
110+
SW_SET_CLASS_CUSTOM_OBJECT(
111+
swoole_thread_arraylist, arraylist_create_object, arraylist_free_object, ThreadArrayListObject, std);
113112

114113
zend_class_implements(swoole_thread_arraylist_ce, 2, zend_ce_arrayaccess, zend_ce_countable);
115114
zend_declare_property_long(swoole_thread_arraylist_ce, ZEND_STRL("id"), 0, ZEND_ACC_PUBLIC | ZEND_ACC_READONLY);
@@ -140,27 +139,27 @@ static PHP_METHOD(swoole_thread_arraylist, __construct) {
140139
}
141140

142141
static PHP_METHOD(swoole_thread_arraylist, offsetGet) {
143-
zval *zkey;
142+
zend_long index;
144143

145144
ZEND_PARSE_PARAMETERS_START(1, 1)
146-
Z_PARAM_ZVAL(zkey)
145+
Z_PARAM_LONG(index)
147146
ZEND_PARSE_PARAMETERS_END();
148147

149148
auto ao = arraylist_fetch_object_check(ZEND_THIS);
150-
if (!ao->list->index_offsetGet(zkey, return_value)) {
149+
if (!ao->list->index_offsetGet(index, return_value)) {
151150
zend_throw_exception(swoole_exception_ce, "out of range", -1);
152151
}
153152
}
154153

155154
static PHP_METHOD(swoole_thread_arraylist, offsetExists) {
156-
zval *zkey;
155+
zend_long index;
157156

158157
ZEND_PARSE_PARAMETERS_START(1, 1)
159-
Z_PARAM_ZVAL(zkey)
158+
Z_PARAM_LONG(index)
160159
ZEND_PARSE_PARAMETERS_END();
161160

162161
auto ao = arraylist_fetch_object_check(ZEND_THIS);
163-
ao->list->index_offsetExists(zkey, return_value);
162+
ao->list->index_offsetExists(index, return_value);
164163
}
165164

166165
static PHP_METHOD(swoole_thread_arraylist, offsetSet) {
@@ -173,7 +172,8 @@ static PHP_METHOD(swoole_thread_arraylist, offsetSet) {
173172
ZEND_PARSE_PARAMETERS_END();
174173

175174
auto ao = arraylist_fetch_object_check(ZEND_THIS);
176-
if (!ao->list->index_offsetSet(zkey, zvalue)) {
175+
zend_long index = ZVAL_IS_NULL(zkey) ? -1 : zval_get_long(zkey);
176+
if (!ao->list->index_offsetSet(index, zvalue)) {
177177
zend_throw_exception(swoole_exception_ce, "out of range", -1);
178178
}
179179
}
@@ -195,7 +195,25 @@ static PHP_METHOD(swoole_thread_arraylist, decr) {
195195
}
196196

197197
static PHP_METHOD(swoole_thread_arraylist, offsetUnset) {
198-
zend_throw_exception(swoole_exception_ce, "unsupported", -3);
198+
zend_long index;
199+
200+
ZEND_PARSE_PARAMETERS_START(1, 1)
201+
Z_PARAM_LONG(index)
202+
ZEND_PARSE_PARAMETERS_END();
203+
204+
auto ao = arraylist_fetch_object_check(ZEND_THIS);
205+
ao->list->index_offsetUnset(index);
206+
}
207+
208+
static PHP_METHOD(swoole_thread_arraylist, find) {
209+
zval *zvalue;
210+
211+
ZEND_PARSE_PARAMETERS_START(1, 1)
212+
Z_PARAM_ZVAL(zvalue)
213+
ZEND_PARSE_PARAMETERS_END();
214+
215+
auto ao = arraylist_fetch_object_check(ZEND_THIS);
216+
ao->list->find(zvalue, return_value);
199217
}
200218

201219
static PHP_METHOD(swoole_thread_arraylist, count) {

ext-src/swoole_thread_map.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static PHP_METHOD(swoole_thread_map, offsetGet);
7777
static PHP_METHOD(swoole_thread_map, offsetExists);
7878
static PHP_METHOD(swoole_thread_map, offsetSet);
7979
static PHP_METHOD(swoole_thread_map, offsetUnset);
80+
static PHP_METHOD(swoole_thread_map, find);
8081
static PHP_METHOD(swoole_thread_map, count);
8182
static PHP_METHOD(swoole_thread_map, keys);
8283
static PHP_METHOD(swoole_thread_map, values);
@@ -95,6 +96,7 @@ static const zend_function_entry swoole_thread_map_methods[] = {
9596
PHP_ME(swoole_thread_map, offsetExists, arginfo_class_Swoole_Thread_Map_offsetExists, ZEND_ACC_PUBLIC)
9697
PHP_ME(swoole_thread_map, offsetSet, arginfo_class_Swoole_Thread_Map_offsetSet, ZEND_ACC_PUBLIC)
9798
PHP_ME(swoole_thread_map, offsetUnset, arginfo_class_Swoole_Thread_Map_offsetUnset, ZEND_ACC_PUBLIC)
99+
PHP_ME(swoole_thread_map, find, arginfo_class_Swoole_Thread_Map_find, ZEND_ACC_PUBLIC)
98100
PHP_ME(swoole_thread_map, count, arginfo_class_Swoole_Thread_Map_count, ZEND_ACC_PUBLIC)
99101
PHP_ME(swoole_thread_map, incr, arginfo_class_Swoole_Thread_Map_incr, ZEND_ACC_PUBLIC)
100102
PHP_ME(swoole_thread_map, decr, arginfo_class_Swoole_Thread_Map_decr, ZEND_ACC_PUBLIC)
@@ -230,6 +232,17 @@ static PHP_METHOD(swoole_thread_map, offsetUnset) {
230232
ZEND_ARRAY_CALL_METHOD(mo->map, offsetUnset, zkey);
231233
}
232234

235+
static PHP_METHOD(swoole_thread_map, find) {
236+
zval *zvalue;
237+
238+
ZEND_PARSE_PARAMETERS_START(1, 1)
239+
Z_PARAM_ZVAL(zvalue)
240+
ZEND_PARSE_PARAMETERS_END();
241+
242+
auto mo = map_fetch_object_check(ZEND_THIS);
243+
mo->map->find(zvalue, return_value);
244+
}
245+
233246
static PHP_METHOD(swoole_thread_map, count) {
234247
auto mo = map_fetch_object_check(ZEND_THIS);
235248
mo->map->count(return_value);

tests/swoole_coroutine/check.phpt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,6 @@ $map = [
2929
(new Chan)->pop();
3030
Assert::assert(0); // never here
3131
},
32-
function () {
33-
fread(STDIN);
34-
Assert::assert(0); // never here
35-
},
36-
function () {
37-
fgets(fopen(__FILE__, 'r'));
38-
Assert::assert(0); // never here
39-
},
40-
function () {
41-
fwrite(fopen(TEST_LOG_FILE, 'w+'), 'foo');
42-
Assert::assert(0); // never here
43-
},
4432
function () {
4533
Co::readFile(__FILE__);
4634
Assert::assert(0); // never here

0 commit comments

Comments
 (0)