postgresql之内存池-GenerationContext

创建GenerationContext

MemoryContext
GenerationContextCreate(MemoryContext parent,
						const char *name,
						Size blockSize)
{
	GenerationContext *set;
...
	set = (GenerationContext *) malloc(MAXALIGN(sizeof(GenerationContext)));
...
	/* Fill in GenerationContext-specific header fields */
	set->blockSize = blockSize;
	set->block = NULL;
	dlist_init(&set->blocks);

	/* Finally, do the type-independent part of context creation */
	MemoryContextCreate((MemoryContext) set,
						T_GenerationContext,
						&GenerationMethods,
						parent,
						name);

	return (MemoryContext) set;
}

在这里插入图片描述

分配空间

分配空间大小大于block/8

  • 计算需要分配空间
  • 分配空间
  • 初始化空间
  • 将空间放入循环双向链表
if (chunk_size > set->blockSize / 8)
	{
		Size		blksize = chunk_size + Generation_BLOCKHDRSZ + Generation_CHUNKHDRSZ;

		block = (GenerationBlock *) malloc(blksize);
		if (block == NULL)
			return NULL;

		context->mem_allocated += blksize;

		/* block with a single (used) chunk */
		block->blksize = blksize;
		block->nchunks = 1;
		block->nfree = 0;

		/* the block is completely full */
		block->freeptr = block->endptr = ((char *) block) + blksize;

		chunk = (GenerationChunk *) (((char *) block) + Generation_BLOCKHDRSZ);
		chunk->block = block;
		chunk->context = set;
		chunk->size = chunk_size;
...

		/* add the block to the list of allocated blocks */
		dlist_push_head(&set->blocks, &block->node);
...
		return GenerationChunkGetPointer(chunk);
	}

在这里插入图片描述

分配空间小于等于block/8

block为空或block剩余空间不足,则创建新的block

/*
	 * Not an over-sized chunk. Is there enough space in the current block? If
	 * not, allocate a new "regular" block.
	 */
	block = set->block;

	if ((block == NULL) ||
		(block->endptr - block->freeptr) < Generation_CHUNKHDRSZ + chunk_size)
	{
		Size		blksize = set->blockSize;

		block = (GenerationBlock *) malloc(blksize);

		if (block == NULL)
			return NULL;

		context->mem_allocated += blksize;

		block->blksize = blksize;
		block->nchunks = 0;
		block->nfree = 0;

		block->freeptr = ((char *) block) + Generation_BLOCKHDRSZ;
		block->endptr = ((char *) block) + blksize;

	...
		/* add it to the doubly-linked list of blocks */
		dlist_push_head(&set->blocks, &block->node);

		/* and also use it as the current allocation block */
		set->block = block;
	}

在这里插入图片描述

分配空间

chunk = (GenerationChunk *) block->freeptr;
...
	block->nchunks += 1;
	block->freeptr += (Generation_CHUNKHDRSZ + chunk_size);
...
	chunk->block = block;
	chunk->context = set;
	chunk->size = chunk_size;

...
	return GenerationChunkGetPointer(chunk);

在这里插入图片描述

释放空间

增加nfree计数

	GenerationContext *set = (GenerationContext *) context;
	GenerationChunk *chunk = GenerationPointerGetChunk(pointer);
	GenerationBlock *block;
...
	block = chunk->block;
...
	/* Reset context to NULL in freed chunks */
	chunk->context = NULL;
...
	block->nfree += 1;

如果nfree等于nchunks,删除节点,释放空间

	/* If there are still allocated chunks in the block, we're done. */
	if (block->nfree < block->nchunks)
		return;
/*
	 * The block is empty, so let's get rid of it. First remove it from the
	 * list of blocks, then return it to malloc().
	 */
	dlist_delete(&block->node);

	/* Also make sure the block is not marked as the current block. */
	if (set->block == block)
		set->block = NULL;

	context->mem_allocated -= block->blksize;
	free(block);

销毁GenerationContext

  • 遍历blocks,删除节点,释放节点空间
  • 释放context
static void
GenerationReset(MemoryContext context)
{
	GenerationContext *set = (GenerationContext *) context;
	dlist_mutable_iter miter;
...
	dlist_foreach_modify(miter, &set->blocks)
	{
		GenerationBlock *block = dlist_container(GenerationBlock, node, miter.cur);

		dlist_delete(miter.cur);

		context->mem_allocated -= block->blksize;
...
		free(block);
	}

	set->block = NULL;
...
}
/*
 * GenerationDelete
 *		Free all memory which is allocated in the given context.
 */
static void
GenerationDelete(MemoryContext context)
{
	/* Reset to release all the GenerationBlocks */
	GenerationReset(context);
	/* And free the context header */
	free(context);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值