diff options
Diffstat (limited to 'src/backend/storage/buffer/localbuf.c')
-rw-r--r-- | src/backend/storage/buffer/localbuf.c | 370 |
1 files changed, 190 insertions, 180 deletions
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 910cb668d7a..072830b3dd6 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -1,21 +1,21 @@ /*------------------------------------------------------------------------- * * localbuf.c-- - * local buffer manager. Fast buffer manager for temporary tables - * or special cases when the operation is not visible to other backends. + * 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. + * 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: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.8 1997/07/28 00:54:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.9 1997/09/07 04:48:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -45,252 +45,262 @@ #include "utils/hsearch.h" #include "utils/memutils.h" #include "utils/relcache.h" -#include "executor/execdebug.h" /* for NDirectFileRead */ +#include "executor/execdebug.h" /* for NDirectFileRead */ #include "catalog/catalog.h" extern long int LocalBufferFlushCount; -int NLocBuffer = 64; -BufferDesc *LocalBufferDescriptors = NULL; -long *LocalRefCount = NULL; +int NLocBuffer = 64; +BufferDesc *LocalBufferDescriptors = NULL; +long *LocalRefCount = NULL; -static int nextFreeLocalBuf = 0; +static int nextFreeLocalBuf = 0; /*#define LBDEBUG*/ /* * LocalBufferAlloc - - * allocate a local buffer. We do round robin allocation for now. + * allocate a local buffer. We do round robin allocation for now. */ -BufferDesc * -LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) +BufferDesc * +LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool * foundPtr) { - int i; - BufferDesc *bufHdr = (BufferDesc *) NULL; + int i; + BufferDesc *bufHdr = (BufferDesc *) NULL; - if (blockNum == P_NEW) { - blockNum = reln->rd_nblocks; - reln->rd_nblocks++; - } + 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 == reln->rd_id && - LocalBufferDescriptors[i].tag.blockNum == blockNum) { + /* a low tech search for now -- not optimized for scans */ + for (i = 0; i < NLocBuffer; i++) + { + if (LocalBufferDescriptors[i].tag.relId.relId == reln->rd_id && + LocalBufferDescriptors[i].tag.blockNum == blockNum) + { #ifdef LBDEBUG - fprintf(stderr, "LB ALLOC (%d,%d) %d\n", - reln->rd_id, blockNum, -i-1); -#endif - LocalRefCount[i]++; - *foundPtr = TRUE; - return &LocalBufferDescriptors[i]; + fprintf(stderr, "LB ALLOC (%d,%d) %d\n", + reln->rd_id, blockNum, -i - 1); +#endif + LocalRefCount[i]++; + *foundPtr = TRUE; + return &LocalBufferDescriptors[i]; + } } - } #ifdef LBDEBUG - fprintf(stderr, "LB ALLOC (%d,%d) %d\n", - reln->rd_id, 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; + fprintf(stderr, "LB ALLOC (%d,%d) %d\n", + reln->rd_id, 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(WARN, "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); + if (bufHdr == NULL) + elog(WARN, "no empty local buffer."); - Assert(bufrel != NULL); - - /* flush this page */ - smgrwrite(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum, - (char *) MAKE_PTR(bufHdr->data)); - LocalBufferFlushCount++; - } - - /* - * it's all ours now. - */ - bufHdr->tag.relId.relId = reln->rd_id; - 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; + /* + * 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(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum, + (char *) MAKE_PTR(bufHdr->data)); + LocalBufferFlushCount++; + } + + /* + * it's all ours now. + */ + bufHdr->tag.relId.relId = reln->rd_id; + 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 + * writes out a local buffer */ int WriteLocalBuffer(Buffer buffer, bool release) { - int bufid; + int bufid; - Assert(BufferIsLocal(buffer)); + Assert(BufferIsLocal(buffer)); #ifdef LBDEBUG - fprintf(stderr, "LB WRITE %d\n", buffer); -#endif - - bufid = - (buffer + 1); - LocalBufferDescriptors[bufid].flags |= BM_DIRTY; + fprintf(stderr, "LB WRITE %d\n", buffer); +#endif - if (release) { - Assert(LocalRefCount[bufid] > 0); - LocalRefCount[bufid]--; - } + bufid = -(buffer + 1); + LocalBufferDescriptors[bufid].flags |= BM_DIRTY; + + if (release) + { + Assert(LocalRefCount[bufid] > 0); + LocalRefCount[bufid]--; + } - return true; + return true; } /* * FlushLocalBuffer - - * flushes a local buffer + * flushes a local buffer */ int FlushLocalBuffer(Buffer buffer, bool release) { - int bufid; - Relation bufrel; - BufferDesc *bufHdr; + int bufid; + Relation bufrel; + BufferDesc *bufHdr; - Assert(BufferIsLocal(buffer)); + 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(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum, - (char *) MAKE_PTR(bufHdr->data)); - LocalBufferFlushCount++; - - Assert(LocalRefCount[bufid] > 0); - if ( release ) - LocalRefCount[bufid]--; - - return true; + 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(bufrel->rd_rel->relsmgr, bufrel, bufHdr->tag.blockNum, + (char *) MAKE_PTR(bufHdr->data)); + LocalBufferFlushCount++; + + 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. + * 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. */ void InitLocalBuffer(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]; + int 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.) + * these aren't going away. I'm not gonna use palloc. */ - buf->buf_id = - i - 2; - } + 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); + 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. + * 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. */ void LocalBufferSync(void) { - int i; - - for (i = 0; i < NLocBuffer; i++) { - BufferDesc *buf = &LocalBufferDescriptors[i]; - Relation bufrel; + int i; + + for (i = 0; i < NLocBuffer; i++) + { + BufferDesc *buf = &LocalBufferDescriptors[i]; + Relation bufrel; - if (buf->flags & BM_DIRTY) { + 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(bufrel->rd_rel->relsmgr, bufrel, buf->tag.blockNum, - (char *) MAKE_PTR(buf->data)); - LocalBufferFlushCount++; - - buf->tag.relId.relId = InvalidOid; - buf->flags &= ~BM_DIRTY; + fprintf(stderr, "LB SYNC %d\n", -i - 1); +#endif + bufrel = RelationIdCacheGetRelation(buf->tag.relId.relId); + + Assert(bufrel != NULL); + + smgrwrite(bufrel->rd_rel->relsmgr, bufrel, buf->tag.blockNum, + (char *) MAKE_PTR(buf->data)); + LocalBufferFlushCount++; + + buf->tag.relId.relId = InvalidOid; + buf->flags &= ~BM_DIRTY; + } } - } - memset(LocalRefCount, 0, sizeof(long) * NLocBuffer); - nextFreeLocalBuf = 0; + memset(LocalRefCount, 0, sizeof(long) * NLocBuffer); + nextFreeLocalBuf = 0; } void ResetLocalBufferPool(void) { - int i; + int i; - for (i = 0; i < NLocBuffer; i++) - { - BufferDesc *buf = &LocalBufferDescriptors[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; - } + buf->tag.relId.relId = InvalidOid; + buf->flags &= ~BM_DIRTY; + buf->buf_id = -i - 2; + } - memset(LocalRefCount, 0, sizeof(long) * NLocBuffer); - nextFreeLocalBuf = 0; + memset(LocalRefCount, 0, sizeof(long) * NLocBuffer); + nextFreeLocalBuf = 0; } |