Chinaunix首页 | 论坛 | 博客
  • 博客访问: 229636
  • 博文数量: 41
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 407
  • 用 户 组: 普通用户
  • 注册时间: 2013-06-27 13:42
文章分类

全部博文(41)

文章存档

2016年(1)

2015年(18)

2014年(22)

我的朋友

分类: 服务器与存储

2015-01-20 15:51:07


点击(此处)折叠或打开

  1. static void
  2. ngx_http_file_cache_loader(void *data)
  3. {
  4.     ngx_http_file_cache_t *cache = data;

  5.     ngx_tree_ctx_t tree;

  6.     if (!cache->sh->cold || cache->sh->loading) {
  7.         return;
  8.     }

  9.     if (!ngx_atomic_cmp_set(&cache->sh->loading, 0, ngx_pid)) {
  10.         return;
  11.     }

  12.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
  13.                    "http file cache loader");

  14.     tree.init_handler = NULL;
  15.     tree.file_handler = ngx_http_file_cache_manage_file;
  16.     tree.pre_tree_handler = ngx_http_file_cache_noop;
  17.     tree.post_tree_handler = ngx_http_file_cache_noop;
  18.     tree.spec_handler = ngx_http_file_cache_delete_file;
  19.     tree.data = cache;
  20.     tree.alloc = 0;
  21.     tree.log = ngx_cycle->log;

  22.     cache->last = ngx_current_msec;
  23.     cache->files = 0;

  24.     if (ngx_walk_tree(&tree, &cache->path->name) == NGX_ABORT) {
  25.         cache->sh->loading = 0;
  26.         return;
  27.     }

  28.     cache->sh->cold = 0;
  29.     cache->sh->loading = 0;

  30.     ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
  31.                   "http file cache: %V %.3fM, bsize: %uz",
  32.                   &cache->path->name,
  33.                   ((double) cache->sh->size * cache->bsize) / (1024 * 1024),
  34.                   cache->bsize);
  35. }


==== 最后分析ngx_walk_tree方法

/* ngx_walk_tree是递归函数,打开每层路径(dir)直到每个文件(file),根据其路径和文件名得到key,在缓存的rbtree(红黑树)里面找这个key(部分), 如果没有找到的话,就在内存中分配一个映射这个文件的node(但是不会把文件的内容进行缓存),然后插入到红黑树中和加入队列。    

             ngx_http_file_cache_loader


              ctx->file_handler=> 

              ngx_http_file_cache_manage_file=> 

              ngx_http_file_cache_add_file=>      

              ngx_http_file_cache_add 

              从n = ngx_read_file(...)函数可以看出,每个磁盘缓存文件的开头的sizeof(ngx_http_file_cache_header_t)个byte存放了跟缓存相关的信息   */

