-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Minheap #53
Minheap #53
Changes from 2 commits
30d2fc8
1a894e8
355ac43
0560df3
54f331b
6094899
5ce9600
2469343
3faf5ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,6 @@ typedef struct ngx_connection_s ngx_connection_t; | |
typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); | ||
typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); | ||
|
||
|
||
#define NGX_OK 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. restore this line |
||
#define NGX_ERROR -1 | ||
#define NGX_AGAIN -2 | ||
|
@@ -66,6 +65,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); | |
#include <ngx_regex.h> | ||
#endif | ||
#include <ngx_trie.h> | ||
#include <ngx_minheap.h> | ||
#include <ngx_radix_tree.h> | ||
#include <ngx_times.h> | ||
#include <ngx_shmtx.h> | ||
|
@@ -106,4 +106,12 @@ void ngx_cpuinfo(void); | |
#define NGX_DISABLE_SYMLINKS_NOTOWNER 2 | ||
#endif | ||
|
||
typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); | ||
typedef ngx_int_t (*ngx_event_timer_init_pt)(ngx_log_t *log); | ||
typedef ngx_msec_t (*ngx_event_find_timer_pt)(void); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ngx_event_find_timer_pt -> ngx_event_find_min_timer_pt |
||
typedef void (*ngx_event_expire_timers_pt)(void); | ||
typedef void (*ngx_event_del_timer_pt)(ngx_event_t *ev); | ||
typedef void (*ngx_event_add_timer_pt)(ngx_event_t *ev, ngx_msec_t timer); | ||
typedef ngx_int_t (*ngx_event_timer_empty_pt)(void); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ngx_event_timer_empty_pt -> ngx_event_timer_is_empty_pt |
||
typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); | ||
#endif /* _NGX_CORE_H_INCLUDED_ */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a blank line above There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should add a new line above |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add one more line above |
||
* Copyright (C) 2010-2012 Alibaba Group Holding Limited | ||
*/ | ||
|
||
#include <ngx_config.h> | ||
#include <ngx_core.h> | ||
|
||
|
||
void | ||
ngx_minheap_insert(ngx_minheap_t *h, ngx_minheap_node_t *node) | ||
{ | ||
ngx_uint_t parent, index; | ||
ngx_minheap_node_t **p; | ||
|
||
if (h->nelts >= h->n) { | ||
h->elts = ngx_prealloc(h->pool, | ||
h->elts, h->n * sizeof(ngx_minheap_node_t *), | ||
h->n * 2 * sizeof(ngx_minheap_node_t *)); | ||
if (h->elts == NULL) { | ||
ngx_log_error(NGX_LOG_EMERG, h->pool->log, 0, | ||
"minheap2 realloc failed %d", h->n * 2); | ||
return; | ||
} | ||
h->n *= 2; | ||
} | ||
|
||
index = h->nelts++; | ||
parent = ngx_minheap_parent(index); | ||
|
||
p = (ngx_minheap_node_t **)h->elts; | ||
while (index && p[parent]->key > node->key) { | ||
(p[index] = p[parent])->index = index; | ||
index = parent; | ||
parent = ngx_minheap_parent(index); | ||
} | ||
|
||
p[index] = node; | ||
p[index]->index = index; | ||
|
||
return; | ||
} | ||
|
||
|
||
void | ||
ngx_minheap_delete(ngx_minheap_t *h, ngx_uint_t index) | ||
{ | ||
ngx_uint_t child, parent; | ||
ngx_minheap_node_t **p, *node; | ||
|
||
p = (ngx_minheap_node_t **) h->elts; | ||
node = p[--h->nelts]; | ||
parent = ngx_minheap_parent(index); | ||
|
||
if (node->key < p[parent]->key) { | ||
while (parent && p[parent]->key > node->key) { | ||
p[index] = p[parent]; | ||
p[index]->index = index; | ||
|
||
index = parent; | ||
parent = ngx_minheap_parent(index); | ||
} | ||
|
||
p[index] = node; | ||
p[index]->index = index; | ||
|
||
} else { | ||
child = ngx_minheap_child(index); | ||
while (child <= h->nelts) { | ||
child -= child == h->nelts || p[child] > p[child - 1]; | ||
if (p[child]->key > node->key) { | ||
break; | ||
} | ||
|
||
p[index] = p[child]; | ||
p[child]->index = index; | ||
|
||
index = child; | ||
child = ngx_minheap_child(index); | ||
} | ||
|
||
p[index] = node; | ||
p[index]->index = index; | ||
} | ||
return; | ||
} | ||
|
||
|
||
void ngx_minheap4_insert(ngx_minheap_t *h, ngx_minheap_node_t *node) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. void |
||
{ | ||
ngx_uint_t parent, index; | ||
ngx_minheap_node_t **p; | ||
|
||
if (h->nelts >= h->n) { | ||
h->elts = ngx_prealloc(h->pool, | ||
h->elts, h->n * sizeof(ngx_minheap_node_t*), | ||
h->n * 2 * sizeof(ngx_minheap_node_t *)); | ||
if (h->elts == NULL) { | ||
ngx_log_error(NGX_LOG_EMERG, h->pool->log, 0, | ||
"minheap4 realloc failed %d", h->n * 2); | ||
} | ||
} | ||
|
||
index = h->nelts++; | ||
parent = ngx_minheap4_parent(index); | ||
|
||
p = (ngx_minheap_node_t **) h->elts; | ||
while (index && p[parent]->key > node->key) { | ||
p[index] = p[parent]; | ||
p[index]->index = index; | ||
index = parent; | ||
parent = ngx_minheap_parent(index); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里是不是 ngx_minheap4_parent There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 嗯,是的 |
||
} | ||
|
||
node->index = index; | ||
p[index] = node; | ||
} | ||
|
||
|
||
void ngx_minheap4_delete(ngx_minheap_t *h, ngx_uint_t index) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. void |
||
{ | ||
ngx_uint_t child, parent, minpos; | ||
ngx_minheap_node_t **p, *node; | ||
|
||
p = (ngx_minheap_node_t **) h->elts; | ||
node = p[--h->nelts]; | ||
parent = ngx_minheap4_parent(index); | ||
|
||
if (node->key < p[parent]->key) { | ||
while (parent && p[parent]->key > node->key) { | ||
p[index] = p[parent]; | ||
p[index]->index = index; | ||
|
||
index = parent; | ||
parent = ngx_minheap4_parent(index); | ||
} | ||
|
||
p[index] = node; | ||
p[index]->index = index; | ||
|
||
} else { | ||
child = ngx_minheap4_child(index); | ||
|
||
while (child < h->nelts) { | ||
minpos = child; | ||
if (child + 1 < h->nelts && p[child + 1]->key < p[minpos]->key) { | ||
minpos = child + 1; | ||
} | ||
|
||
if (child + 2 < h->nelts && p[child + 2]->key < p[minpos]->key) { | ||
minpos = child + 2; | ||
} | ||
|
||
if (child + 3 < h->nelts && p[child +3]->key < p[minpos]->key) { | ||
minpos = child + 3; | ||
} | ||
|
||
if (node->key <= p[minpos]->key) { | ||
break; | ||
} | ||
|
||
p[index] = p[minpos]; | ||
p[index]->index = index; | ||
|
||
index = minpos; | ||
child = ngx_minheap4_child(index); | ||
} | ||
|
||
p[index] = node; | ||
p[index]->index = index; | ||
} | ||
|
||
return; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
|
||
/* CopyRight (C) www.taobao.com | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alibaba |
||
*/ | ||
|
||
#ifndef _NGX_MINHEAP_H_INCLUDE_ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a new line above |
||
#define _NGX_MINHEAP_H_INCLUDE_ | ||
|
||
|
||
#include <ngx_config.h> | ||
#include <ngx_core.h> | ||
|
||
|
||
#define ngx_minheap_child(i) ((i << 1) + 2) | ||
#define ngx_minheap_parent(i) (i > 0 ? (i - 1) >> 1 : 0) | ||
#define ngx_minheap4_child(i) ((i << 2) + 1) | ||
#define ngx_minheap4_parent(i) (i > 0 ? (i - 1) >> 2 : 0) | ||
|
||
|
||
typedef ngx_uint_t ngx_minheap_key_t; | ||
typedef ngx_int_t ngx_minheap_key_int_t; | ||
typedef struct ngx_minheap_s ngx_minheap_t; | ||
typedef struct ngx_minheap_node_s ngx_minheap_node_t; | ||
|
||
struct ngx_minheap_s { | ||
void **elts; | ||
ngx_uint_t n, nelts; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
ngx_pool_t *pool; | ||
}; | ||
|
||
|
||
struct ngx_minheap_node_s { | ||
ngx_uint_t index; | ||
ngx_minheap_key_t key; | ||
}; | ||
|
||
void ngx_minheap_insert(ngx_minheap_t *h, ngx_minheap_node_t *node); | ||
void ngx_minheap_delete(ngx_minheap_t *h, ngx_uint_t index); | ||
void ngx_minheap4_insert(ngx_minheap_t *h, ngx_minheap_node_t *node); | ||
void ngx_minheap4_delete(ngx_minheap_t *h, ngx_uint_t index); | ||
|
||
#define ngx_minheap_init(h, n, pool) \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this macro is not called? |
||
(h)->n = n; \ | ||
(h)->nelts = 0; \ | ||
(h)->pool = pool | ||
|
||
#define ngx_minheap_min(h) ((h)->elts[0]) | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
|
||
static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, | ||
void *conf); | ||
static char *ngx_event_timer(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | ||
static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | ||
static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, | ||
void *conf); | ||
|
@@ -79,6 +80,13 @@ ngx_atomic_t *ngx_stat_request_time = &ngx_stat_request_time0; | |
#endif | ||
|
||
|
||
ngx_int_t (*ngx_event_timer_init)(ngx_log_t *log); | ||
ngx_msec_t (*ngx_event_find_timer)(void); | ||
void (*ngx_event_expire_timers)(void); | ||
void (*ngx_event_del_timer)(ngx_event_t *ev); | ||
void (*ngx_event_add_timer)(ngx_event_t *ev, ngx_msec_t timer); | ||
ngx_int_t (*ngx_event_timer_empty)(void); | ||
|
||
|
||
static ngx_command_t ngx_events_commands[] = { | ||
|
||
|
@@ -135,6 +143,13 @@ static ngx_command_t ngx_event_core_commands[] = { | |
0, | ||
NULL }, | ||
|
||
{ ngx_string("timer"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. timers |
||
NGX_EVENT_CONF|NGX_CONF_TAKE1, | ||
ngx_event_timer, | ||
0, | ||
0, | ||
NULL }, | ||
|
||
{ ngx_string("use"), | ||
NGX_EVENT_CONF|NGX_CONF_TAKE1, | ||
ngx_event_use, | ||
|
@@ -997,6 +1012,53 @@ ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
} | ||
|
||
|
||
static char * | ||
ngx_event_timer(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | ||
{ | ||
ngx_str_t *value; | ||
|
||
value = cf->args->elts; | ||
value++; | ||
|
||
if (value->len == 6 | ||
&& ngx_strncmp(value->data, "rbtree", 6) == 0) { | ||
ngx_event_timer_init = ngx_event_timer_init_rbtree; | ||
ngx_event_timer_empty = ngx_event_timer_empty_rbtree; | ||
ngx_event_find_timer = ngx_event_find_timer_rbtree; | ||
ngx_event_expire_timers = ngx_event_expire_timers_rbtree; | ||
ngx_event_add_timer = ngx_event_add_timer_rbtree; | ||
ngx_event_del_timer = ngx_event_del_timer_rbtree; | ||
|
||
} else if (value->len == 7 | ||
&& ngx_strncmp(value->data, "minheap", 7) == 0) | ||
{ | ||
ngx_event_timer_init = ngx_event_timer_init_minheap; | ||
ngx_event_timer_empty = ngx_event_timer_empty_minheap; | ||
ngx_event_find_timer = ngx_event_find_timer_minheap; | ||
ngx_event_expire_timers = ngx_event_expire_timers_minheap; | ||
ngx_event_add_timer = ngx_event_add_timer_minheap; | ||
ngx_event_del_timer = ngx_event_del_timer_minheap; | ||
|
||
} else if (value->len == 8 | ||
&& ngx_strncmp(value->data, "minheap4", 8) == 0) | ||
{ | ||
ngx_event_timer_init = ngx_event_timer_init_minheap; | ||
ngx_event_timer_empty = ngx_event_timer_empty_minheap; | ||
ngx_event_find_timer = ngx_event_find_timer_minheap4; | ||
ngx_event_expire_timers = ngx_event_expire_timers_minheap4; | ||
ngx_event_add_timer = ngx_event_add_timer_minheap4; | ||
ngx_event_del_timer = ngx_event_del_timer_minheap4; | ||
|
||
} else { | ||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid args"); | ||
|
||
return NGX_CONF_ERROR; | ||
} | ||
|
||
return NGX_CONF_OK; | ||
} | ||
|
||
|
||
static char * | ||
ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | ||
{ | ||
|
@@ -1295,6 +1357,11 @@ ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf) | |
ngx_conf_init_value(ecf->accept_mutex, 1); | ||
ngx_conf_init_msec_value(ecf->accept_mutex_delay, 100); | ||
|
||
ngx_event_timer_init = ngx_event_timer_init_rbtree; | ||
ngx_event_find_timer = ngx_event_find_timer_rbtree; | ||
ngx_event_expire_timers = ngx_event_expire_timers_rbtree; | ||
ngx_event_add_timer = ngx_event_add_timer_rbtree; | ||
ngx_event_del_timer = ngx_event_del_timer_rbtree; | ||
|
||
#if (NGX_HAVE_RTSIG) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这对吗?