Skip to content

Commit a224a89

Browse files
committed
Proposal: Add final class Vector to PHP
See spl_vector.stub.php for the userland API. Earlier work on the implementation can be found at https://github.com/TysonAndre/pecl-teds and it can be tested out at https://pecl.php.net/package/teds as `Teds\Vector` (currently the same apart from reusing spl's conversion of mixed to `int $offset`) This was originally based on spl_fixedarray.c and previous work I did on an RFC. Notable features: - Roughly half the memory usage of (non-constant) arrays due to not needing a list of indexes of buckets separately from the zval buckets themselves. - Same memory usage as SplFixedArray in 8.2 for a given **capacity** - Lower memory usage and better performance than SplDoublyLinkedList or its subclasses (SplStack) due to being an array instead of a linked list - More efficient resizing than SplFixedArray's setSize(getSize+1) ```php final class Vector implements IteratorAggregate, Countable, JsonSerializable, ArrayAccess { public function __construct( iterable $iterator = [], bool $preserveKeys = true ) {} public function getIterator(): InternalIterator {} public function count(): int {} public function capacity(): int {} public function clear(): void {} public function setSize(int $size): void {} public function __serialize(): array {} public function __unserialize(array $data): void {} public static function __set_state(array $array): Vector {} public function push(mixed $value): void {} public function pop(): mixed {} public function toArray(): array {} // Strictly typed, unlike offsetGet/offsetSet public function valueAt(int $offset): mixed {} public function setValueAt(int $offset, mixed $value): void {} public function offsetGet(mixed $offset): mixed {} public function offsetExists(mixed $offset): bool {} public function offsetSet(mixed $offset, mixed $value): void {} // Throws because unset and null are different things. public function offsetUnset(mixed $offset): void {} public function indexOf(mixed $value): int|false {} public function contains(mixed $value): bool {} public function shrinkToFit(): void {} public function jsonSerialize(): array {} } ```
1 parent ac2d85d commit a224a89

28 files changed

+2260
-35
lines changed

ext/spl/config.m4

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
2-
PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h])
1+
PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c spl_vector.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
2+
PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h spl_vector.h])
33
PHP_ADD_EXTENSION_DEP(spl, pcre, true)
44
PHP_ADD_EXTENSION_DEP(spl, standard, true)
55
PHP_ADD_EXTENSION_DEP(spl, json)

ext/spl/config.w32

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// vim:ft=javascript
22

3-
EXTENSION("spl", "php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
3+
EXTENSION("spl", "php_spl.c spl_functions.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c spl_vector.c", false /*never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
44
PHP_SPL="yes";
5-
PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h");
5+
PHP_INSTALL_HEADERS("ext/spl", "php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h spl_vector.h");

ext/spl/php_spl.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "spl_observer.h"
3434
#include "spl_dllist.h"
3535
#include "spl_fixedarray.h"
36+
#include "spl_vector.h"
3637
#include "spl_heap.h"
3738
#include "zend_exceptions.h"
3839
#include "zend_interfaces.h"
@@ -708,6 +709,7 @@ PHP_MINIT_FUNCTION(spl)
708709
PHP_MINIT(spl_dllist)(INIT_FUNC_ARGS_PASSTHRU);
709710
PHP_MINIT(spl_heap)(INIT_FUNC_ARGS_PASSTHRU);
710711
PHP_MINIT(spl_fixedarray)(INIT_FUNC_ARGS_PASSTHRU);
712+
PHP_MINIT(spl_vector)(INIT_FUNC_ARGS_PASSTHRU);
711713
PHP_MINIT(spl_observer)(INIT_FUNC_ARGS_PASSTHRU);
712714

713715
return SUCCESS;

ext/spl/spl_fixedarray.c

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "spl_fixedarray.h"
3232
#include "spl_exceptions.h"
3333
#include "spl_iterators.h"
34+
#include "spl_util.h"
3435
#include "ext/json/php_json.h"
3536

3637
zend_object_handlers spl_handler_SplFixedArray;
@@ -310,37 +311,6 @@ static zend_object *spl_fixedarray_object_clone(zend_object *old_object)
310311
return new_object;
311312
}
312313

313-
static zend_long spl_offset_convert_to_long(zval *offset) /* {{{ */
314-
{
315-
try_again:
316-
switch (Z_TYPE_P(offset)) {
317-
case IS_STRING: {
318-
zend_ulong index;
319-
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), index)) {
320-
return (zend_long) index;
321-
}
322-
break;
323-
}
324-
case IS_DOUBLE:
325-
return zend_dval_to_lval_safe(Z_DVAL_P(offset));
326-
case IS_LONG:
327-
return Z_LVAL_P(offset);
328-
case IS_FALSE:
329-
return 0;
330-
case IS_TRUE:
331-
return 1;
332-
case IS_REFERENCE:
333-
offset = Z_REFVAL_P(offset);
334-
goto try_again;
335-
case IS_RESOURCE:
336-
zend_use_resource_as_offset(offset);
337-
return Z_RES_HANDLE_P(offset);
338-
}
339-
340-
zend_type_error("Illegal offset type");
341-
return 0;
342-
}
343-
344314
static zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset)
345315
{
346316
zend_long index;

ext/spl/spl_util.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef SPL_UTIL
2+
#define SPL_UTIL
3+
4+
#include "zend_types.h"
5+
6+
static zend_long spl_offset_convert_to_long(zval *offset) /* {{{ */
7+
{
8+
try_again:
9+
switch (Z_TYPE_P(offset)) {
10+
case IS_STRING: {
11+
zend_ulong index;
12+
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), index)) {
13+
return (zend_long) index;
14+
}
15+
break;
16+
}
17+
case IS_DOUBLE:
18+
return zend_dval_to_lval_safe(Z_DVAL_P(offset));
19+
case IS_LONG:
20+
return Z_LVAL_P(offset);
21+
case IS_FALSE:
22+
return 0;
23+
case IS_TRUE:
24+
return 1;
25+
case IS_REFERENCE:
26+
offset = Z_REFVAL_P(offset);
27+
goto try_again;
28+
case IS_RESOURCE:
29+
zend_use_resource_as_offset(offset);
30+
return Z_RES_HANDLE_P(offset);
31+
}
32+
33+
zend_type_error("Illegal offset type");
34+
return 0;
35+
}
36+
37+
#endif

0 commit comments

Comments
 (0)