コード例 #1
0
ファイル: slabs.c プロジェクト: FangJianHust/memcached-1.4.15
/**
 * 内存初始化,预分配若干slab的内存空间
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const double factor, const bool prealloc)
{
    int i = POWER_SMALLEST - 1;
    //size表示申请空间的大小,其值由配置的chunk_size和单个item的大小来指定
    unsigned int size = sizeof(item) + settings.chunk_size;
    mem_limit = limit;//mem_limit是全局变量
    //支持预分配
    if (prealloc)
    {
        /* Allocate everything in a big chunk with malloc */
    	mem_base = malloc(mem_limit);//申请地址,mem_base指向申请的地址
		if (mem_base != NULL)
		{
			mem_current = mem_base;//mem_current指向当前地址
			mem_avail = mem_limit;//可用内存大小为mem_limit
		}
		else
		{//支持预分配失败
            fprintf(stderr, "Warning: Failed to allocate requested memory in"" one large chunk.\nWill allocate in smaller chunks\n");
        }
    }
    //置空slabclass数组
    memset(slabclass, 0, sizeof(slabclass));
    //开始分配,i<200 && 单个chunk的size<单个item最大大小/内存增长因子
    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor)
    {
        /* size 保证 n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES) size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);
        slabclass[i].size = size;//slab对应chunk的大小
        slabclass[i].perslab = settings.item_size_max / slabclass[i].size;//slab对应的chunk的个数
        size *= factor;//size下一个值为按增长因子的倍数增长
        if (settings.verbose > 1)
        {//如果有打开调试信息,则输出调试信息
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",i, slabclass[i].size, slabclass[i].perslab);
        }
    }
    //循环结束时,size已经增长到1M
    power_largest = i;//再增加一个slab
    slabclass[power_largest].size = settings.item_size_max;//slab的size为item_size_max
    slabclass[power_largest].perslab = 1;//chunk个数为1
    if (settings.verbose > 1)
    {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n", i, slabclass[i].size, slabclass[i].perslab);
    }
    /* for the test suite:  faking of how much we've already malloc'd */
    //读取环境变量T_MEMD_INITIAL_MALLOC的值
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc)
        {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }
    }
    if (prealloc)
    {
    	//分配每个slab的内存空间,传入最大已经初始化的最大slab编号
        slabs_preallocate(power_largest);
    }
}
コード例 #2
0
 //内存初始化,settings.maxbytes是Memcached初始启动参数指定的内存值大小,settings.factor是内存增长因子  
void slabs_init(const size_t limit, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;  // POWER_SMALLEST : slabclass数组的最小下标, 默认为1
     //size表示申请空间的大小,其值由配置的chunk_size和单个item的大小来指定  
	unsigned int size = sizeof(item) + settings.chunk_size;
    
    mem_limit = limit;//总的内存大小

    //支持预分配 
    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);//申请地址,mem_base指向申请的地址  
        if (mem_base != NULL) {
            mem_current = mem_base; //mem_current指向当前地址 
            mem_avail = mem_limit;  //可用内存大小为mem_limit  
        } else {//支持预分配失败
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }
    //初始化置空slabclass 数组
    memset(slabclass, 0, sizeof(slabclass));

     //开始分配     i<200    && 单个chunk的size 小于等于最大item/内存增长因子的大小
    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES) //size执行8byte对齐 如果有余数就是没有对齐就进行差距的相加从而达到内存对齐
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);  //字节对齐

        slabclass[i].size = size;//slab对应的chunk大小
        slabclass[i].perslab = settings.item_size_max / slabclass[i].size; //slab对应的chunk个数
        size *= factor;//size按增长因子编程下一个
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i; //如果增长完毕,size已经增长到1M
    slabclass[power_largest].size = settings.item_size_max;//再增加一个slab slab的size 为item_size_max
    slabclass[power_largest].perslab = 1;//chunk的个数为1
    if (settings.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, slabclass[i].size, slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {//读取环境变量T_MEMD_INITIAL_MALLOC的值
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

    if (prealloc) {
		 //分配每个slab的内存空间,传入最大已经初始化的最大slab编号  
        slabs_preallocate(power_largest);
    }
}
コード例 #3
0
ファイル: slabs.c プロジェクト: liucheng98/MemcachedGPU
/**
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(item) + settings.chunk_size;

    mem_limit = limit;

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);

        if (mem_base != NULL) {
            mem_current = mem_base;
            mem_avail = mem_limit;
        } else {
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }

    memset(slabclass, 0, sizeof(slabclass));

    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        slabclass[i].size = size;
        slabclass[i].perslab = settings.item_size_max / slabclass[i].size;
        size *= factor;
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i;
    slabclass[power_largest].size = settings.item_size_max;
    slabclass[power_largest].perslab = 1;
    if (settings.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, slabclass[i].size, slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

    if (prealloc) {
        slabs_preallocate(power_largest);
    }
}
コード例 #4
0
ファイル: slabs.c プロジェクト: Abioy/kitsune-memcached
/*
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const double factor) {
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(item) + settings.chunk_size;

    /* Factor of 2.0 means use the default memcached behavior */
    if (factor == 2.0 && size < 128)
        size = 128;

    mem_limit = limit;
    memset(slabclass, 0, sizeof(slabclass));

    while (++i < POWER_LARGEST && size <= POWER_BLOCK / 2) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        slabclass[i].size = size;
        slabclass[i].perslab = POWER_BLOCK / slabclass[i].size;
        size *= factor;
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %6u perslab %5u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i;
    slabclass[power_largest].size = POWER_BLOCK;
    slabclass[power_largest].perslab = 1;

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

#ifndef DONT_PREALLOC_SLABS
    {
        char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");

        if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
            slabs_preallocate(power_largest);
        }
    }
