@@ -970,38 +970,85 @@ static void spl_deque_shrink_capacity(spl_deque_entries *array, size_t new_capac
970
970
971
971
PHP_METHOD (Deque , push )
972
972
{
973
+ const zval * args ;
974
+ uint32_t argc ;
973
975
zval * value ;
974
976
975
- ZEND_PARSE_PARAMETERS_START (1 , 1 )
976
- Z_PARAM_ZVAL ( value )
977
+ ZEND_PARSE_PARAMETERS_START (0 , - 1 )
978
+ Z_PARAM_VARIADIC ( '+' , args , argc )
977
979
ZEND_PARSE_PARAMETERS_END ();
978
980
979
- spl_deque_push_back (Z_DEQUE_P (ZEND_THIS ), value );
981
+ if (UNEXPECTED (argc == 0 )) {
982
+ return ;
983
+ }
984
+
985
+ spl_deque * intern = Z_DEQUE_P (ZEND_THIS );
986
+ size_t old_size = intern -> array .size ;
987
+ const size_t new_size = old_size + argc ;
988
+ size_t mask = intern -> array .mask ;
989
+ const size_t old_capacity = mask ? mask + 1 : 0 ;
990
+
991
+ if (new_size > old_capacity ) {
992
+ const size_t new_capacity = spl_deque_next_pow2_capacity (new_size );
993
+ spl_deque_raise_capacity (& intern -> array , new_capacity );
994
+ mask = intern -> array .mask ;
995
+ }
996
+ zval * const circular_buffer = intern -> array .circular_buffer ;
997
+ const size_t old_offset = intern -> array .offset ;
998
+
999
+ while (1 ) {
1000
+ zval * dest = & circular_buffer [(old_offset + old_size ) & mask ];
1001
+ ZVAL_COPY (dest , args );
1002
+ if (++ old_size >= new_size ) {
1003
+ break ;
1004
+ }
1005
+ args ++ ;
1006
+ }
1007
+ intern -> array .size = new_size ;
980
1008
}
981
1009
982
1010
PHP_METHOD (Deque , unshift )
983
1011
{
1012
+ const zval * args ;
1013
+ uint32_t argc ;
984
1014
zval * value ;
985
1015
986
- ZEND_PARSE_PARAMETERS_START (1 , 1 )
987
- Z_PARAM_ZVAL ( value )
1016
+ ZEND_PARSE_PARAMETERS_START (0 , - 1 )
1017
+ Z_PARAM_VARIADIC ( '+' , args , argc )
988
1018
ZEND_PARSE_PARAMETERS_END ();
989
1019
1020
+ if (UNEXPECTED (argc == 0 )) {
1021
+ return ;
1022
+ }
1023
+
990
1024
spl_deque * intern = Z_DEQUE_P (ZEND_THIS );
991
- const size_t old_size = intern -> array .size ;
992
- const size_t old_mask = intern -> array .mask ;
993
- const size_t old_capacity = old_mask ? old_mask + 1 : 0 ;
1025
+ size_t old_size = intern -> array .size ;
1026
+ const size_t new_size = old_size + argc ;
1027
+ size_t mask = intern -> array .mask ;
1028
+ const size_t old_capacity = mask ? mask + 1 : 0 ;
994
1029
995
- if (old_size >= old_capacity ) {
996
- ZEND_ASSERT (old_size == old_capacity );
997
- const size_t new_capacity = old_capacity > 0 ? old_capacity * 2 : 4 ;
1030
+ if (new_size > old_capacity ) {
1031
+ const size_t new_capacity = spl_deque_next_pow2_capacity (new_size );
998
1032
spl_deque_raise_capacity (& intern -> array , new_capacity );
1033
+ mask = intern -> array .mask ;
999
1034
}
1000
- intern -> array .offset = (intern -> array .offset - 1 ) & intern -> array .mask ;
1001
- intern -> array .size ++ ;
1035
+ size_t offset = intern -> array .offset ;
1036
+ zval * const circular_buffer = intern -> array .circular_buffer ;
1037
+
1038
+ do {
1039
+ offset = (offset - 1 ) & mask ;
1040
+ zval * dest = & circular_buffer [offset ];
1041
+ ZVAL_COPY (dest , args );
1042
+ if (-- argc == 0 ) {
1043
+ break ;
1044
+ }
1045
+ args ++ ;
1046
+ } while (1 );
1047
+
1048
+ intern -> array .offset = offset ;
1049
+ intern -> array .size = new_size ;
1050
+
1002
1051
DEBUG_ASSERT_CONSISTENT_DEQUE (& intern -> array );
1003
- zval * dest = & intern -> array .circular_buffer [intern -> array .offset ];
1004
- ZVAL_COPY (dest , value );
1005
1052
}
1006
1053
1007
1054
static zend_always_inline void spl_deque_try_shrink_capacity (spl_deque * intern , size_t old_size )
0 commit comments