Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_geo_module.c @ 3645:9f22c780d574
eliminate a number of ranges: about 18,000 /16 networks are empty,
this change saves about 70K/140K on 32/64-bit platforms
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 24 Jun 2010 15:26:05 +0000 |
parents | 762712d69672 |
children | c12b0dd5bd1c |
comparison
equal
deleted
inserted
replaced
3644:5d3282cfc43c | 3645:9f22c780d574 |
---|---|
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | 10 |
11 | 11 |
12 typedef struct { | 12 typedef struct { |
13 ngx_http_variable_value_t *value; | |
13 u_short start; | 14 u_short start; |
14 u_short end; | 15 u_short end; |
15 ngx_http_variable_value_t *value; | |
16 } ngx_http_geo_range_t; | 16 } ngx_http_geo_range_t; |
17 | 17 |
18 | 18 |
19 typedef struct { | 19 typedef struct { |
20 ngx_http_geo_range_t *ranges; | 20 ngx_http_geo_range_t *low[0x10000]; |
21 ngx_uint_t n; | |
22 } ngx_http_geo_low_ranges_t; | |
23 | |
24 | |
25 typedef struct { | |
26 ngx_http_geo_low_ranges_t low[0x10000]; | |
27 ngx_http_variable_value_t *default_value; | 21 ngx_http_variable_value_t *default_value; |
28 } ngx_http_geo_high_ranges_t; | 22 } ngx_http_geo_high_ranges_t; |
29 | 23 |
30 | 24 |
31 typedef struct { | 25 typedef struct { |
152 uintptr_t data) | 146 uintptr_t data) |
153 { | 147 { |
154 ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data; | 148 ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data; |
155 | 149 |
156 in_addr_t addr; | 150 in_addr_t addr; |
157 ngx_uint_t i, n; | 151 ngx_uint_t n; |
158 ngx_http_geo_range_t *range; | 152 ngx_http_geo_range_t *range; |
159 | 153 |
160 *v = *ctx->u.high->default_value; | 154 *v = *ctx->u.high->default_value; |
161 | 155 |
162 addr = ngx_http_geo_addr(r, ctx); | 156 addr = ngx_http_geo_addr(r, ctx); |
163 | 157 |
164 range = ctx->u.high->low[addr >> 16].ranges; | 158 range = ctx->u.high->low[addr >> 16]; |
165 | 159 |
166 n = addr & 0xffff; | 160 if (range) { |
167 | 161 n = addr & 0xffff; |
168 for (i = 0; i < ctx->u.high->low[addr >> 16].n; i++) { | 162 do { |
169 if (n >= (ngx_uint_t) range[i].start && n <= (ngx_uint_t) range[i].end) | 163 if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end) |
170 { | 164 { |
171 *v = *range[i].value; | 165 *v = *range->value; |
172 break; | 166 break; |
173 } | 167 } |
168 } while ((++range)->value); | |
174 } | 169 } |
175 | 170 |
176 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 171 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
177 "http geo: %v", v); | 172 "http geo: %v", v); |
178 | 173 |
260 | 255 |
261 static char * | 256 static char * |
262 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 257 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
263 { | 258 { |
264 char *rv; | 259 char *rv; |
260 void **p; | |
265 size_t len; | 261 size_t len; |
266 ngx_str_t *value, name; | 262 ngx_str_t *value, name; |
267 ngx_uint_t i; | 263 ngx_uint_t i; |
268 ngx_conf_t save; | 264 ngx_conf_t save; |
269 ngx_pool_t *pool; | 265 ngx_pool_t *pool; |
333 geo->proxies = ctx.proxies; | 329 geo->proxies = ctx.proxies; |
334 | 330 |
335 if (ctx.high) { | 331 if (ctx.high) { |
336 | 332 |
337 for (i = 0; i < 0x10000; i++) { | 333 for (i = 0; i < 0x10000; i++) { |
338 a = (ngx_array_t *) ctx.high->low[i].ranges; | 334 a = (ngx_array_t *) ctx.high->low[i]; |
339 | 335 |
340 if (a == NULL || a->nelts == 0) { | 336 if (a == NULL || a->nelts == 0) { |
341 continue; | 337 continue; |
342 } | 338 } |
343 | 339 |
344 ctx.high->low[i].n = a->nelts; | |
345 | |
346 len = a->nelts * sizeof(ngx_http_geo_range_t); | 340 len = a->nelts * sizeof(ngx_http_geo_range_t); |
347 | 341 |
348 ctx.high->low[i].ranges = ngx_palloc(cf->pool, len); | 342 ctx.high->low[i] = ngx_palloc(cf->pool, len + sizeof(void *)); |
349 if (ctx.high->low[i].ranges == NULL) { | 343 if (ctx.high->low[i] == NULL) { |
350 return NGX_CONF_ERROR; | 344 return NGX_CONF_ERROR; |
351 } | 345 } |
352 | 346 |
353 ngx_memcpy(ctx.high->low[i].ranges, a->elts, len); | 347 p = (void **) ngx_cpymem(ctx.high->low[i], a->elts, len); |
348 *p = NULL; | |
354 } | 349 } |
355 | 350 |
356 geo->u.high = ctx.high; | 351 geo->u.high = ctx.high; |
357 | 352 |
358 var->get_handler = ngx_http_geo_range_variable; | 353 var->get_handler = ngx_http_geo_range_variable; |
609 | 604 |
610 } else { | 605 } else { |
611 e = 0xffff; | 606 e = 0xffff; |
612 } | 607 } |
613 | 608 |
614 a = (ngx_array_t *) ctx->high->low[h].ranges; | 609 a = (ngx_array_t *) ctx->high->low[h]; |
615 | 610 |
616 if (a == NULL) { | 611 if (a == NULL) { |
617 a = ngx_array_create(ctx->temp_pool, 64, | 612 a = ngx_array_create(ctx->temp_pool, 64, |
618 sizeof(ngx_http_geo_range_t)); | 613 sizeof(ngx_http_geo_range_t)); |
619 if (a == NULL) { | 614 if (a == NULL) { |
620 return NGX_CONF_ERROR; | 615 return NGX_CONF_ERROR; |
621 } | 616 } |
622 | 617 |
623 ctx->high->low[h].ranges = (ngx_http_geo_range_t *) a; | 618 ctx->high->low[h] = (ngx_http_geo_range_t *) a; |
624 } | 619 } |
625 | 620 |
626 i = a->nelts; | 621 i = a->nelts; |
627 range = a->elts; | 622 range = a->elts; |
628 | 623 |
806 | 801 |
807 } else { | 802 } else { |
808 e = 0xffff; | 803 e = 0xffff; |
809 } | 804 } |
810 | 805 |
811 a = (ngx_array_t *) ctx->high->low[h].ranges; | 806 a = (ngx_array_t *) ctx->high->low[h]; |
812 | 807 |
813 if (a == NULL) { | 808 if (a == NULL) { |
814 warn = 1; | 809 warn = 1; |
815 continue; | 810 continue; |
816 } | 811 } |