changeset 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 5d3282cfc43c
children 7a8e7576eb94
files src/http/modules/ngx_http_geo_module.c
diffstat 1 files changed, 22 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -10,20 +10,14 @@
 
 
 typedef struct {
+    ngx_http_variable_value_t       *value;
     u_short                          start;
     u_short                          end;
-    ngx_http_variable_value_t       *value;
 } ngx_http_geo_range_t;
 
 
 typedef struct {
-    ngx_http_geo_range_t            *ranges;
-    ngx_uint_t                       n;
-} ngx_http_geo_low_ranges_t;
-
-
-typedef struct {
-    ngx_http_geo_low_ranges_t        low[0x10000];
+    ngx_http_geo_range_t            *low[0x10000];
     ngx_http_variable_value_t       *default_value;
 } ngx_http_geo_high_ranges_t;
 
@@ -154,23 +148,24 @@ ngx_http_geo_range_variable(ngx_http_req
     ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
 
     in_addr_t              addr;
-    ngx_uint_t             i, n;
+    ngx_uint_t             n;
     ngx_http_geo_range_t  *range;
 
     *v = *ctx->u.high->default_value;
 
     addr = ngx_http_geo_addr(r, ctx);
 
-    range = ctx->u.high->low[addr >> 16].ranges;
-
-    n = addr & 0xffff;
+    range = ctx->u.high->low[addr >> 16];
 
-    for (i = 0; i < ctx->u.high->low[addr >> 16].n; i++) {
-        if (n >= (ngx_uint_t) range[i].start && n <= (ngx_uint_t) range[i].end)
-        {
-            *v = *range[i].value;
-            break;
-        }
+    if (range) {
+        n = addr & 0xffff;
+        do {
+            if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end)
+            {
+                *v = *range->value;
+                break;
+            }
+        } while ((++range)->value);
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -262,6 +257,7 @@ static char *
 ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     char                     *rv;
+    void                    **p;
     size_t                    len;
     ngx_str_t                *value, name;
     ngx_uint_t                i;
@@ -335,22 +331,21 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c
     if (ctx.high) {
 
         for (i = 0; i < 0x10000; i++) {
-            a = (ngx_array_t *) ctx.high->low[i].ranges;
+            a = (ngx_array_t *) ctx.high->low[i];
 
             if (a == NULL || a->nelts == 0) {
                 continue;
             }
 
-            ctx.high->low[i].n = a->nelts;
-
             len = a->nelts * sizeof(ngx_http_geo_range_t);
 
-            ctx.high->low[i].ranges = ngx_palloc(cf->pool, len);
-            if (ctx.high->low[i].ranges == NULL) {
+            ctx.high->low[i] = ngx_palloc(cf->pool, len + sizeof(void *));
+            if (ctx.high->low[i] == NULL) {
                 return NGX_CONF_ERROR;
             }
 
-            ngx_memcpy(ctx.high->low[i].ranges, a->elts, len);
+            p = (void **) ngx_cpymem(ctx.high->low[i], a->elts, len);
+            *p = NULL;
         }
 
         geo->u.high = ctx.high;
@@ -611,7 +606,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n
             e = 0xffff;
         }
 
-        a = (ngx_array_t *) ctx->high->low[h].ranges;
+        a = (ngx_array_t *) ctx->high->low[h];
 
         if (a == NULL) {
             a = ngx_array_create(ctx->temp_pool, 64,
@@ -620,7 +615,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, n
                 return NGX_CONF_ERROR;
             }
 
-            ctx->high->low[h].ranges = (ngx_http_geo_range_t *) a;
+            ctx->high->low[h] = (ngx_http_geo_range_t *) a;
         }
 
         i = a->nelts;
@@ -808,7 +803,7 @@ ngx_http_geo_delete_range(ngx_conf_t *cf
             e = 0xffff;
         }
 
-        a = (ngx_array_t *) ctx->high->low[h].ranges;
+        a = (ngx_array_t *) ctx->high->low[h];
 
         if (a == NULL) {
             warn = 1;