comparison src/http/ngx_http_cache.c @ 195:8dee38ea9117

nginx-0.0.1-2003-11-25-23:44:56 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 25 Nov 2003 20:44:56 +0000
parents 71ce40b3c37b
children 0b81c7a0b133
comparison
equal deleted inserted replaced
194:2357fa41738a 195:8dee38ea9117
11 #define MD5Update MD5_Update 11 #define MD5Update MD5_Update
12 #define MD5Final MD5_Final 12 #define MD5Final MD5_Final
13 #endif 13 #endif
14 14
15 15
16 static int ngx_crc(char *data, size_t len);
17
18 static void *ngx_http_cache_create_conf(ngx_conf_t *cf);
19 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
20 void *parent, void *child);
21
22
23 static ngx_http_module_t ngx_http_cache_module_ctx = {
24 NULL, /* pre conf */
25
26 NULL, /* create main configuration */
27 NULL, /* init main configuration */
28
29 NULL, /* create server configuration */
30 NULL, /* merge server configuration */
31
32 ngx_http_cache_create_conf, /* create location configuration */
33 ngx_http_core_merge_loc_conf /* merge location configuration */
34 };
35
36
37 ngx_module_t ngx_http_cache_module = {
38 NGX_MODULE,
39 &ngx_http_cache_module_ctx, /* module context */
40 NULL, /* module directives */
41 NGX_HTTP_MODULE, /* module type */
42 NULL, /* init module */
43 NULL /* init child */
44 };
45
46
47
16 int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) 48 int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
17 { 49 {
18 MD5_CTX md5; 50 MD5_CTX md5;
19 51
20 ctx->header_size = sizeof(ngx_http_cache_header_t) + ctx->key.len + 1; 52 /* we use offsetof() because sizeof() pads struct size to int size */
53 ctx->header_size = offsetof(ngx_http_cache_header_t, key)
54 + ctx->key.len + 1;
21 55
22 ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32; 56 ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32;
23 if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) { 57 if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) {
24 return NGX_ERROR; 58 return NGX_ERROR;
25 } 59 }
44 78
45 return ngx_http_cache_open_file(ctx, 0); 79 return ngx_http_cache_open_file(ctx, 0);
46 } 80 }
47 81
48 82
49 /* TODO: Win32 inode analogy */ 83 int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
84 {
85 ngx_uint_t n, i;
86
87 ctx->crc = ngx_crc(ctx->key.data, ctx->key.len);
88
89 n = ctx->crc % ctx->hash->hash;
90 for (i = 0; i < ctx->hash->nelts; i++) {
91 if (ctx->hash->cache[n][i].crc == ctx->crc
92 && ctx->hash->cache[n][i].key.len == ctx->key.len
93 && ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data,
94 ctx->key.len) == 0)
95 {
96 ctx->cache = ctx->hash->cache[n][i].data;
97 ctx->hash->cache[n][i].refs++;
98 return NGX_OK;
99 }
100 }
101
102 return NGX_DECLINED;
103 }
104
105
106 ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r,
107 ngx_http_cache_ctx_t *ctx)
108 {
109 time_t old;
110 ngx_uint_t n, i;
111 ngx_http_cache_entry_t *ce;
112
113 old = ngx_time() + 1;
114 ce = NULL;
115
116 n = ctx->crc % ctx->hash->hash;
117 for (i = 0; i < ctx->hash->nelts; i++) {
118 if (ctx->hash->cache[n][i].key.data == NULL) {
119
120 /* a free entry is found */
121
122 ce = &ctx->hash->cache[n][i];
123 break;
124 }
125
126 if (ctx->hash->cache[n][i].refs == 0
127 && old > ctx->hash->cache[n][i].accessed)
128 {
129 /* looking for the oldest cache entry that is not used right now */
130
131 old = ctx->hash->cache[n][i].accessed;
132 ce = &ctx->hash->cache[n][i];
133 }
134 }
135
136 if (ce) {
137 if (ce->key.data) {
138 if (ctx->key.len > ce->key.len) {
139 ngx_free(ce->key.data);
140 ce->key.data = NULL;
141 }
142 }
143
144 if (ce->key.data) {
145 ce->key.data = ngx_alloc(ctx->key.len, r->connection->log);
146 if (ce->key.data == NULL) {
147 return NULL;
148 }
149 }
150
151 ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len);
152
153 ce->key.len = ctx->key.len;
154 ce->crc = ctx->crc;
155 }
156
157 return ce;
158 }
159
50 160
51 int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) 161 int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq)
52 { 162 {
53 ssize_t n; 163 ssize_t n;
54 ngx_err_t err; 164 ngx_err_t err;
136 246
137 return NGX_OK; 247 return NGX_OK;
138 } 248 }
139 249
140 250
141 int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
142 ngx_dir_t *dir)
143 {
144 int rc;
145 char data[sizeof(ngx_http_cache_header_t)];
146 ngx_hunk_t buf;
147 ngx_http_cache_ctx_t ctx;
148
149 ctx.file.fd = NGX_INVALID_FILE;
150 ctx.file.name = *name;
151 ctx.file.log = gc->log;
152
153 ctx.header_size = sizeof(ngx_http_cache_header_t);
154 ctx.buf = &buf;
155 ctx.log = gc->log;
156 ctx.key.len = 0;
157
158 buf.type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
159 buf.pos = data;
160 buf.last = data;
161 buf.start = data;
162 buf.end = data + sizeof(ngx_http_cache_header_t);
163
164 rc = ngx_http_cache_open_file(&ctx, 0);
165
166 /* TODO: NGX_AGAIN */
167
168 if (rc != NGX_ERROR && rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) {
169 return NGX_OK;
170 }
171
172 if (ngx_delete_file(name->data) == NGX_FILE_ERROR) {
173 ngx_log_error(NGX_LOG_CRIT, gc->log, ngx_errno,
174 ngx_delete_file_n " \"%s\" failed", name->data);
175 return NGX_ERROR;
176 }
177
178 gc->deleted++;
179 gc->freed += ngx_de_size(dir);
180
181 return NGX_OK;
182 }
183
184
185 int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, 251 int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
186 ngx_str_t *temp_file) 252 ngx_str_t *temp_file)
187 { 253 {
188 int retry; 254 int retry;
189 ngx_err_t err; 255 ngx_err_t err;
219 return NGX_ERROR; 285 return NGX_ERROR;
220 } 286 }
221 287
222 retry = 1; 288 retry = 1;
223 } 289 }
290 }
291
292
293 int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
294 ngx_dir_t *dir)
295 {
296 int rc;
297 char data[sizeof(ngx_http_cache_header_t)];
298 ngx_hunk_t buf;
299 ngx_http_cache_ctx_t ctx;
300
301 ctx.file.fd = NGX_INVALID_FILE;
302 ctx.file.name = *name;
303 ctx.file.log = gc->log;
304
305 ctx.header_size = sizeof(ngx_http_cache_header_t);
306 ctx.buf = &buf;
307 ctx.log = gc->log;
308 ctx.key.len = 0;
309
310 buf.type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
311 buf.pos = data;
312 buf.last = data;
313 buf.start = data;
314 buf.end = data + sizeof(ngx_http_cache_header_t);
315
316 rc = ngx_http_cache_open_file(&ctx, 0);
317
318 /* TODO: NGX_AGAIN */
319
320 if (rc != NGX_ERROR && rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) {
321 return NGX_OK;
322 }
323
324 if (ngx_delete_file(name->data) == NGX_FILE_ERROR) {
325 ngx_log_error(NGX_LOG_CRIT, gc->log, ngx_errno,
326 ngx_delete_file_n " \"%s\" failed", name->data);
327 return NGX_ERROR;
328 }
329
330 gc->deleted++;
331 gc->freed += ngx_de_size(dir);
332
333 return NGX_OK;
334 }
335
336
337 /* 32-bit crc16 */
338
339 static int ngx_crc(char *data, size_t len)
340 {
341 uint32_t sum;
342
343 for (sum = 0; len; len--) {
344 /*
345 * gcc 2.95.2 x86 and icc 7.1.006 compile that operator
346 * into the single rol opcode.
347 * msvc 6.0sp2 compiles it into four opcodes.
348 */
349 sum = sum >> 1 | sum << 31;
350
351 sum += *data++;
352 }
353
354 return sum;
355 }
356
357
358 static void *ngx_http_cache_create_conf(ngx_conf_t *cf)
359 {
360 ngx_http_cache_conf_t *conf;
361
362 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_conf_t)))) {
363 return NGX_CONF_ERROR;
364 }
365
366 return conf;
367 }
368
369
370 static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
371 void *parent, void *child)
372 {
373 ngx_http_cache_conf_t *prev = parent;
374 ngx_http_cache_conf_t *conf = child;
375
376 if (conf->hash == NULL) {
377 if (prev->hash) {
378 conf->hash = prev->hash;
379
380 } else {
381 conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t));
382 if (conf->hash == NULL) {
383 return NGX_CONF_ERROR;
384 }
385
386 conf->hash->hash = NGX_HTTP_CACHE_HASH;
387 conf->hash->nelts = NGX_HTTP_CACHE_NELTS;
388
389 conf->hash->cache = ngx_pcalloc(cf->pool,
390 NGX_HTTP_CACHE_HASH
391 * NGX_HTTP_CACHE_NELTS
392 * sizeof(ngx_http_cache_entry_t));
393 if (conf->hash->cache == NULL) {
394 return NGX_CONF_ERROR;
395 }
396 }
397 }
398
399 return NGX_CONF_OK;
224 } 400 }
225 401
226 402
227 #if 0 403 #if 0
228 404
259 int flags; 435 int flags;
260 } ngx_http_cache_entry_t; 436 } ngx_http_cache_entry_t;
261 437
262 438
263 typedef struct { 439 typedef struct {
264 u_int32_t crc; 440 uint32_t crc;
265 ngx_str_t uri; 441 ngx_str_t uri;
266 ngx_http_cache_t *cache; 442 ngx_http_cache_t *cache;
267 } ngx_http_cache_hash_entry_t; 443 } ngx_http_cache_hash_entry_t;
268 444
269 445
270 typedef struct { 446 typedef struct {
271 ngx_http_cache_t *cache; 447 ngx_http_cache_t *cache;
272 u_int32_t crc; 448 uint32_t crc;
273 int n; 449 int n;
274 } ngx_http_cache_handle_t; 450 } ngx_http_cache_handle_t;
275 451
276 452
277 int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash, 453 int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash,
303 479
304 /* 32-bit crc16 */ 480 /* 32-bit crc16 */
305 481
306 int ngx_crc(char *data, size_t len) 482 int ngx_crc(char *data, size_t len)
307 { 483 {
308 u_int32_t sum; 484 uint32_t sum;
309 485
310 for (sum = 0; len; len--) { 486 for (sum = 0; len; len--) {
311 /* 487 /*
312 * gcc 2.95.2 x86 and icc 7.1.006 compile that operator 488 * gcc 2.95.2 x86 and icc 7.1.006 compile that operator
313 * into the single rol opcode. 489 * into the single rol opcode.