comparison src/http/ngx_http_file_cache.c @ 4038:30519bb5621d stable-1.0

Merge of r3966, r3967, r3968, r3969, r3970, r3971: Cache loader improvements: The cache loader performs two tasks: inserting cache objects in inactivity list and evaluating total cache size. Reading just directory is enough for this purpose. Elimination of reading cache files saves at least one disk I/O operation per file.
author Igor Sysoev <igor@sysoev.ru>
date Mon, 29 Aug 2011 09:51:56 +0000
parents f4dd627c657f
children ee270f311dea
comparison
equal deleted inserted replaced
4037:f4dd627c657f 4038:30519bb5621d
529 rc = NGX_OK; 529 rc = NGX_OK;
530 530
531 goto done; 531 goto done;
532 } 532 }
533 533
534 if (fcn->exists) { 534 if (fcn->exists || fcn->uses >= c->min_uses) {
535 535
536 c->exists = fcn->exists; 536 c->exists = fcn->exists;
537 c->body_start = fcn->body_start; 537 if (fcn->body_start) {
538 c->body_start = fcn->body_start;
539 }
538 540
539 rc = NGX_OK; 541 rc = NGX_OK;
540 542
541 goto done; 543 goto done;
542 } 544 }
543 545
544 if (fcn->uses >= c->min_uses) { 546 rc = NGX_AGAIN;
545
546 c->exists = fcn->exists;
547 c->body_start = fcn->body_start;
548
549 rc = NGX_OK;
550
551 } else {
552 rc = NGX_AGAIN;
553 }
554 547
555 goto done; 548 goto done;
556 } 549 }
557 550
558 fcn = ngx_slab_alloc_locked(cache->shpool, 551 fcn = ngx_slab_alloc_locked(cache->shpool,
857 ngx_http_cache_t *c; 850 ngx_http_cache_t *c;
858 851
859 c = r->cache; 852 c = r->cache;
860 853
861 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 854 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
862 "http file cache send: %s", c->file.name.data); 855 "http file cache send: %s", c->file.name.data);
863 856
864 /* we need to allocate all before the header would be sent */ 857 /* we need to allocate all before the header would be sent */
865 858
866 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); 859 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
867 if (b == NULL) { 860 if (b == NULL) {
1326 1319
1327 1320
1328 static ngx_int_t 1321 static ngx_int_t
1329 ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name) 1322 ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name)
1330 { 1323 {
1331 u_char *p; 1324 u_char *p;
1332 ngx_fd_t fd; 1325 ngx_int_t n;
1333 ngx_int_t n; 1326 ngx_uint_t i;
1334 ngx_uint_t i; 1327 ngx_http_cache_t c;
1335 ngx_file_info_t fi; 1328 ngx_http_file_cache_t *cache;
1336 ngx_http_cache_t c;
1337 ngx_http_file_cache_t *cache;
1338 ngx_http_file_cache_header_t h;
1339 1329
1340 if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) { 1330 if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) {
1341 return NGX_ERROR; 1331 return NGX_ERROR;
1342 } 1332 }
1343 1333
1344 ngx_memzero(&c, sizeof(ngx_http_cache_t)); 1334 if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) {
1345
1346 fd = ngx_open_file(name->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
1347
1348 if (fd == NGX_INVALID_FILE) {
1349 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
1350 ngx_open_file_n " \"%s\" failed", name->data);
1351 return NGX_ERROR;
1352 }
1353
1354 c.file.fd = fd;
1355 c.file.name = *name;
1356 c.file.log = ctx->log;
1357
1358 n = ngx_read_file(&c.file, (u_char *) &h,
1359 sizeof(ngx_http_file_cache_header_t), 0);
1360 if (n == NGX_ERROR) {
1361 return NGX_ERROR;
1362 }
1363
1364 if ((size_t) n < sizeof(ngx_http_file_cache_header_t)) {
1365 ngx_log_error(NGX_LOG_CRIT, ctx->log, 0, 1335 ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
1366 "cache file \"%s\" is too small", name->data); 1336 "cache file \"%s\" is too small", name->data);
1367 return NGX_ERROR; 1337 return NGX_ERROR;
1368 } 1338 }
1369 1339
1340 ngx_memzero(&c, sizeof(ngx_http_cache_t));
1370 cache = ctx->data; 1341 cache = ctx->data;
1371 1342
1372 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { 1343 c.length = ctx->size;
1373 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, 1344 c.fs_size = (ctx->fs_size + cache->bsize - 1) / cache->bsize;
1374 ngx_fd_info_n " \"%s\" failed", name->data);
1375
1376 } else {
1377 c.uniq = ngx_file_uniq(&fi);
1378 c.valid_sec = h.valid_sec;
1379 c.valid_msec = h.valid_msec;
1380 c.body_start = h.body_start;
1381 c.length = ngx_file_size(&fi);
1382 c.fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
1383 }
1384
1385 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
1386 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
1387 ngx_close_file_n " \"%s\" failed", name->data);
1388 }
1389
1390 if (c.body_start == 0) {
1391 return NGX_ERROR;
1392 }
1393 1345
1394 p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN]; 1346 p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN];
1395 1347
1396 for (i = 0; i < NGX_HTTP_CACHE_KEY_LEN; i++) { 1348 for (i = 0; i < NGX_HTTP_CACHE_KEY_LEN; i++) {
1397 n = ngx_hextoi(p, 2); 1349 n = ngx_hextoi(p, 2);
1434 1386
1435 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); 1387 ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
1436 1388
1437 fcn->uses = 1; 1389 fcn->uses = 1;
1438 fcn->count = 0; 1390 fcn->count = 0;
1439 fcn->valid_msec = c->valid_msec; 1391 fcn->valid_msec = 0;
1440 fcn->error = 0; 1392 fcn->error = 0;
1441 fcn->exists = 1; 1393 fcn->exists = 1;
1442 fcn->updating = 0; 1394 fcn->updating = 0;
1443 fcn->deleting = 0; 1395 fcn->deleting = 0;
1444 fcn->uniq = c->uniq; 1396 fcn->uniq = 0;
1445 fcn->valid_sec = c->valid_sec; 1397 fcn->valid_sec = 0;
1446 fcn->body_start = c->body_start; 1398 fcn->body_start = 0;
1447 fcn->fs_size = c->fs_size; 1399 fcn->fs_size = c->fs_size;
1448 1400
1449 cache->sh->size += c->fs_size; 1401 cache->sh->size += c->fs_size;
1450 1402
1451 } else { 1403 } else {