| /* | |
| * Copyright (C) Igor Sysoev | |
| */ | |
| #include <ngx_config.h> | |
| #include <ngx_core.h> | |
| /* | |
| * find the middle queue element if the queue has odd number of elements | |
| * or the first element of the queue's second part otherwise | |
| */ | |
| ngx_queue_t * | |
| ngx_queue_middle(ngx_queue_t *queue) | |
| { | |
| ngx_queue_t *middle, *next; | |
| middle = ngx_queue_head(queue); | |
| if (middle == ngx_queue_last(queue)) { | |
| return middle; | |
| } | |
| next = ngx_queue_head(queue); | |
| for ( ;; ) { | |
| middle = ngx_queue_next(middle); | |
| next = ngx_queue_next(next); | |
| if (next == ngx_queue_last(queue)) { | |
| return middle; | |
| } | |
| next = ngx_queue_next(next); | |
| if (next == ngx_queue_last(queue)) { | |
| return middle; | |
| } | |
| } | |
| } | |
| /* the stable insertion sort */ | |
| void | |
| ngx_queue_sort(ngx_queue_t *queue, | |
| ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *)) | |
| { | |
| ngx_queue_t *q, *prev, *next; | |
| q = ngx_queue_head(queue); | |
| if (q == ngx_queue_last(queue)) { | |
| return; | |
| } | |
| for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) { | |
| prev = ngx_queue_prev(q); | |
| next = ngx_queue_next(q); | |
| ngx_queue_remove(q); | |
| do { | |
| if (cmp(prev, q) <= 0) { | |
| break; | |
| } | |
| prev = ngx_queue_prev(prev); | |
| } while (prev != ngx_queue_sentinel(queue)); | |
| ngx_queue_insert_after(prev, q); | |
| } | |
| } |