*** ./src/backend/tsearch/spell.c.orig 2010-01-02 17:57:53.000000000 +0100 --- ./src/backend/tsearch/spell.c 2010-09-07 09:05:12.734260315 +0200 *************** *** 18,23 **** --- 18,30 ---- #include "tsearch/ts_locale.h" #include "utils/memutils.h" + typedef struct { + size_t size; /* size of free mem */ + void *free; /* pointer to begin of free mem */ + char data[1]; /* begin of allocated memory */ + } privateMemoryBlock; + + #define PMBHDRSZ (offsetof(privateMemoryBlock, data)) /* * Initialization requires a lot of memory that's not needed *************** *** 27,32 **** --- 34,40 ---- * for the short-lived stuff. */ static MemoryContext tmpCtx = NULL; + static privateMemoryBlock *p_memory; /* private memory for never free structures */ #define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz)) #define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz)) *************** *** 45,55 **** --- 53,95 ---- ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); + + /* initialize a group allocated memory */ + p_memory = (privateMemoryBlock *) palloc0(ALLOCSET_DEFAULT_INITSIZE + PMBHDRSZ); + p_memory->size = ALLOCSET_DEFAULT_INITSIZE; + p_memory->free = p_memory->data; } else tmpCtx = CurrentMemoryContext->firstchild; } + /* + * returns a pointer to reservated memory. This pointer must not be + * released. + */ + static void * + hold_memory(size_t size) + { + void *result; + + /* don't use a private memory for large block */ + if (size > ALLOCSET_SMALL_INITSIZE) + return palloc0(size); + + if (size > p_memory->size) + { + p_memory = (privateMemoryBlock *) palloc0(ALLOCSET_DEFAULT_INITSIZE + PMBHDRSZ); + p_memory->size = ALLOCSET_DEFAULT_INITSIZE; + p_memory->free = p_memory->data; + } + + result = p_memory->free; + p_memory->size -= MAXALIGN(size); + p_memory->free = (char *) p_memory->free + MAXALIGN(size); + + return result; + } + static char * lowerstr_ctx(char *src) { *************** *** 878,884 **** if (!nchar) return NULL; ! rs = (SPNode *) palloc0(SPNHDRSZ + nchar * sizeof(SPNodeData)); rs->length = nchar; data = rs->data; --- 918,929 ---- if (!nchar) return NULL; ! /* ! * We can significantly reduce used memory when we allocate ! * SPNodeData from preallocated memory - there are a dictionaries ! * where our memory management means a significant overhead. ! */ ! rs = (SPNode *) hold_memory(SPNHDRSZ + nchar * sizeof(SPNodeData)); rs->length = nchar; data = rs->data;