Nginx源代码分析--基本数据结构--hash

    技术2022-05-20  58

          Nginx对内存的使用极其苛刻,达到了令人呕吐的地步。

     

          这里仅仅分析一个hash桶的映射过程中的一小步骤:

     

          计算映射一个数组到hash桶的时候,所需要的桶的多少。

     

     

     

     

     

    这是图:

     

     

     

    源代码:

     

          //假定需要的桶多少是start,由于max_size是桶的最大大小,所以最多就是hinit->max_size

          //该函数是进行测试,预想的大小是否可以满足桶的大小的实际需求

     

     

          for (size = start; size < hinit->max_size; size++) {

     

            //在计算过程中,根本没另外分配内存来存放计算出的每个桶已经”预定放入”的k-v键值对占用内存的多少。

           //而是每次使用test这个内存的前size(预想的桶多少)个字节来进行存储。

            ngx_memzero(test, size * sizeof(u_short));           for (n = 0; n < nelts; n++) {             if (names[n].key.data == NULL) {                 continue;             }

     

                //通过取余运算获知,在当前的预想的桶个数情况下,应该分配到哪个桶。

                key = names[n].key_hash % size;

     

               //将该桶的k-v占用内存计数增加

                test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));

     

       //log级别相关

    #if 0             ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,                           "%ui: %ui %ui /"%V/"",                           size, key, test[key], &names[n].key); #endif         //该桶的k-v占用内存太多了,则进入next,也就是桶数需要增加

                if (test[key] > (u_short) bucket_size) {                 goto next;             }         }

     

            //成功的计算完成,去found进一步处理计算结果,即包括需要的桶数和每个桶的k-v需要的内存大小

            goto found;

     

         //桶的内存超过限定的时候,进入下一次循环的地方(下一次循环,即试探将桶+1是否可以)     next:         continue;     }

     

     

     

     

    虽然处理并不复杂,但是整个通过其不完全符合面向对象逻辑的处理,可以看出作者对内存使用的用心。

     

     


    最新回复(0)