mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Install infrastructure for shared-memory free space map. Doesn't actually
do anything yet, but it has the necessary connections to initialization and so forth. Make some gestures towards allowing number of blocks in a relation to be BlockNumber, ie, unsigned int, rather than signed int. (I doubt I got all the places that are sloppy about it, yet.) On the way, replace the hardwired NLOCKS_PER_XACT fudge factor with a GUC variable.
This commit is contained in:
30
src/backend/storage/freespace/Makefile
Normal file
30
src/backend/storage/freespace/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Makefile--
|
||||
# Makefile for storage/freespace
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $Header: /cvsroot/pgsql/src/backend/storage/freespace/Makefile,v 1.1 2001/06/27 23:31:39 tgl Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
subdir = src/backend/storage/freespace
|
||||
top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = freespace.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
SUBSYS.o: $(OBJS)
|
||||
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
|
||||
|
||||
depend dep:
|
||||
$(CC) -MM $(CFLAGS) *.c >depend
|
||||
|
||||
clean:
|
||||
rm -f SUBSYS.o $(OBJS)
|
||||
|
||||
ifeq (depend,$(wildcard depend))
|
||||
include depend
|
||||
endif
|
||||
183
src/backend/storage/freespace/freespace.c
Normal file
183
src/backend/storage/freespace/freespace.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* freespace.c
|
||||
* POSTGRES free space map for quickly finding free space in relations
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.1 2001/06/27 23:31:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/freespace.h"
|
||||
#include "storage/itemid.h"
|
||||
#include "storage/shmem.h"
|
||||
|
||||
|
||||
/*
|
||||
* Shared free-space-map objects
|
||||
*
|
||||
* Note: we handle pointers to these items as pointers, not as SHMEM_OFFSETs.
|
||||
* This assumes that all processes accessing the map will have the shared
|
||||
* memory segment mapped at the same place in their address space.
|
||||
*/
|
||||
typedef struct FSMHeader FSMHeader;
|
||||
typedef struct FSMRelation FSMRelation;
|
||||
typedef struct FSMChunk FSMChunk;
|
||||
|
||||
/* Header for whole map */
|
||||
struct FSMHeader
|
||||
{
|
||||
HTAB *relationHash; /* hashtable of FSMRelation entries */
|
||||
FSMRelation *relationList; /* FSMRelations in order by recency of use */
|
||||
int numRelations; /* number of FSMRelations now in use */
|
||||
FSMChunk *freeChunks; /* linked list of currently-free chunks */
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-relation struct --- this is an entry in the shared hash table.
|
||||
* The hash key is the RelFileNode value (hence, we look at the physical
|
||||
* relation ID, not the logical ID, which is appropriate).
|
||||
*/
|
||||
struct FSMRelation
|
||||
{
|
||||
RelFileNode key; /* hash key (must be first) */
|
||||
FSMRelation *nextRel; /* next rel in order by recency of use */
|
||||
FSMRelation *priorRel; /* prior rel in order by recency of use */
|
||||
FSMChunk *relChunks; /* linked list of page info chunks */
|
||||
};
|
||||
|
||||
#define SHMEM_FSMHASH_KEYSIZE sizeof(RelFileNode)
|
||||
#define SHMEM_FSMHASH_DATASIZE (sizeof(FSMRelation) - SHMEM_FSMHASH_KEYSIZE)
|
||||
|
||||
#define CHUNKPAGES 32 /* each chunk can store this many pages */
|
||||
|
||||
struct FSMChunk
|
||||
{
|
||||
FSMChunk *next; /* linked-list link */
|
||||
int numPages; /* number of pages described here */
|
||||
BlockNumber pages[CHUNKPAGES]; /* page numbers within relation */
|
||||
ItemLength bytes[CHUNKPAGES]; /* free space available on each page */
|
||||
};
|
||||
|
||||
|
||||
SPINLOCK FreeSpaceLock; /* in Shmem or created in
|
||||
* CreateSpinlocks() */
|
||||
|
||||
int MaxFSMRelations; /* these are set by guc.c */
|
||||
int MaxFSMPages;
|
||||
|
||||
static FSMHeader *FreeSpaceMap; /* points to FSMHeader in shared memory */
|
||||
|
||||
|
||||
/*
|
||||
* InitFreeSpaceMap -- Initialize the freespace module.
|
||||
*
|
||||
* This must be called once during shared memory initialization.
|
||||
* It builds the empty free space map table. FreeSpaceLock must also be
|
||||
* initialized at some point, but is not touched here --- we assume there is
|
||||
* no need for locking, since only the calling process can be accessing shared
|
||||
* memory as yet. FreeSpaceShmemSize() was called previously while computing
|
||||
* the space needed for shared memory.
|
||||
*/
|
||||
void
|
||||
InitFreeSpaceMap(void)
|
||||
{
|
||||
HASHCTL info;
|
||||
FSMChunk *chunks,
|
||||
*prevchunk;
|
||||
int nchunks;
|
||||
|
||||
/* Create table header */
|
||||
FreeSpaceMap = (FSMHeader *) ShmemAlloc(sizeof(FSMHeader));
|
||||
if (FreeSpaceMap == NULL)
|
||||
elog(FATAL, "Insufficient shared memory for free space map");
|
||||
MemSet(FreeSpaceMap, 0, sizeof(FSMHeader));
|
||||
|
||||
/* Create hashtable for FSMRelations */
|
||||
info.keysize = SHMEM_FSMHASH_KEYSIZE;
|
||||
info.datasize = SHMEM_FSMHASH_DATASIZE;
|
||||
info.hash = tag_hash;
|
||||
|
||||
FreeSpaceMap->relationHash = ShmemInitHash("Free Space Map Hash",
|
||||
MaxFSMRelations / 10,
|
||||
MaxFSMRelations,
|
||||
&info,
|
||||
(HASH_ELEM | HASH_FUNCTION));
|
||||
|
||||
if (!FreeSpaceMap->relationHash)
|
||||
elog(FATAL, "Insufficient shared memory for free space map");
|
||||
|
||||
/* Allocate FSMChunks and fill up the free-chunks list */
|
||||
nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
|
||||
|
||||
chunks = (FSMChunk *) ShmemAlloc(nchunks * sizeof(FSMChunk));
|
||||
if (chunks == NULL)
|
||||
elog(FATAL, "Insufficient shared memory for free space map");
|
||||
|
||||
prevchunk = NULL;
|
||||
while (nchunks-- > 0)
|
||||
{
|
||||
chunks->next = prevchunk;
|
||||
prevchunk = chunks;
|
||||
chunks++;
|
||||
}
|
||||
FreeSpaceMap->freeChunks = prevchunk;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FreeSpaceShmemSize(void)
|
||||
{
|
||||
int size;
|
||||
int nchunks;
|
||||
|
||||
/*
|
||||
* There is no point in allowing less than one "chunk" per relation,
|
||||
* so force MaxFSMPages to be at least CHUNKPAGES * MaxFSMRelations.
|
||||
*/
|
||||
Assert(MaxFSMRelations > 0);
|
||||
if (MaxFSMPages < CHUNKPAGES * MaxFSMRelations)
|
||||
MaxFSMPages = CHUNKPAGES * MaxFSMRelations;
|
||||
|
||||
/* table header */
|
||||
size = MAXALIGN(sizeof(FSMHeader));
|
||||
|
||||
/* hash table, including the FSMRelation objects */
|
||||
size += hash_estimate_size(MaxFSMRelations,
|
||||
SHMEM_FSMHASH_KEYSIZE,
|
||||
SHMEM_FSMHASH_DATASIZE);
|
||||
|
||||
/* FSMChunk objects */
|
||||
nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
|
||||
|
||||
size += MAXALIGN(nchunks * sizeof(FSMChunk));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FreeSpaceMapForgetRel(RelFileNode *rel)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifdef FREESPACE_DEBUG
|
||||
/*
|
||||
* Dump contents of freespace map for debugging.
|
||||
*
|
||||
* We assume caller holds the FreeSpaceLock, or is otherwise unconcerned
|
||||
* about other processes.
|
||||
*/
|
||||
void
|
||||
DumpFreeSpace(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* FREESPACE_DEBUG */
|
||||
Reference in New Issue
Block a user