Mercurial > hg > nginx
comparison src/http/ngx_http_cache.c @ 197:0b81c7a0b133
nginx-0.0.1-2003-11-27-10:45:22 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 27 Nov 2003 07:45:22 +0000 |
parents | 8dee38ea9117 |
children | a65b630b3a66 |
comparison
equal
deleted
inserted
replaced
196:11fbd0fc041d | 197:0b81c7a0b133 |
---|---|
78 | 78 |
79 return ngx_http_cache_open_file(ctx, 0); | 79 return ngx_http_cache_open_file(ctx, 0); |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) | 83 ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache, |
84 { | 84 ngx_str_t *key, uint32_t *crc) |
85 ngx_uint_t n, i; | 85 { |
86 | 86 ngx_uint_t i; |
87 ctx->crc = ngx_crc(ctx->key.data, ctx->key.len); | 87 ngx_http_cache_t *c; |
88 | 88 |
89 n = ctx->crc % ctx->hash->hash; | 89 *crc = ngx_crc(key->data, key->len); |
90 for (i = 0; i < ctx->hash->nelts; i++) { | 90 |
91 if (ctx->hash->cache[n][i].crc == ctx->crc | 91 c = cache->elts |
92 && ctx->hash->cache[n][i].key.len == ctx->key.len | 92 + *crc % cache->hash * cache->nelts * sizeof(ngx_http_cache_t); |
93 && ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data, | 93 |
94 ctx->key.len) == 0) | 94 for (i = 0; i < cache->nelts; i++) { |
95 if (c[i].crc == *crc | |
96 && c[i].key.len == key->len | |
97 && ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0) | |
95 { | 98 { |
96 ctx->cache = ctx->hash->cache[n][i].data; | 99 c[i].refs++; |
97 ctx->hash->cache[n][i].refs++; | 100 return &c[i]; |
98 return NGX_OK; | 101 } |
99 } | 102 } |
100 } | 103 |
101 | 104 return NULL; |
102 return NGX_DECLINED; | 105 } |
103 } | 106 |
104 | 107 |
105 | 108 ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache, |
106 ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r, | 109 ngx_str_t *key, uint32_t crc, |
107 ngx_http_cache_ctx_t *ctx) | 110 ngx_log_t *log) |
108 { | 111 { |
109 time_t old; | 112 time_t old; |
110 ngx_uint_t n, i; | 113 ngx_uint_t i; |
111 ngx_http_cache_entry_t *ce; | 114 ngx_http_cache_t *c, *found; |
112 | 115 |
113 old = ngx_time() + 1; | 116 old = ngx_time() + 1; |
114 ce = NULL; | 117 found = NULL; |
115 | 118 |
116 n = ctx->crc % ctx->hash->hash; | 119 c = cache->elts |
117 for (i = 0; i < ctx->hash->nelts; i++) { | 120 + crc % cache->hash * cache->nelts * sizeof(ngx_http_cache_t); |
118 if (ctx->hash->cache[n][i].key.data == NULL) { | 121 |
122 for (i = 0; i < cache->nelts; i++) { | |
123 if (c[i].key.data == NULL) { | |
119 | 124 |
120 /* a free entry is found */ | 125 /* a free entry is found */ |
121 | 126 |
122 ce = &ctx->hash->cache[n][i]; | 127 found = &c[i]; |
123 break; | 128 break; |
124 } | 129 } |
125 | 130 |
126 if (ctx->hash->cache[n][i].refs == 0 | 131 /* looking for the oldest cache entry that is not been using */ |
127 && old > ctx->hash->cache[n][i].accessed) | 132 |
128 { | 133 if (c[i].refs == 0 && old > c[i].accessed) { |
129 /* looking for the oldest cache entry that is not used right now */ | 134 |
130 | 135 old = c[i].accessed; |
131 old = ctx->hash->cache[n][i].accessed; | 136 found = &c[i]; |
132 ce = &ctx->hash->cache[n][i]; | 137 } |
133 } | 138 } |
134 } | 139 |
135 | 140 if (found) { |
136 if (ce) { | 141 if (found->key.data) { |
137 if (ce->key.data) { | 142 if (key->len > found->key.len) { |
138 if (ctx->key.len > ce->key.len) { | 143 ngx_free(found->key.data); |
139 ngx_free(ce->key.data); | 144 found->key.data = NULL; |
140 ce->key.data = NULL; | 145 } |
141 } | 146 } |
142 } | 147 |
143 | 148 if (found->key.data == NULL) { |
144 if (ce->key.data) { | 149 found->key.data = ngx_alloc(key->len, log); |
145 ce->key.data = ngx_alloc(ctx->key.len, r->connection->log); | 150 if (found->key.data == NULL) { |
146 if (ce->key.data == NULL) { | |
147 return NULL; | 151 return NULL; |
148 } | 152 } |
149 } | 153 } |
150 | 154 |
151 ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len); | 155 ngx_memcpy(found->key.data, key->data, key->len); |
152 | 156 |
153 ce->key.len = ctx->key.len; | 157 found->crc = crc; |
154 ce->crc = ctx->crc; | 158 found->key.len = key->len; |
155 } | 159 found->refs = 1; |
156 | 160 found->deleted = 0; |
157 return ce; | 161 } |
162 | |
163 return found; | |
158 } | 164 } |
159 | 165 |
160 | 166 |
161 int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) | 167 int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) |
162 { | 168 { |
371 void *parent, void *child) | 377 void *parent, void *child) |
372 { | 378 { |
373 ngx_http_cache_conf_t *prev = parent; | 379 ngx_http_cache_conf_t *prev = parent; |
374 ngx_http_cache_conf_t *conf = child; | 380 ngx_http_cache_conf_t *conf = child; |
375 | 381 |
376 if (conf->hash == NULL) { | 382 if (conf->open_files == NULL) { |
377 if (prev->hash) { | 383 if (prev->open_files) { |
378 conf->hash = prev->hash; | 384 conf->open_files = prev->open_files; |
379 | 385 |
380 } else { | 386 } else { |
381 conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t)); | 387 conf->open_files = ngx_pcalloc(cf->pool, |
382 if (conf->hash == NULL) { | 388 sizeof(ngx_http_cache_hash_t)); |
389 if (conf->open_files == NULL) { | |
383 return NGX_CONF_ERROR; | 390 return NGX_CONF_ERROR; |
384 } | 391 } |
385 | 392 |
386 conf->hash->hash = NGX_HTTP_CACHE_HASH; | 393 conf->open_files->hash = NGX_HTTP_CACHE_HASH; |
387 conf->hash->nelts = NGX_HTTP_CACHE_NELTS; | 394 conf->open_files->nelts = NGX_HTTP_CACHE_NELTS; |
388 | 395 |
389 conf->hash->cache = ngx_pcalloc(cf->pool, | 396 conf->open_files->elts = ngx_pcalloc(cf->pool, |
390 NGX_HTTP_CACHE_HASH | 397 NGX_HTTP_CACHE_HASH |
391 * NGX_HTTP_CACHE_NELTS | 398 * NGX_HTTP_CACHE_NELTS |
392 * sizeof(ngx_http_cache_entry_t)); | 399 * sizeof(ngx_http_cache_t)); |
393 if (conf->hash->cache == NULL) { | 400 if (conf->open_files->elts == NULL) { |
394 return NGX_CONF_ERROR; | 401 return NGX_CONF_ERROR; |
395 } | 402 } |
396 } | 403 } |
397 } | 404 } |
398 | 405 |
399 return NGX_CONF_OK; | 406 return NGX_CONF_OK; |
400 } | 407 } |
401 | |
402 | |
403 #if 0 | |
404 | |
405 /* | |
406 * small file in malloc()ed memory, mmap()ed file, file descriptor only, | |
407 * file access time only (to estimate could pages still be in memory), | |
408 * translated URI (ngx_http_index_hanlder), | |
409 * compiled script (ngx_http_ssi_filter). | |
410 */ | |
411 | |
412 | |
413 #define NGX_HTTP_CACHE_ENTRY_DELETED 0x00000001 | |
414 #define NGX_HTTP_CACHE_ENTRY_MMAPED 0x00000002 | |
415 | |
416 /* "/" -> "/index.html" in ngx_http_index_handler */ | |
417 #define NGX_HTTP_CACHE_ENTRY_URI 0x00000004 | |
418 | |
419 /* 301 location "/dir" -> "dir/" in ngx_http_core_handler */ | |
420 | |
421 /* compiled script in ngx_http_ssi_filter */ | |
422 #define NGX_HTTP_CACHE_ENTRY_SCRIPT 0x00000008 | |
423 | |
424 #define NGX_HTTP_CACHE_FILTER_FLAGS 0xFFFF0000 | |
425 | |
426 | |
427 typedef struct { | |
428 ngx_fd_t fd; | |
429 off_t size; | |
430 void *data; | |
431 time_t accessed; | |
432 time_t last_modified; | |
433 time_t updated; /* no needed with kqueue */ | |
434 int refs; | |
435 int flags; | |
436 } ngx_http_cache_entry_t; | |
437 | |
438 | |
439 typedef struct { | |
440 uint32_t crc; | |
441 ngx_str_t uri; | |
442 ngx_http_cache_t *cache; | |
443 } ngx_http_cache_hash_entry_t; | |
444 | |
445 | |
446 typedef struct { | |
447 ngx_http_cache_t *cache; | |
448 uint32_t crc; | |
449 int n; | |
450 } ngx_http_cache_handle_t; | |
451 | |
452 | |
453 int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash, | |
454 ngx_str_t *uri, ngx_http_cache_handle_t *h) | |
455 { | |
456 int hi; | |
457 ngx_http_cache_hash_entry_t *entry; | |
458 | |
459 h->crc = ngx_crc(uri->data, uri->len); | |
460 | |
461 hi = h->crc % cache_hash->size; | |
462 entry = cache_hash[hi].elts; | |
463 | |
464 for (i = 0; i < cache_hash[hi].nelts; i++) { | |
465 if (entry[i].crc == crc | |
466 && entry[i].uri.len == uri->len | |
467 && ngx_strncmp(entry[i].uri.data, uri->data, uri->len) == 0 | |
468 { | |
469 h->cache = entry[i].cache; | |
470 h->cache->refs++; | |
471 h->n = hi; | |
472 return NGX_OK; | |
473 } | |
474 } | |
475 | |
476 return NGX_ERROR; | |
477 } | |
478 | |
479 | |
480 /* 32-bit crc16 */ | |
481 | |
482 int ngx_crc(char *data, size_t len) | |
483 { | |
484 uint32_t sum; | |
485 | |
486 for (sum = 0; len; len--) { | |
487 /* | |
488 * gcc 2.95.2 x86 and icc 7.1.006 compile that operator | |
489 * into the single rol opcode. | |
490 * msvc 6.0sp2 compiles it into four opcodes. | |
491 */ | |
492 sum = sum >> 1 | sum << 31; | |
493 | |
494 sum += *data++; | |
495 } | |
496 | |
497 return sum; | |
498 } | |
499 | |
500 #endif |