点击(此处)折叠或打开

  1. ngx_int_t
  2. ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t*tree)
  3. {
  4.     void *data, *prev;
  5.     u_char *p, *name;
  6.     size_t len;
  7.     ngx_int_t rc;
  8.     ngx_err_t err;
  9.     ngx_str_t file, buf;
  10.     ngx_dir_t dir;
  11.     ngx_str_null(&buf);
  12.     ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
  13.                    "walk tree\"%V\"", tree);
  14.     //打开name指定的目录,并将返回值以DIR*的形式赋值给dir->dir后面对该目录下所有文件的访问都可以通过dir->dir进行
  15.     if(ngx_open_dir(tree, &dir) == NGX_ERROR)
  16.     {
  17.         ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
  18.                       ngx_open_dir_n "\"%s\" failed", tree->data);
  19.         return NGX_ERROR;
  20.     }
  21.     prev = ctx->data;
  22.     if(ctx->alloc)
  23.     {
  24.         data = ngx_alloc(ctx->alloc, ctx->log);
  25.         if (data == NULL)
  26.         {
  27.             goto failed;

  28.         }
  29.         if (ctx->init_handler(data, prev) == NGX_ABORT)
  30.         {
  31.             goto failed;
  32.         }
  33.         ctx->data = data;
  34.     }
  35.     else
  36.     {
  37.         data = NULL;
  38.     }
  39.     for ( ;; )
  40.     {
  41.         ngx_set_errno(0);
  42.         //返回下一个目录进入点,并赋值给dir->de
  43.         if (ngx_read_dir(&dir) == NGX_ERROR)
  44.         {
  45.             err = ngx_errno;
  46.             if (err == NGX_ENOMOREFILES)
  47.             {
  48.                 rc = NGX_OK;
  49.             }
  50.             else
  51.             {
  52.                 ngx_log_error(NGX_LOG_CRIT,ctx->log, err,
  53.                               ngx_read_dir_n" \"%s\" failed", tree->data);
  54.                 rc = NGX_ERROR;
  55.             }
  56.             goto done;
  57.         }
  58.         len = ngx_de_namelen(&dir);
  59.         name = ngx_de_name(&dir);
  60.         ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
  61.                        "tree name%uz:\"%s\"", len, name);
  62.         if (len == 1 && name[0] == '.')
  63.         {
  64.             continue;
  65.         }
  66.         if (len == 2 && name[0] == '.' && name[1] == '.')
  67.         {
  68.             continue;
  69.         }
  70.         file.len = tree->len + 1 + len;
  71.         if (file.len + NGX_DIR_MASK_LEN > buf.len)
  72.         {
  73.             if (buf.len)
  74.             {
  75.                 ngx_free(buf.data);
  76.             }
  77.             buf.len = tree->len + 1 + len + NGX_DIR_MASK_LEN;
  78.             buf.data = ngx_alloc(buf.len + 1, ctx->log);
  79.             if (buf.data == NULL)
  80.             {
  81.                 goto failed;
  82.             }
  83.         }
  84.         p = ngx_cpymem(buf.data, tree->data, tree->len);
  85.         *p++ = '/';
  86.         ngx_memcpy(p, name, len + 1);
  87.         file.data = buf.data;
  88.         ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
  89.                        "tree path \"%s\"",file.data);
  90.         if (!dir.valid_info)
  91.         {
  92.             if (ngx_de_info(file.data, &dir) == NGX_FILE_ERROR)
  93.             {
  94.                 ngx_log_error(NGX_LOG_CRIT,ctx->log, ngx_errno,
  95.                               ngx_de_info_n" \"%s\" failed", file.data);
  96.                 continue;
  97.             }
  98.         }
  99.         //dir->de指向的是文件
  100.         if (ngx_de_is_file(&dir))
  101.         {
  102.             ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
  103.                            "tree file\"%s\"", file.data);
  104.             ctx->size = ngx_de_size(&dir);
  105.             ctx->fs_size = ngx_de_fs_size(&dir);
  106.             ctx->access = ngx_de_access(&dir);
  107.             ctx->mtime = ngx_de_mtime(&dir);
  108.             ////////////////////////////////////////////////////////////////进行索引重建 
  109.             //ngx_http_file_cache_loader中将其设置为tree.file_handler = ngx_http_file_cache_manage_file;
  110.             if (ctx->file_handler(ctx, &file) == NGX_ABORT)
  111.             {
  112.                 goto failed;
  113.             }
  114.             //dir->de指向的是目录
  115.         }
  116.         else if (ngx_de_is_dir(&dir))
  117.         {
  118.             ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
  119.                            "tree enter dir\"%s\"", file.data);
  120.             ctx->access = ngx_de_access(&dir);
  121.             ctx->mtime = ngx_de_mtime(&dir);
  122.             //其实在ngx_http_file_cache_loader方法中已经完成了注册,只是返回NGX_OK
  123.             if (ctx->pre_tree_handler(ctx, &file) == NGX_ABORT)
  124.             {
  125.                 goto failed;
  126.             }

  127.             //针对于子目录进行递归调用
  128.             if (ngx_walk_tree(ctx, &file) == NGX_ABORT)
  129.             {
  130.                 goto failed;
  131.             }
  132.             ctx->access = ngx_de_access(&dir);
  133.             ctx->mtime = ngx_de_mtime(&dir);
  134.             //其实在ngx_http_file_cache_loader方法中已经完成了注册,只是返回NGX_OK

  135.             if (ctx->post_tree_handler(ctx, &file) == NGX_ABORT)
  136.             {
  137.                 goto failed;
  138.             }
  139.         }
  140.         else
  141.         {
  142.             ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
  143.                            "tree special\"%s\"", file.data);
  144.             if (ctx->spec_handler(ctx, &file) == NGX_ABORT)
  145.             {
  146.                 goto failed;
  147.             }
  148.         }
  149.     }
  150. failed:
  151.     rc= NGX_ABORT;
  152. done:
  153.     if(buf.len)
  154.     {
  155.         ngx_free(buf.data);
  156.     }

  157.     if(data)
  158.     {
  159.         ngx_free(data);
  160.         ctx->data = prev;
  161.     }

  162.     if(ngx_close_dir(&dir) == NGX_ERROR)
  163.     {
  164.         ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
  165.                       ngx_close_dir_n "\"%s\" failed", tree->data);
  166.     }
  167.     return rc;
  168. }

阅读(1609) | 评论(0) | 转发(0) |
0

上一篇:nginx cache设计分析

下一篇:设计模式

给主人留下些什么吧!~~