Skip to content

Commit 9554d13

Browse files
committed
Small deque.c refactor
1 parent 0665ad8 commit 9554d13

File tree

1 file changed

+58
-95
lines changed

1 file changed

+58
-95
lines changed

src/ds/ds_deque.c

Lines changed: 58 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -47,32 +47,6 @@ ds_deque_t *ds_deque()
4747
return deque;
4848
}
4949

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-
7650
static ds_deque_t *ds_deque_from_buffer_ex(
7751
zval *buffer,
7852
zend_long size,
@@ -95,6 +69,22 @@ ds_deque_t *ds_deque_from_buffer(zval *buffer, zend_long size)
9569
return ds_deque_from_buffer_ex(buffer, size, capacity);
9670
}
9771

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+
9888
static inline bool ds_deque_valid_index(ds_deque_t *deque, zend_long index)
9989
{
10090
if (index < 0 || index >= deque->size) {
@@ -281,32 +271,18 @@ ds_deque_t *ds_deque_reversed(ds_deque_t *deque)
281271
return ds_deque_from_buffer_ex(buf, deque->size, deque->capacity);
282272
}
283273

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-
302274
void ds_deque_shift(ds_deque_t *deque, zval *return_value)
303275
{
304276
if (deque->size == 0) {
305277
NOT_ALLOWED_WHEN_EMPTY();
306278
return;
307279
}
308280

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);
310286
}
311287

312288
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)
316292
return;
317293
}
318294

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);
320300
}
321301

322302
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)
327307

328308
// Basic shift if it's the first element in the sequence.
329309
if (index == 0) {
330-
_ds_deque_shift(deque, return_value);
310+
ds_deque_shift(deque, return_value);
311+
return;
312+
}
331313

332314
// 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+
}
340319

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);
344322

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]);
348325

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--;
352330

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.
357334

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++;
360338
}
339+
340+
deque->size--;
341+
ds_deque_auto_truncate(deque);
361342
}
362343

363344
void ds_deque_unshift_va(ds_deque_t *deque, VA_PARAMS)
364345
{
365346
ds_deque_ensure_capacity(deque, deque->size + argc);
366-
367347
deque->size += argc;
368348

369349
while (argc--) {
@@ -462,36 +442,21 @@ void ds_deque_insert_va(ds_deque_t *deque, zend_long position, VA_PARAMS)
462442
return;
463443
}
464444

465-
// It's valid to insert at the end of the sequence.
466445
if (ds_deque_valid_index(deque, position)) {
467446
_ds_deque_insert_va(deque, position, VA_ARGS);
468447
}
469448
}
470449

471450
static zend_long ds_deque_find_index(ds_deque_t *deque, zval *value)
472451
{
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;
477454

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;
487456

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;
495460
}
496461
}
497462

@@ -532,8 +497,6 @@ bool ds_deque_contains_va(ds_deque_t *deque, VA_PARAMS)
532497

533498
void ds_deque_rotate(ds_deque_t *deque, zend_long n)
534499
{
535-
zval *buffer = deque->buffer;
536-
537500
if (n < 0) {
538501
for (n = llabs(n) % deque->size; n > 0; n--) {
539502

@@ -542,13 +505,13 @@ void ds_deque_rotate(ds_deque_t *deque, zend_long n)
542505
ds_deque_decrement_tail(deque);
543506

544507
// 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]);
546509
}
547510
} else if (n > 0) {
548511
for (n = n % deque->size; n > 0; n--) {
549512

550513
// 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]);
552515

553516
// Shift, push
554517
ds_deque_increment_head(deque);

0 commit comments

Comments
 (0)