|  | 
 | /* | 
 |  * 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); | 
 |     } | 
 | } |