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); /* prev指针前移 */ } while (prev != ngx_queue_sentinel(queue)); ngx_queue_insert_after(prev, q);/* 将q插入prev节点之后(此处即为简单插入) */ } }
// cmp 指向函数的指针 // 队列排序采用的是稳定的简单插入排序方法,即从第一个节点开始遍历,依次将节点(q)插入前面已经排序好的队列(链表)中 // prev 为已经排序好的queue 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); } }
static void ngx_http_v2_waiting_queue(ngx_http_v2_connection_t *h2c, ngx_http_v2_stream_t *stream) { ngx_queue_t *q; ngx_http_v2_stream_t *s; if (stream->handled) { return; } stream->handled = 1; for (q = ngx_queue_last(&h2c->waiting); q != ngx_queue_sentinel(&h2c->waiting); q = ngx_queue_prev(q)) { s = ngx_queue_data(q, ngx_http_v2_stream_t, queue); if (s->node->rank < stream->node->rank || (s->node->rank == stream->node->rank && s->node->rel_weight >= stream->node->rel_weight)) { break; } } ngx_queue_insert_after(q, &stream->queue); }
static void ngx_http_spdy_waiting_queue(ngx_http_spdy_connection_t *sc, ngx_http_spdy_stream_t *stream) { ngx_queue_t *q; ngx_http_spdy_stream_t *s; if (stream->handled) { return; } stream->handled = 1; for (q = ngx_queue_last(&sc->waiting); q != ngx_queue_sentinel(&sc->waiting); q = ngx_queue_prev(q)) { s = ngx_queue_data(q, ngx_http_spdy_stream_t, queue); /* * NB: higher values represent lower priorities. */ if (stream->priority >= s->priority) { break; } } ngx_queue_insert_after(q, &stream->queue); }
void ngx_queue_sort(ngx_queue_t *queue, intptr_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); } }
int main(int argc, char const *argv[]) { ngx_queue_t queueContainer; ngx_queue_init(&queueContainer); int i = 0; my_queue node[5]; for(;i < 5;++i){ node[i].num = i; } ngx_queue_insert_tail(&queueContainer,&node[0].que); ngx_queue_insert_head(&queueContainer,&node[1].que); ngx_queue_insert_tail(&queueContainer,&node[2].que); ngx_queue_insert_after(&queueContainer,&node[3].que); ngx_queue_insert_tail(&queueContainer,&node[4].que); ngx_queue_sort(&queueContainer,compTestNode); ngx_queue_t *q; for(q = ngx_queue_head(&queueContainer);q != ngx_queue_sentinel(&queueContainer) ;q = ngx_queue_next(q)){ my_queue* eleNode = ngx_queue_data(q,my_queue,que); printf("%d\n",eleNode -> num ); } return 0; }
/* * [analy] 队列排序采用的是稳定的简单插入排序方法,即从第一个节点开始遍历,依次将当前节点(q)插入前面已经排好序的队列(链表)中 * 由于排序仅简单的修改了指针指向的操作,所以效率较高的。 */ 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)) { // 第一个节点和最后一个节点相等,不需要排序(有0或1个节点) 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); } }
int main(int argc, char *argv[]) { ngx_int_t n; ngx_log_t * log; ngx_queue_t queue_container; ngx_queue_t *q; test_node node[5]; test_node *ele_node; ngx_pagesize = getpagesize(); n = ngx_strerror_init(); if (n == NGX_ERROR){ return NGX_ERROR; } ngx_time_init(); log = ngx_log_init((u_char *)"./"); ngx_use_stderr = 0; if (log == NULL){ ngx_log_stderr(NGX_ERROR,(const char*)"can not init log "); return NGX_ERROR; } ngx_queue_init(&queue_container); for (n = 0;n < 5;n++){ node[n].num = n; } ngx_queue_insert_tail(&queue_container,&node[0].queue); ngx_queue_insert_head(&queue_container,&node[1].queue); ngx_queue_insert_after(&queue_container,&node[2].queue); ngx_queue_insert_head(&queue_container,&node[3].queue); ngx_queue_insert_tail(&queue_container,&node[4].queue); for (q = ngx_queue_head(&queue_container); q != ngx_queue_sentinel(&queue_container); q = ngx_queue_next(q)){ ele_node = ngx_queue_data(q,test_node,queue); printf("%d\n",ele_node->num); } ngx_queue_sort(&queue_container,cmp_test_node); for (q = ngx_queue_head(&queue_container); q != ngx_queue_sentinel(&queue_container); q = ngx_queue_next(q)){ ele_node = ngx_queue_data(q,test_node,queue); printf("%d\n",ele_node->num); } return NGX_OK; }