⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 localbuf.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * localbuf.c *	  local buffer manager. Fast buffer manager for temporary tables *	  or special cases when the operation is not visible to other backends. * *	  When a relation is being created, the descriptor will have rd_islocal *	  set to indicate that the local buffer manager should be used. During *	  the same transaction the relation is being created, any inserts or *	  selects from the newly created relation will use the local buffer *	  pool. rd_islocal is reset at the end of a transaction (commit/abort). *	  This is useful for queries like SELECT INTO TABLE and create index. * * Copyright (c) 1994-5, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.22 1999/05/10 00:45:36 momjian Exp $ * *------------------------------------------------------------------------- */#include <sys/types.h>#include <sys/file.h>#include <stdio.h>#include <string.h>#include <math.h>#include <signal.h>#include "postgres.h"/* declarations split between these three files */#include "storage/buf.h"#include "storage/buf_internals.h"#include "storage/bufmgr.h"#include "storage/fd.h"#include "storage/ipc.h"#include "storage/shmem.h"#include "storage/spin.h"#include "storage/smgr.h"#include "storage/lmgr.h"#include "miscadmin.h"#include "utils/builtins.h"#include "utils/hsearch.h"#include "utils/memutils.h"#include "utils/relcache.h"#include "executor/execdebug.h" /* for NDirectFileRead */#include "catalog/catalog.h"extern long int LocalBufferFlushCount;int			NLocBuffer = 64;BufferDesc *LocalBufferDescriptors = NULL;long	   *LocalRefCount = NULL;static int	nextFreeLocalBuf = 0;/*#define LBDEBUG*//* * LocalBufferAlloc - *	  allocate a local buffer. We do round robin allocation for now. */BufferDesc *LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr){	int			i;	BufferDesc *bufHdr = (BufferDesc *) NULL;	if (blockNum == P_NEW)	{		blockNum = reln->rd_nblocks;		reln->rd_nblocks++;	}	/* a low tech search for now -- not optimized for scans */	for (i = 0; i < NLocBuffer; i++)	{		if (LocalBufferDescriptors[i].tag.relId.relId == RelationGetRelid(reln) &&			LocalBufferDescriptors[i].tag.blockNum == blockNum)		{#ifdef LBDEBUG			fprintf(stderr, "LB ALLOC (%u,%d) %d\n",					RelationGetRelid(reln), blockNum, -i - 1);#endif			LocalRefCount[i]++;			*foundPtr = TRUE;			return &LocalBufferDescriptors[i];		}	}#ifdef LBDEBUG	fprintf(stderr, "LB ALLOC (%u,%d) %d\n",			RelationGetRelid(reln), blockNum, -nextFreeLocalBuf - 1);#endif	/* need to get a new buffer (round robin for now) */	for (i = 0; i < NLocBuffer; i++)	{		int			b = (nextFreeLocalBuf + i) % NLocBuffer;		if (LocalRefCount[b] == 0)		{			bufHdr = &LocalBufferDescriptors[b];			LocalRefCount[b]++;			nextFreeLocalBuf = (b + 1) % NLocBuffer;			break;		}	}	if (bufHdr == NULL)		elog(ERROR, "no empty local buffer.");	/*	 * this buffer is not referenced but it might still be dirty (the last	 * transaction to touch it doesn't need its contents but has not	 * flushed it).  if that's the case, write it out before reusing it!	 */	if (bufHdr->flags & BM_DIRTY)	{		Relation	bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);		Assert(bufrel != NULL);		/* flush this page */		smgrwrite(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum,				  (char *) MAKE_PTR(bufHdr->data));		LocalBufferFlushCount++;		RelationDecrementReferenceCount(bufrel);	}	/*	 * it's all ours now.	 */	bufHdr->tag.relId.relId = RelationGetRelid(reln);	bufHdr->tag.blockNum = blockNum;	bufHdr->flags &= ~BM_DIRTY;	/*	 * lazy memory allocation. (see MAKE_PTR for why we need to do	 * MAKE_OFFSET.)	 */	if (bufHdr->data == (SHMEM_OFFSET) 0)	{		char	   *data = (char *) malloc(BLCKSZ);		bufHdr->data = MAKE_OFFSET(data);	}	*foundPtr = FALSE;	return bufHdr;}/* * WriteLocalBuffer - *	  writes out a local buffer */intWriteLocalBuffer(Buffer buffer, bool release){	int			bufid;	Assert(BufferIsLocal(buffer));#ifdef LBDEBUG	fprintf(stderr, "LB WRITE %d\n", buffer);#endif	bufid = -(buffer + 1);	LocalBufferDescriptors[bufid].flags |= BM_DIRTY;	if (release)	{		Assert(LocalRefCount[bufid] > 0);		LocalRefCount[bufid]--;	}	return true;}/* * FlushLocalBuffer - *	  flushes a local buffer */intFlushLocalBuffer(Buffer buffer, bool release){	int			bufid;	Relation	bufrel;	BufferDesc *bufHdr;	Assert(BufferIsLocal(buffer));#ifdef LBDEBUG	fprintf(stderr, "LB FLUSH %d\n", buffer);#endif	bufid = -(buffer + 1);	bufHdr = &LocalBufferDescriptors[bufid];	bufHdr->flags &= ~BM_DIRTY;	bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);	Assert(bufrel != NULL);	smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum,			  (char *) MAKE_PTR(bufHdr->data));	LocalBufferFlushCount++;	RelationDecrementReferenceCount(bufrel);	Assert(LocalRefCount[bufid] > 0);	if (release)		LocalRefCount[bufid]--;	return true;}/* * InitLocalBuffer - *	  init the local buffer cache. Since most queries (esp. multi-user ones) *	  don't involve local buffers, we delay allocating memory for actual the *	  buffer until we need it. */voidInitLocalBuffer(void){	int			i;	/*	 * these aren't going away. I'm not gonna use palloc.	 */	LocalBufferDescriptors =		(BufferDesc *) malloc(sizeof(BufferDesc) * NLocBuffer);	MemSet(LocalBufferDescriptors, 0, sizeof(BufferDesc) * NLocBuffer);	nextFreeLocalBuf = 0;	for (i = 0; i < NLocBuffer; i++)	{		BufferDesc *buf = &LocalBufferDescriptors[i];		/*		 * negative to indicate local buffer. This is tricky: shared		 * buffers start with 0. We have to start with -2. (Note that the		 * routine BufferDescriptorGetBuffer adds 1 to buf_id so our first		 * buffer id is -1.)		 */		buf->buf_id = -i - 2;	}	LocalRefCount = (long *) malloc(sizeof(long) * NLocBuffer);	MemSet(LocalRefCount, 0, sizeof(long) * NLocBuffer);}/* * LocalBufferSync - *	  flush all dirty buffers in the local buffer cache. Since the buffer *	  cache is only used for keeping relations visible during a transaction, *	  we will not need these buffers again. */voidLocalBufferSync(void){	int			i;	for (i = 0; i < NLocBuffer; i++)	{		BufferDesc *buf = &LocalBufferDescriptors[i];		Relation	bufrel;		if (buf->flags & BM_DIRTY)		{#ifdef LBDEBUG			fprintf(stderr, "LB SYNC %d\n", -i - 1);#endif			bufrel = RelationIdCacheGetRelation(buf->tag.relId.relId);			Assert(bufrel != NULL);			smgrwrite(DEFAULT_SMGR, bufrel, buf->tag.blockNum,					  (char *) MAKE_PTR(buf->data));			LocalBufferFlushCount++;			RelationDecrementReferenceCount(bufrel);			buf->tag.relId.relId = InvalidOid;			buf->flags &= ~BM_DIRTY;		}	}	MemSet(LocalRefCount, 0, sizeof(long) * NLocBuffer);	nextFreeLocalBuf = 0;}voidResetLocalBufferPool(void){	int			i;	for (i = 0; i < NLocBuffer; i++)	{		BufferDesc *buf = &LocalBufferDescriptors[i];		buf->tag.relId.relId = InvalidOid;		buf->flags &= ~BM_DIRTY;		buf->buf_id = -i - 2;	}	MemSet(LocalRefCount, 0, sizeof(long) * NLocBuffer);	nextFreeLocalBuf = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -