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