@@ -47,32 +47,6 @@ ds_deque_t *ds_deque()
47
47
return deque ;
48
48
}
49
49
50
- static void ds_deque_copy (ds_deque_t * src , ds_deque_t * dst )
51
- {
52
- zend_long tail = src -> tail ;
53
- zend_long head = src -> head ;
54
- zend_long mask = src -> capacity - 1 ;
55
-
56
- for (; head != tail ; head = (head + 1 ) & mask ) {
57
- ZVAL_COPY (& dst -> buffer [head ], & src -> buffer [head ]);
58
- }
59
- }
60
-
61
- ds_deque_t * ds_deque_clone (ds_deque_t * deque )
62
- {
63
- ds_deque_t * cloned = ecalloc (1 , sizeof (ds_deque_t ));
64
-
65
- cloned -> buffer = ALLOC_ZVAL_BUFFER (deque -> capacity );
66
- cloned -> capacity = deque -> capacity ;
67
- cloned -> head = deque -> head ;
68
- cloned -> tail = deque -> tail ;
69
- cloned -> size = deque -> size ;
70
-
71
- ds_deque_copy (deque , cloned );
72
-
73
- return cloned ;
74
- }
75
-
76
50
static ds_deque_t * ds_deque_from_buffer_ex (
77
51
zval * buffer ,
78
52
zend_long size ,
@@ -95,6 +69,22 @@ ds_deque_t *ds_deque_from_buffer(zval *buffer, zend_long size)
95
69
return ds_deque_from_buffer_ex (buffer , size , capacity );
96
70
}
97
71
72
+ ds_deque_t * ds_deque_clone (ds_deque_t * deque )
73
+ {
74
+ zval * source ;
75
+ zval * buffer = ALLOC_ZVAL_BUFFER (deque -> capacity );
76
+ zval * target = buffer ;
77
+
78
+ DS_DEQUE_FOREACH (deque , source ) {
79
+ ZVAL_COPY (target , source );
80
+ target ++ ;
81
+ }
82
+ DS_DEQUE_FOREACH_END ();
83
+
84
+ return ds_deque_from_buffer_ex (buffer , deque -> size , deque -> capacity );
85
+ }
86
+
87
+
98
88
static inline bool ds_deque_valid_index (ds_deque_t * deque , zend_long index )
99
89
{
100
90
if (index < 0 || index >= deque -> size ) {
@@ -281,32 +271,18 @@ ds_deque_t *ds_deque_reversed(ds_deque_t *deque)
281
271
return ds_deque_from_buffer_ex (buf , deque -> size , deque -> capacity );
282
272
}
283
273
284
- static inline void _ds_deque_shift (ds_deque_t * deque , zval * return_value )
285
- {
286
- ZVAL_COPY_DTOR (return_value , & deque -> buffer [deque -> head ]);
287
- ds_deque_increment_head (deque );
288
-
289
- deque -> size -- ;
290
- ds_deque_auto_truncate (deque );
291
- }
292
-
293
- static inline void _ds_deque_pop (ds_deque_t * deque , zval * return_value )
294
- {
295
- ds_deque_decrement_tail (deque );
296
- ZVAL_COPY_DTOR (return_value , & deque -> buffer [deque -> tail ]);
297
-
298
- deque -> size -- ;
299
- ds_deque_auto_truncate (deque );
300
- }
301
-
302
274
void ds_deque_shift (ds_deque_t * deque , zval * return_value )
303
275
{
304
276
if (deque -> size == 0 ) {
305
277
NOT_ALLOWED_WHEN_EMPTY ();
306
278
return ;
307
279
}
308
280
309
- _ds_deque_shift (deque , return_value );
281
+ ZVAL_COPY_DTOR (return_value , & deque -> buffer [deque -> head ]);
282
+ ds_deque_increment_head (deque );
283
+
284
+ deque -> size -- ;
285
+ ds_deque_auto_truncate (deque );
310
286
}
311
287
312
288
void ds_deque_pop (ds_deque_t * deque , zval * return_value )
@@ -316,7 +292,11 @@ void ds_deque_pop(ds_deque_t *deque, zval *return_value)
316
292
return ;
317
293
}
318
294
319
- _ds_deque_pop (deque , return_value );
295
+ ds_deque_decrement_tail (deque );
296
+ ZVAL_COPY_DTOR (return_value , & deque -> buffer [deque -> tail ]);
297
+
298
+ deque -> size -- ;
299
+ ds_deque_auto_truncate (deque );
320
300
}
321
301
322
302
void ds_deque_remove (ds_deque_t * deque , zend_long index , zval * return_value )
@@ -327,43 +307,43 @@ void ds_deque_remove(ds_deque_t *deque, zend_long index, zval *return_value)
327
307
328
308
// Basic shift if it's the first element in the sequence.
329
309
if (index == 0 ) {
330
- _ds_deque_shift (deque , return_value );
310
+ ds_deque_shift (deque , return_value );
311
+ return ;
312
+ }
331
313
332
314
// Basic pop if it's the last element in the sequence.
333
- } else if (index == deque -> size - 1 ) {
334
- _ds_deque_pop (deque , return_value );
335
-
336
- } else {
337
- index = (deque -> head + index ) & (deque -> capacity - 1 ); // Buffer index
338
-
339
- ZVAL_COPY_DTOR (return_value , & deque -> buffer [index ]);
315
+ if (index == deque -> size - 1 ) {
316
+ ds_deque_pop (deque , return_value );
317
+ return ;
318
+ }
340
319
341
- if (index < deque -> tail ) {
342
- // Index comes before the tail, so it must be between 0 and tail,
343
- // otherwise it would have wrapped around.
320
+ // Translate the positional index to a buffer index.
321
+ index = ds_deque_lookup_index (deque , index );
344
322
345
- // Shift all values between the index and the tail.
346
- _memmove (deque , index , index + 1 , deque -> tail - index );
347
- deque -> tail -- ;
323
+ // Copy the value into the return value, then destruct.
324
+ ZVAL_COPY_DTOR (return_value , & deque -> buffer [index ]);
348
325
349
- } else {
350
- // Index comes after tail, and we know at this point that the index
351
- // is valid, so it ,ust be after the head which has wrapped around.
326
+ if (index < deque -> tail ) {
327
+ // Shift all values between the index and the tail.
328
+ _memmove (deque , index , index + 1 , deque -> tail - index );
329
+ deque -> tail -- ;
352
330
353
- // Unshift all values between the head and the index.
354
- _memmove (deque , deque -> head + 1 , deque -> head , index - deque -> head );
355
- deque -> head ++ ;
356
- }
331
+ } else {
332
+ // Index comes after tail, and we know at this point that the index
333
+ // is valid, so it must be after the head which has wrapped around.
357
334
358
- deque -> size -- ;
359
- ds_deque_auto_truncate (deque );
335
+ // Unshift all values between the head and the index.
336
+ _memmove (deque , deque -> head + 1 , deque -> head , index - deque -> head );
337
+ deque -> head ++ ;
360
338
}
339
+
340
+ deque -> size -- ;
341
+ ds_deque_auto_truncate (deque );
361
342
}
362
343
363
344
void ds_deque_unshift_va (ds_deque_t * deque , VA_PARAMS )
364
345
{
365
346
ds_deque_ensure_capacity (deque , deque -> size + argc );
366
-
367
347
deque -> size += argc ;
368
348
369
349
while (argc -- ) {
@@ -462,36 +442,21 @@ void ds_deque_insert_va(ds_deque_t *deque, zend_long position, VA_PARAMS)
462
442
return ;
463
443
}
464
444
465
- // It's valid to insert at the end of the sequence.
466
445
if (ds_deque_valid_index (deque , position )) {
467
446
_ds_deque_insert_va (deque , position , VA_ARGS );
468
447
}
469
448
}
470
449
471
450
static zend_long ds_deque_find_index (ds_deque_t * deque , zval * value )
472
451
{
473
- zend_long tail = deque -> tail ;
474
- zend_long head = deque -> head ;
475
- zend_long mask = deque -> capacity - 1 ;
476
- zend_long index = 0 ;
452
+ zend_long head = deque -> head ;
453
+ zend_long mask = deque -> capacity - 1 ;
477
454
478
- if (head < tail ) {
479
- // No need to mod because the head is before the tail.
480
- do {
481
- if (zend_is_identical (value , & deque -> buffer [head ++ ])) {
482
- return index ;
483
- }
484
- index ++ ;
485
-
486
- } while (head < tail );
455
+ zend_long index ;
487
456
488
- } else {
489
- while (head != tail ) {
490
- if (zend_is_identical (value , & deque -> buffer [head ])) {
491
- return index ;
492
- }
493
- head = (head + 1 ) & mask ;
494
- index ++ ;
457
+ for (index = 0 ; index < deque -> size ; index ++ , head ++ ) {
458
+ if (zend_is_identical (value , & deque -> buffer [head & mask ])) {
459
+ return index ;
495
460
}
496
461
}
497
462
@@ -532,8 +497,6 @@ bool ds_deque_contains_va(ds_deque_t *deque, VA_PARAMS)
532
497
533
498
void ds_deque_rotate (ds_deque_t * deque , zend_long n )
534
499
{
535
- zval * buffer = deque -> buffer ;
536
-
537
500
if (n < 0 ) {
538
501
for (n = llabs (n ) % deque -> size ; n > 0 ; n -- ) {
539
502
@@ -542,13 +505,13 @@ void ds_deque_rotate(ds_deque_t *deque, zend_long n)
542
505
ds_deque_decrement_tail (deque );
543
506
544
507
// Tail is now at last value, head is before the first.
545
- SWAP_ZVAL (buffer [deque -> tail ], buffer [deque -> head ]);
508
+ SWAP_ZVAL (deque -> buffer [deque -> tail ], deque -> buffer [deque -> head ]);
546
509
}
547
510
} else if (n > 0 ) {
548
511
for (n = n % deque -> size ; n > 0 ; n -- ) {
549
512
550
513
// Tail is one past the last value, head is at first value.
551
- SWAP_ZVAL (buffer [deque -> tail ], buffer [deque -> head ]);
514
+ SWAP_ZVAL (deque -> buffer [deque -> tail ], deque -> buffer [deque -> head ]);
552
515
553
516
// Shift, push
554
517
ds_deque_increment_head (deque );
0 commit comments