#endif
}
コード例 #5
0
ファイル: slab.cpp プロジェクト: BreezeMaker/mini-memcahced
Slab::Slab(size_t limit, double factor, struct settings* mem_setting) :
    mem_limit(limit),
    mem_malloced(0) {

    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(base_item) + mem_setting->chunk_size;
    
    slabclass temp;//only fill mem_base[0], no use
    mem_base.push_back(temp);

    while (++i < POWER_LARGEST && size <= mem_setting->item_size_max/factor) {
        //保证刚好字节对齐
        if (size % CHUNK_ALION_BYTES)
            size += CHUNK_ALION_BYTES - (size % CHUNK_ALION_BYTES);
        
        slabclass temp_slab;
        temp_slab.size = size;
        temp_slab.perslab = mem_setting->item_size_max / temp_slab.size;
        
        mem_base.push_back(temp_slab);

        size *= factor;
        if (mem_setting->verbose > 1) {
            std::cerr << "slab class " << i << ": chunk size " << temp_slab.size << " perslab " << temp_slab.perslab << std::endl; 
        }
    }

    power_largest = i;
    slabclass temp_slab;
    temp_slab.size = mem_setting->item_size_max;
    temp_slab.perslab = 1;
    mem_base.push_back(temp_slab);
    
    if (mem_setting->verbose > 1) {
        std::cerr << "slab class " << i << ": chunk size " << temp_slab.size << " perslab " << temp_slab.perslab << std::endl; 
    }

    //可以关闭
    slabs_preallocate(POWER_LARGEST);
}
コード例 #6
0
ファイル: slabs.c プロジェクト: hsharsha/memcached
/**
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
ENGINE_ERROR_CODE slabs_init(struct default_engine *engine,
                             const size_t limit,
                             const double factor,
                             const bool prealloc) {
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(hash_item) + (unsigned int)engine->config.chunk_size;

    engine->slabs.mem_limit = limit;

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        engine->slabs.mem_base = my_allocate(engine, engine->slabs.mem_limit);
        if (engine->slabs.mem_base != NULL) {
            engine->slabs.mem_current = engine->slabs.mem_base;
            engine->slabs.mem_avail = engine->slabs.mem_limit;
        } else {
            return ENGINE_ENOMEM;
        }
    }

    memset(engine->slabs.slabclass, 0, sizeof(engine->slabs.slabclass));

    while (++i < POWER_LARGEST && size <= engine->config.item_size_max / factor) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        engine->slabs.slabclass[i].size = size;
        engine->slabs.slabclass[i].perslab = (unsigned int)engine->config.item_size_max / engine->slabs.slabclass[i].size;
        size = (unsigned int)(size * factor);
        if (engine->config.verbose > 1) {
            EXTENSION_LOGGER_DESCRIPTOR *logger;
            logger = (void*)engine->server.extension->get_extension(EXTENSION_LOGGER);
            logger->log(EXTENSION_LOG_INFO, NULL,
                        "slab class %3d: chunk size %9u perslab %7u\n",
                        i, engine->slabs.slabclass[i].size,
                        engine->slabs.slabclass[i].perslab);
        }
    }

    engine->slabs.power_largest = i;
    engine->slabs.slabclass[engine->slabs.power_largest].size = (unsigned int)engine->config.item_size_max;
    engine->slabs.slabclass[engine->slabs.power_largest].perslab = 1;
    if (engine->config.verbose > 1) {
        EXTENSION_LOGGER_DESCRIPTOR *logger;
        logger = (void*)engine->server.extension->get_extension(EXTENSION_LOGGER);
        logger->log(EXTENSION_LOG_INFO, NULL,
                    "slab class %3d: chunk size %9u perslab %7u\n",
                    i, engine->slabs.slabclass[i].size,
                    engine->slabs.slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            engine->slabs.mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

#ifndef DONT_PREALLOC_SLABS
    {
        char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");

        if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
            slabs_preallocate(power_largest);
        }
    }
#endif

    return ENGINE_SUCCESS;
}
コード例 #7
0
ファイル: slabs.c プロジェクト: Khushboo1192/public-plugins
/**
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(item) + settings.chunk_size;

    /* Factor of 2.0 means use the default memcached behavior */
    if (factor == 2.0 && size < 128)
        size = 128;

    mem_limit = limit;

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);
        if (mem_base != NULL) {
            mem_current = mem_base;
            mem_avail = mem_limit;
        } else {
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }

    memset(slabclass, 0, sizeof(slabclass));

    while (++i < POWER_LARGEST && size <= POWER_BLOCK / 2) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        slabclass[i].size = size;
        slabclass[i].perslab = POWER_BLOCK / slabclass[i].size;
        size *= factor;
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %6u perslab %5u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i;
    slabclass[power_largest].size = POWER_BLOCK;
    slabclass[power_largest].perslab = 1;

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

