*** ./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;
  