#ifndef DONT_PREALLOC_SLABS
    {
        char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");

        if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
            slabs_preallocate(power_largest);
        }
    }
#endif
}
コード例 #8
0
ファイル: slabs.c プロジェクト: Baoxiyi-Github/Memcached
//参数factor是扩容因子,默认值是1.25
//limit参数就是memcached能分配的总内存
void slabs_init(const size_t limit, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;




//settings.chunk_size默认值为48,可以在启动memcached的时候通过-n选项设置  
//size由两部分组成: item结构体本身 和 这个item对应的数据  
//这里的数据也就是set、add命令中的那个数据.后面的循环可以看到这个size变量会  
//根据扩容因子factor慢慢扩大,所以能存储的数据长度也会变大的
    unsigned int size = sizeof(item) + settings.chunk_size;

    mem_limit = limit;//用户设置或者默认的内存最大限制



    //用户要求预分配一大块的内存,以后需要内存,就向这块内存申请
    if (prealloc) {//默认值为false
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);
        if (mem_base != NULL) {
            mem_current = mem_base;
            mem_avail = mem_limit;
        } else {
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }


    //初始化数组,这个操作很重要,数组中所有元素的成员变量值都为0了
    memset(slabclass, 0, sizeof(slabclass));



    //slabclass数组中的第一个元素并不使用  
    //settings.item_size_max是memcached支持的最大item尺寸,默认为1M(也就是网上  
    //所说的memcached存储的数据最大为1MB)。
    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)//8字节对齐
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        //这个slabclass的slab分配器能分配的item大小
        slabclass[i].size = size;

        //这个slabclass的slab分配器最多能分配多少个item(也决定了最多分配多少内存) 
        slabclass[i].perslab = settings.item_size_max / slabclass[i].size;
        size *= factor;//扩容
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i;//最大的item
    slabclass[power_largest].size = settings.item_size_max;
    slabclass[power_largest].perslab = 1;
    if (settings.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, slabclass[i].size, slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

    if (prealloc) {//预分配内存
        slabs_preallocate(power_largest);
    }
}
コード例 #9
0
ファイル: slabs.c プロジェクト: jhpark816/arcus-memcached
/**
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
ENGINE_ERROR_CODE slabs_init(struct default_engine *engine,
                             const size_t limit, const double factor, const bool prealloc)
{
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(hash_item) + engine->config.chunk_size;

    logger = engine->server.log->get_logger();

    engine->slabs.mem_limit = limit;
    engine->slabs.mem_reserved = (limit / 100) * RESERVED_SLAB_RATIO;
    if (engine->slabs.mem_reserved < (RESERVED_SLABS*engine->config.item_size_max))
        engine->slabs.mem_reserved = (RESERVED_SLABS*engine->config.item_size_max);

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        engine->slabs.mem_base = malloc(engine->slabs.mem_limit);
        if (engine->slabs.mem_base != NULL) {
            engine->slabs.mem_current = engine->slabs.mem_base;
            engine->slabs.mem_avail = engine->slabs.mem_limit;
        } else {
            return ENGINE_ENOMEM;
        }
    } else {
        engine->slabs.mem_base = NULL;
        engine->slabs.mem_current = NULL;
        engine->slabs.mem_avail = 0;
    }

    memset(engine->slabs.slabclass, 0, sizeof(engine->slabs.slabclass));

    while (++i < POWER_LARGEST && size <= engine->config.item_size_max / factor) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        engine->slabs.slabclass[i].size = size;
        engine->slabs.slabclass[i].perslab = engine->config.item_size_max / engine->slabs.slabclass[i].size;
        engine->slabs.slabclass[i].rsvd_slabs = RESERVED_SLABS;

        size *= factor;
        if (engine->config.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                    i, engine->slabs.slabclass[i].size, engine->slabs.slabclass[i].perslab);
        }
    }

    engine->slabs.power_largest = i;
    engine->slabs.slabclass[engine->slabs.power_largest].size = engine->config.item_size_max;
    engine->slabs.slabclass[engine->slabs.power_largest].perslab = 1;
    engine->slabs.slabclass[engine->slabs.power_largest].rsvd_slabs = RESERVED_SLABS;

    if (engine->config.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, engine->slabs.slabclass[i].size, engine->slabs.slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            engine->slabs.mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }
#ifndef DONT_PREALLOC_SLABS
    {
        char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");

        if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
            slabs_preallocate(power_largest);
        }
    }
#endif

    do_smmgr_init(engine);
    return ENGINE_SUCCESS;
}
コード例 #10
0
ファイル: slabs.c プロジェクト: slawomir-pryczek/memcached
/**
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const double* factors, const bool prealloc) {

    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(item) + settings.chunk_size;

    mem_limit = limit;

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);
        if (mem_base != NULL) {
            mem_current = mem_base;
            mem_avail = mem_limit;
        } else {
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }

    memset(slabclass, 0, sizeof(slabclass));

    int factor_count = 0;	// first factor is minumum value
    int factor_curr = 0;
    const double *f = factors;
    while (*f != 0) {
        factor_count++;
        f += 1;
    }

    int _perslab = -1;
    int _perslab_last = -1;
    while (i < POWER_LARGEST - 1) {

        factor_curr = (int) ( ( (double)i / (double)POWER_LARGEST ) * (double)factor_count );
        double factor = factors[factor_curr];

        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);
        
        _perslab = (int)(settings.item_size_max / size);
        if (size >= settings.item_size_max)
            break;
        if (_perslab <= 1)
            break;

        if (_perslab_last != _perslab) {
            i++;
            slabclass[i].size = size;
            slabclass[i].perslab = _perslab;

            if (settings.verbose > 1) {
                fprintf(stderr, "slab class %3d: chunk size %9u (factor #: %i) perslab %7u\n",
                 i, slabclass[i].size, factor_curr+1, slabclass[i].perslab);
            }
        }
        _perslab_last = _perslab;
       
        if (factor > 0) {
            int _newsize = size * factor;
            if (_newsize <= size)
                size += 1;
            else
                size = _newsize;
        }
        else
            size += CHUNK_ALIGN_BYTES > -factor ? CHUNK_ALIGN_BYTES : -factor;
    }

    i++;
    power_largest = i;
    slabclass[power_largest].size = settings.item_size_max;
    slabclass[power_largest].perslab = 1;
    if (settings.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, slabclass[i].size, slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

    if (prealloc) {
        slabs_preallocate(power_largest);
    }

}
コード例 #11
0
ファイル: slabs.c プロジェクト: JunBian/memcached
/**
 * 初始话整个系统的一个存储空间。
 * limit 分配内存的限制大小 0是没有限制 ,
 * factor 是增长因子,每个快大小都会使用大小是上一个块的factor大小的
 * prealloc 是否提前分配
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(item) + settings.chunk_size;

    mem_limit = limit;

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);
        if (mem_base != NULL) {
            mem_current = mem_base;
            mem_avail = mem_limit;
        } else {
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }

    memset(slabclass, 0, sizeof(slabclass));

    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {
	// item_size_max指的是每个内存快的大小,每个内存块的大小是现在在1M 大小以内的,
	// 也就是说item_size_max的大小是 1M ,详细可以查看memcached的init函数
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);
	//这个是用来确保每个size都是8的倍数

        slabclass[i].size = size;
        slabclass[i].perslab = settings.item_size_max / slabclass[i].size;
	// item_size_max是每个slab的大小
        size *= factor;
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i;// i的最后一个,也就是内存大小最大的那个slabs
    slabclass[power_largest].size = settings.item_size_max;//最后的一个大小设置为1M
    slabclass[power_largest].perslab = 1;//而已只有一个
    if (settings.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, slabclass[i].size, slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

#ifndef DONT_PREALLOC_SLABS
    {
        char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");

        if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
            slabs_preallocate(power_largest);
        }
    }
#endif
}
コード例 #12
0
/**
 * Determines the chunk sizes and initializes the slab class descriptors
 * accordingly.
 */
void slabs_init(const size_t limit, const size_t disk_cache_size, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;
    unsigned int size = sizeof(item) + settings.chunk_size;

    mem_limit = limit;
    // limit == 0 means no limit
    disk_item_mem_limit = 1;
    if (limit && disk_cache_size) {
      const size_t M = 1024 * 1024;
      // settings.average_value_len + settings.average_key_len is ensured to be greater than 0
      double k = (double)(sizeof(item) + settings.average_key_len + sizeof(DiskDataAddr)) /
          (settings.average_value_len + settings.average_key_len);
      disk_item_mem_limit = ((size_t)(disk_cache_size * k)) & ~(M - 1);
      if (disk_item_mem_limit >= limit) {
        disk_item_mem_limit = limit;
        mem_limit = 1;// 0 means unlimited, so it cannot be 0
      } else if (disk_item_mem_limit == 0) {
        disk_item_mem_limit = 1;
      } else {
        mem_limit = limit - disk_item_mem_limit;
      }
    }
    fprintf(stderr, "slabs_init: mem_limit: %lu, disk_item_mem_limit: %lu\n",
        mem_limit, disk_item_mem_limit);

    if (prealloc) {
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);
        if (mem_base != NULL) {
            mem_current = mem_base;
            mem_avail = mem_limit;
        } else {
            fprintf(stderr, "Warning: Failed to allocate requested memory in"
                    " one large chunk.\nWill allocate in smaller chunks\n");
        }
    }

    memset(slabclass, 0, sizeof(slabclass));

    while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {
        /* Make sure items are always n-byte aligned */
        if (size % CHUNK_ALIGN_BYTES)
            size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

        slabclass[i].size = size;
        slabclass[i].perslab = settings.item_size_max / slabclass[i].size;
        size *= factor;
        if (settings.verbose > 1) {
            fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                    i, slabclass[i].size, slabclass[i].perslab);
        }
    }

    power_largest = i;
    slabclass[power_largest].size = settings.item_size_max;
    slabclass[power_largest].perslab = 1;
    if (settings.verbose > 1) {
        fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",
                i, slabclass[i].size, slabclass[i].perslab);
    }

    /* for the test suite:  faking of how much we've already malloc'd */
    {
        char *t_initial_malloc = getenv("T_MEMD_INITIAL_MALLOC");
        if (t_initial_malloc) {
            mem_malloced = (size_t)atol(t_initial_malloc);
        }

    }

#ifndef DONT_PREALLOC_SLABS
    {
        char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC");

        if (pre_alloc == NULL || atoi(pre_alloc) != 0) {
            slabs_preallocate(power_largest);
        }
    }
#endif
}