simple_alloc.diff
application/octet-stream
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/tsearch/dict_ispell.c | 21 | 5 |
| src/backend/tsearch/spell.c | 81 | 37 |
| src/backend/utils/mmgr/Makefile | 1 | 1 |
| src/backend/utils/mmgr/simple_alloc.c | 308 | 0 |
| src/include/nodes/memnodes.h | 1 | 1 |
| src/include/nodes/nodes.h | 1 | 0 |
| src/include/tsearch/dicts/spell.h | 4 | 4 |
| src/include/utils/memutils.h | 8 | 0 |
*** ./src/backend/tsearch/dict_ispell.c.orig 2010-03-15 15:10:31.997321968 +0100
--- ./src/backend/tsearch/dict_ispell.c 2010-03-15 15:17:33.726323706 +0100
***************
*** 38,43 ****
--- 38,46 ----
stoploaded = false;
ListCell *l;
+ MemoryContext simple_ctx = NULL;
+ MemoryContext temp_ctx = NULL;
+
d = (DictISpell *) palloc0(sizeof(DictISpell));
foreach(l, dictoptions)
***************
*** 52,58 ****
errmsg("multiple DictFile parameters")));
NIImportDictionary(&(d->obj),
get_tsearch_config_filename(defGetString(defel),
! "dict"));
dictloaded = true;
}
else if (pg_strcasecmp(defel->defname, "AffFile") == 0)
--- 55,63 ----
errmsg("multiple DictFile parameters")));
NIImportDictionary(&(d->obj),
get_tsearch_config_filename(defGetString(defel),
! "dict"),
! &simple_ctx,
! &temp_ctx);
dictloaded = true;
}
else if (pg_strcasecmp(defel->defname, "AffFile") == 0)
***************
*** 63,69 ****
errmsg("multiple AffFile parameters")));
NIImportAffixes(&(d->obj),
get_tsearch_config_filename(defGetString(defel),
! "affix"));
affloaded = true;
}
else if (pg_strcasecmp(defel->defname, "StopWords") == 0)
--- 68,76 ----
errmsg("multiple AffFile parameters")));
NIImportAffixes(&(d->obj),
get_tsearch_config_filename(defGetString(defel),
! "affix"),
! &simple_ctx,
! &temp_ctx);
affloaded = true;
}
else if (pg_strcasecmp(defel->defname, "StopWords") == 0)
***************
*** 86,93 ****
if (affloaded && dictloaded)
{
! NISortDictionary(&(d->obj));
! NISortAffixes(&(d->obj));
}
else if (!affloaded)
{
--- 93,100 ----
if (affloaded && dictloaded)
{
! NISortDictionary(&(d->obj), &simple_ctx, &temp_ctx);
! NISortAffixes(&(d->obj), &simple_ctx, &temp_ctx);
}
else if (!affloaded)
{
***************
*** 102,108 ****
errmsg("missing DictFile parameter")));
}
! MemoryContextDeleteChildren(CurrentMemoryContext);
PG_RETURN_POINTER(d);
}
--- 109,124 ----
errmsg("missing DictFile parameter")));
}
! fprintf(stderr,"final\n");
! MemoryContextStats(CurrentMemoryContext);
!
! if (temp_ctx != NULL)
! MemoryContextDelete(temp_ctx);
!
! fprintf(stderr,"super final\n");
! MemoryContextStats(CurrentMemoryContext);
!
!
PG_RETURN_POINTER(d);
}
*** ./src/backend/tsearch/spell.c.orig 2010-01-02 17:57:53.000000000 +0100
--- ./src/backend/tsearch/spell.c 2010-03-15 17:53:33.092448863 +0100
***************
*** 27,53 ****
* for the short-lived stuff.
*/
static MemoryContext tmpCtx = NULL;
#define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
#define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
static void
! checkTmpCtx(void)
{
/*
* XXX: This assumes that CurrentMemoryContext doesn't have any children
* other than the one we create here.
*/
! if (CurrentMemoryContext->firstchild == NULL)
{
! tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
"Ispell dictionary init context",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
}
else
! tmpCtx = CurrentMemoryContext->firstchild;
}
static char *
--- 27,69 ----
* for the short-lived stuff.
*/
static MemoryContext tmpCtx = NULL;
+ static MemoryContext simple_tmpCtx = NULL;
#define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
#define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
+ #define tmp_simple_alloc(sz) MemoryContextAlloc(simple_tmpCtx, (sz))
+ #define tmp_simple_alloc0(sz) MemoryContextAllocZero(simple_tmpCtx, (sz))
+
+
+
static void
! checkTmpCtx(MemoryContext *temp_ctx)
{
/*
* XXX: This assumes that CurrentMemoryContext doesn't have any children
* other than the one we create here.
*/
! if (*temp_ctx == NULL)
{
! *temp_ctx = AllocSetContextCreate(CurrentMemoryContext,
"Ispell dictionary init context",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
+ tmpCtx = *temp_ctx;
+
+ simple_tmpCtx = SimpleAllocContextCreate(tmpCtx,
+ "Ispell dictionary simple init context",
+ SIMPLEALLOC_LARGE_INITSIZE,
+ malloc,
+ free);
}
else
! {
! tmpCtx = *temp_ctx;
! simple_tmpCtx = tmpCtx->firstchild;
! }
}
static char *
***************
*** 179,185 ****
Conf->Spell = (SPELL **) tmpalloc(Conf->mspell * sizeof(SPELL *));
}
}
! Conf->Spell[Conf->nspell] = (SPELL *) tmpalloc(SPELLHDRSZ + strlen(word) + 1);
strcpy(Conf->Spell[Conf->nspell]->word, word);
strncpy(Conf->Spell[Conf->nspell]->p.flag, flag, MAXFLAGLEN);
Conf->nspell++;
--- 195,201 ----
Conf->Spell = (SPELL **) tmpalloc(Conf->mspell * sizeof(SPELL *));
}
}
! Conf->Spell[Conf->nspell] = (SPELL *) tmp_simple_alloc(SPELLHDRSZ + strlen(word) + 1);
strcpy(Conf->Spell[Conf->nspell]->word, word);
strncpy(Conf->Spell[Conf->nspell]->p.flag, flag, MAXFLAGLEN);
Conf->nspell++;
***************
*** 191,202 ****
* Note caller must already have applied get_tsearch_config_filename
*/
void
! NIImportDictionary(IspellDict *Conf, const char *filename)
{
tsearch_readline_state trst;
char *line;
! checkTmpCtx();
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
--- 207,218 ----
* Note caller must already have applied get_tsearch_config_filename
*/
void
! NIImportDictionary(IspellDict *Conf, const char *filename, MemoryContext *simple_ctx, MemoryContext *temp_ctx)
{
tsearch_readline_state trst;
char *line;
! checkTmpCtx(temp_ctx);
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
***************
*** 344,357 ****
Affix->issimple = 0;
Affix->isregis = 0;
! tmask = (char *) tmpalloc(strlen(mask) + 3);
if (type == FF_SUFFIX)
sprintf(tmask, "%s$", mask);
else
sprintf(tmask, "^%s", mask);
masklen = strlen(tmask);
! wmask = (pg_wchar *) tmpalloc((masklen + 1) * sizeof(pg_wchar));
wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen);
err = pg_regcomp(&(Affix->reg.regex), wmask, wmasklen, REG_ADVANCED | REG_NOSUB);
--- 360,373 ----
Affix->issimple = 0;
Affix->isregis = 0;
! tmask = (char *) tmp_simple_alloc(strlen(mask) + 3);
if (type == FF_SUFFIX)
sprintf(tmask, "%s$", mask);
else
sprintf(tmask, "^%s", mask);
masklen = strlen(tmask);
! wmask = (pg_wchar *) tmp_simple_alloc((masklen + 1) * sizeof(pg_wchar));
wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen);
err = pg_regcomp(&(Affix->reg.regex), wmask, wmasklen, REG_ADVANCED | REG_NOSUB);
***************
*** 526,532 ****
}
static void
! NIImportOOAffixes(IspellDict *Conf, const char *filename)
{
char type[BUFSIZ],
*ptype = NULL;
--- 542,548 ----
}
static void
! NIImportOOAffixes(IspellDict *Conf, const char *filename, MemoryContext *simple_ctx, MemoryContext *temp_ctx)
{
char type[BUFSIZ],
*ptype = NULL;
***************
*** 545,551 ****
char scanbuf[BUFSIZ];
char *recoded;
! checkTmpCtx();
/* read file to find any flag */
memset(Conf->flagval, 0, sizeof(Conf->flagval));
--- 561,567 ----
char scanbuf[BUFSIZ];
char *recoded;
! checkTmpCtx(temp_ctx);
/* read file to find any flag */
memset(Conf->flagval, 0, sizeof(Conf->flagval));
***************
*** 687,693 ****
* Note caller must already have applied get_tsearch_config_filename
*/
void
! NIImportAffixes(IspellDict *Conf, const char *filename)
{
char *pstr = NULL;
char mask[BUFSIZ];
--- 703,709 ----
* Note caller must already have applied get_tsearch_config_filename
*/
void
! NIImportAffixes(IspellDict *Conf, const char *filename, MemoryContext *simple_ctx, MemoryContext *temp_ctx)
{
char *pstr = NULL;
char mask[BUFSIZ];
***************
*** 702,708 ****
bool oldformat = false;
char *recoded = NULL;
! checkTmpCtx();
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
--- 718,724 ----
bool oldformat = false;
char *recoded = NULL;
! checkTmpCtx(temp_ctx);
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
***************
*** 802,808 ****
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("wrong affix file format for flag")));
tsearch_readline_end(&trst);
! NIImportOOAffixes(Conf, filename);
return;
}
if ((!suffixes) && (!prefixes))
--- 818,824 ----
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("wrong affix file format for flag")));
tsearch_readline_end(&trst);
! NIImportOOAffixes(Conf, filename, simple_ctx, temp_ctx);
return;
}
if ((!suffixes) && (!prefixes))
***************
*** 859,865 ****
}
static SPNode *
! mkSPNode(IspellDict *Conf, int low, int high, int level)
{
int i;
int nchar = 0;
--- 875,881 ----
}
static SPNode *
! mkSPNode(IspellDict *Conf, int low, int high, int level, MemoryContext simple_ctx)
{
int i;
int nchar = 0;
***************
*** 878,884 ****
if (!nchar)
return NULL;
! rs = (SPNode *) palloc0(SPNHDRSZ + nchar * sizeof(SPNodeData));
rs->length = nchar;
data = rs->data;
--- 894,901 ----
if (!nchar)
return NULL;
! rs = (SPNode *) MemoryContextAllocZero(simple_ctx,
! SPNHDRSZ + nchar * sizeof(SPNodeData));
rs->length = nchar;
data = rs->data;
***************
*** 890,896 ****
{
if (lastchar)
{
! data->node = mkSPNode(Conf, lownew, i, level + 1);
lownew = i;
data++;
}
--- 907,913 ----
{
if (lastchar)
{
! data->node = mkSPNode(Conf, lownew, i, level + 1, simple_ctx);
lownew = i;
data++;
}
***************
*** 929,935 ****
}
}
! data->node = mkSPNode(Conf, lownew, high, level + 1);
return rs;
}
--- 946,952 ----
}
}
! data->node = mkSPNode(Conf, lownew, high, level + 1, simple_ctx);
return rs;
}
***************
*** 939,951 ****
* and affixes.
*/
void
! NISortDictionary(IspellDict *Conf)
{
int i;
int naffix = 0;
int curaffix;
! checkTmpCtx();
/* compress affixes */
--- 956,968 ----
* and affixes.
*/
void
! NISortDictionary(IspellDict *Conf, MemoryContext *simple_ctx, MemoryContext *temp_ctx)
{
int i;
int naffix = 0;
int curaffix;
! checkTmpCtx(temp_ctx);
/* compress affixes */
***************
*** 959,971 ****
if (i == 0 || strncmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag, MAXFLAGLEN))
naffix++;
}
/*
* Fill in Conf->AffixData with the affixes that were used in the
* dictionary. Replace textual flag-field of Conf->Spell entries with
* indexes into Conf->AffixData array.
*/
! Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
curaffix = -1;
for (i = 0; i < Conf->nspell; i++)
--- 976,1000 ----
if (i == 0 || strncmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag, MAXFLAGLEN))
naffix++;
}
+
+ if (*simple_ctx == NULL)
+ {
+ /* create simple alloc memory context */
+ *simple_ctx = SimpleAllocContextCreate(CurrentMemoryContext,
+ "Ispell dictionary simple context",
+ SIMPLEALLOC_LARGE_INITSIZE,
+ malloc,
+ free);
+ }
/*
* Fill in Conf->AffixData with the affixes that were used in the
* dictionary. Replace textual flag-field of Conf->Spell entries with
* indexes into Conf->AffixData array.
*/
!
! Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
! /* cannot move to simple context now ^ */
curaffix = -1;
for (i = 0; i < Conf->nspell; i++)
***************
*** 974,979 ****
--- 1003,1009 ----
{
curaffix++;
Assert(curaffix < naffix);
+ /* can't be moved to simple alloc context now */
Conf->AffixData[curaffix] = pstrdup(Conf->Spell[i]->p.flag);
}
***************
*** 984,996 ****
Conf->lenAffixData = Conf->nAffixData = naffix;
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
! Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
Conf->Spell = NULL;
}
static AffixNode *
! mkANode(IspellDict *Conf, int low, int high, int level, int type)
{
int i;
int nchar = 0;
--- 1014,1026 ----
Conf->lenAffixData = Conf->nAffixData = naffix;
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
! Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0, *simple_ctx);
Conf->Spell = NULL;
}
static AffixNode *
! mkANode(IspellDict *Conf, int low, int high, int level, int type, MemoryContext simple_ctx)
{
int i;
int nchar = 0;
***************
*** 1014,1020 ****
aff = (AFFIX **) tmpalloc(sizeof(AFFIX *) * (high - low + 1));
naff = 0;
! rs = (AffixNode *) palloc0(ANHRDSZ + nchar * sizeof(AffixNodeData));
rs->length = nchar;
data = rs->data;
--- 1044,1052 ----
aff = (AFFIX **) tmpalloc(sizeof(AFFIX *) * (high - low + 1));
naff = 0;
! rs = (AffixNode *) MemoryContextAllocZero(simple_ctx,
! ANHRDSZ + nchar * sizeof(AffixNodeData));
!
rs->length = nchar;
data = rs->data;
***************
*** 1026,1036 ****
{
if (lastchar)
{
! data->node = mkANode(Conf, lownew, i, level + 1, type);
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
--- 1058,1068 ----
{
if (lastchar)
{
! data->node = mkANode(Conf, lownew, i, level + 1, type, simple_ctx);
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) MemoryContextAlloc(simple_ctx, sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
***************
*** 1046,1056 ****
}
}
! data->node = mkANode(Conf, lownew, high, level + 1, type);
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
--- 1078,1088 ----
}
}
! data->node = mkANode(Conf, lownew, high, level + 1, type, simple_ctx);
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) MemoryContextAlloc(simple_ctx, sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
***************
*** 1061,1073 ****
}
static void
! mkVoidAffix(IspellDict *Conf, bool issuffix, int startsuffix)
{
int i,
cnt = 0;
int start = (issuffix) ? startsuffix : 0;
int end = (issuffix) ? Conf->naffixes : startsuffix;
! AffixNode *Affix = (AffixNode *) palloc0(ANHRDSZ + sizeof(AffixNodeData));
Affix->length = 1;
Affix->isvoid = 1;
--- 1093,1107 ----
}
static void
! mkVoidAffix(IspellDict *Conf, bool issuffix, int startsuffix, MemoryContext simple_ctx)
{
int i,
cnt = 0;
int start = (issuffix) ? startsuffix : 0;
int end = (issuffix) ? Conf->naffixes : startsuffix;
! //AffixNode *Affix = (AffixNode *) palloc0(ANHRDSZ + sizeof(AffixNodeData));
!
! AffixNode *Affix = (AffixNode *) MemoryContextAllocZero(simple_ctx, ANHRDSZ + sizeof(AffixNodeData));
Affix->length = 1;
Affix->isvoid = 1;
***************
*** 1091,1097 ****
if (cnt == 0)
return;
! Affix->data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * cnt);
Affix->data->naff = (uint32) cnt;
cnt = 0;
--- 1125,1131 ----
if (cnt == 0)
return;
! Affix->data->aff = (AFFIX **) MemoryContextAllocZero(simple_ctx, sizeof(AFFIX *) * cnt);
Affix->data->naff = (uint32) cnt;
cnt = 0;
***************
*** 1116,1129 ****
}
void
! NISortAffixes(IspellDict *Conf)
{
AFFIX *Affix;
size_t i;
CMPDAffix *ptr;
int firstsuffix = Conf->naffixes;
! checkTmpCtx();
if (Conf->naffixes == 0)
return;
--- 1150,1173 ----
}
void
! NISortAffixes(IspellDict *Conf, MemoryContext *simple_ctx, MemoryContext *temp_ctx)
{
AFFIX *Affix;
size_t i;
CMPDAffix *ptr;
int firstsuffix = Conf->naffixes;
! checkTmpCtx(temp_ctx);
!
! if (*simple_ctx == NULL)
! {
! /* create simple alloc memory context */
! *simple_ctx = SimpleAllocContextCreate(CurrentMemoryContext,
! "Ispell dictionary simple context",
! SIMPLEALLOC_LARGE_INITSIZE,
! malloc,
! free);
! }
if (Conf->naffixes == 0)
return;
***************
*** 1159,1168 ****
ptr->affix = NULL;
Conf->CompoundAffix = (CMPDAffix *) repalloc(Conf->CompoundAffix, sizeof(CMPDAffix) * (ptr - Conf->CompoundAffix + 1));
! Conf->Prefix = mkANode(Conf, 0, firstsuffix, 0, FF_PREFIX);
! Conf->Suffix = mkANode(Conf, firstsuffix, Conf->naffixes, 0, FF_SUFFIX);
! mkVoidAffix(Conf, true, firstsuffix);
! mkVoidAffix(Conf, false, firstsuffix);
}
static AffixNodeData *
--- 1203,1212 ----
ptr->affix = NULL;
Conf->CompoundAffix = (CMPDAffix *) repalloc(Conf->CompoundAffix, sizeof(CMPDAffix) * (ptr - Conf->CompoundAffix + 1));
! Conf->Prefix = mkANode(Conf, 0, firstsuffix, 0, FF_PREFIX, *simple_ctx);
! Conf->Suffix = mkANode(Conf, firstsuffix, Conf->naffixes, 0, FF_SUFFIX, *simple_ctx);
! mkVoidAffix(Conf, true, firstsuffix, *simple_ctx);
! mkVoidAffix(Conf, false, firstsuffix, *simple_ctx);
}
static AffixNodeData *
*** ./src/backend/utils/mmgr/Makefile.orig 2008-02-19 11:30:09.000000000 +0100
--- ./src/backend/utils/mmgr/Makefile 2010-03-15 11:03:16.738323659 +0100
***************
*** 12,17 ****
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
! OBJS = aset.o mcxt.o portalmem.o
include $(top_srcdir)/src/backend/common.mk
--- 12,17 ----
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
! OBJS = aset.o mcxt.o portalmem.o simple_alloc.o
include $(top_srcdir)/src/backend/common.mk
*** ./src/backend/utils/mmgr/simple_alloc.c.orig 2010-03-15 11:02:48.741323741 +0100
--- ./src/backend/utils/mmgr/simple_alloc.c 2010-03-15 14:32:40.009321969 +0100
***************
*** 0 ****
--- 1,308 ----
+ #include "postgres.h"
+
+ #include "utils/memutils.h"
+
+ typedef struct AllocBlockData *AllocBlock; /* forward reference */
+
+
+ typedef struct SimpleAllocContextData
+ {
+ MemoryContextData header; /* Standard memory-context fields */
+ AllocBlock blocks; /* head of list of blocks */
+ bool isReset;
+ /* Allocation parameters for this context */
+ Size initBlockSize;
+ void *(*external_alloc) (Size size); /* allocate memory */
+ void (*external_free) (void *); /* deallocate memory */
+ } SimpleAllocContextData;
+
+ typedef SimpleAllocContextData *SimpleAlloc;
+
+ typedef struct AllocBlockData
+ {
+ AllocBlock next;
+ Size freesize;
+ char *freeptr;
+ char data[1];
+ } AllocBlockData;
+
+ #define SimpleAllocCtxIsValid(ctx) PointerIsValid(ctx);
+
+ static void SimpleAllocInit(MemoryContext context);
+ static void SimpleAllocReset(MemoryContext context);
+ static void SimpleAllocDelete(MemoryContext context);
+ static void *SimpleAllocAlloc(MemoryContext context, Size size);
+ static void SimpleAllocStats(MemoryContext context, int level);
+ static void *SimpleAllocRealloc(MemoryContext context, void *pointer, Size size);
+ static void SimpleAllocFree(MemoryContext context, void *pointer);
+ static bool SimpleAllocIsEmpty(MemoryContext context);
+ static Size SimpleAllocGetChunkSpace(MemoryContext context, void *pointer);
+
+ #ifdef MEMORY_CONTEXT_CHECKING
+ static void SimpleAllocCheck(MemoryContext context);
+ #endif
+
+ /*
+ * This is the virtual function table for SimpleAlloc context
+ */
+ static MemoryContextMethods SimpleAllocMethods = {
+ SimpleAllocAlloc,
+ SimpleAllocFree, /* not supported */
+ SimpleAllocRealloc, /* not supported */
+ SimpleAllocInit,
+ SimpleAllocReset,
+ SimpleAllocDelete,
+ SimpleAllocGetChunkSpace, /* not supported */
+ SimpleAllocIsEmpty,
+ SimpleAllocStats
+ #ifdef MEMORY_CONTEXT_CHECKING
+ , SimpleAllocCheck
+ #endif
+ };
+
+ #ifdef RANDOMIZE_ALLOCATED_MEMORY
+
+ /*
+ * Fill a just-allocated piece of memory with "random" data. It's not really
+ * very random, just a repeating sequence with a length that's prime. What
+ * we mainly want out of it is to have a good probability that two palloc's
+ * of the same number of bytes start out containing different data.
+ */
+ static void
+ randomize_mem(char *ptr, size_t size)
+ {
+ static int save_ctr = 1;
+ int ctr;
+
+ ctr = save_ctr;
+ while (size-- > 0)
+ {
+ *ptr++ = ctr;
+ if (++ctr > 251)
+ ctr = 1;
+ }
+ save_ctr = ctr;
+ }
+ #endif /* RANDOMIZE_ALLOCATED_MEMORY */
+
+ /*
+ * SimpleAllocContextCreate
+ *
+ *
+ */
+ MemoryContext
+ SimpleAllocContextCreate(MemoryContext parent,
+ const char *name,
+ Size initBlockSize,
+ void *(*external_alloc) (Size size),
+ void (*external_free) (void *))
+ {
+ SimpleAlloc context;
+
+ context = (SimpleAlloc) MemoryContextCreate(T_SimpleAllocContext,
+ sizeof(SimpleAllocContextData),
+ &SimpleAllocMethods,
+ parent,
+ name);
+ context->initBlockSize = initBlockSize;
+ context->external_alloc = external_alloc;
+ context->external_free = external_free;
+
+ context->blocks = NULL;
+ context->isReset = true;
+
+ return (MemoryContext) context;
+ }
+
+ /*
+ * Context type methods
+ */
+ static void
+ SimpleAllocInit(MemoryContext context)
+ {
+ /*
+ * do nothing
+ */
+ }
+
+ static void
+ SimpleAllocReset(MemoryContext context)
+ {
+ AllocBlock block;
+ SimpleAlloc simple_ctx = (SimpleAlloc) context;
+
+ Assert(SimpleAllocCtxIsValid(simple_ctx));
+
+ block = simple_ctx->blocks;
+
+ /*
+ * reset all allocated memory
+ */
+ while (block != NULL)
+ {
+ block->freesize = simple_ctx->initBlockSize;
+ block->freeptr = block->data;
+
+ #ifdef CLOBBER_FREED_MEMORY
+ memset(block->freeptr, 0x7F, simple_ctx->initBlockSize);
+ #endif
+ block = block->next;
+ }
+ simple_ctx->isReset = true;
+ }
+
+ static void
+ SimpleAllocDelete(MemoryContext context)
+ {
+ AllocBlock block;
+ SimpleAlloc simple_ctx = (SimpleAlloc) context;
+
+ Assert(SimpleAllocCtxIsValid(simple_ctx));
+
+ block = simple_ctx->blocks;
+
+ /*
+ * reset all allocated memory
+ */
+ while (block != NULL)
+ {
+ AllocBlock next = block->next;
+
+ block->freesize = simple_ctx->initBlockSize;
+ block->freeptr = block->data;
+
+ #ifdef CLOBBER_FREED_MEMORY
+ memset(block->freeptr, 0x7F, simple_ctx->initBlockSize);
+ #endif
+ if (simple_ctx->external_free != NULL)
+ simple_ctx->external_free(block);
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot release allocated memory")));
+ block = next;
+ }
+
+ simple_ctx->blocks = NULL;
+ simple_ctx->isReset = true;
+ }
+
+ static void *
+ SimpleAllocAlloc(MemoryContext context, Size size)
+ {
+ SimpleAlloc simple_ctx = (SimpleAlloc) context;
+ AllocBlock block;
+ void *newPointer;
+
+ Assert(SimpleAllocCtxIsValid(simple_ctx));
+
+ if (size > simple_ctx->initBlockSize)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory"),
+ errdetail("simple allocator cannot allocate larger block than is initial size")));
+
+ if (simple_ctx->blocks == NULL || (simple_ctx->blocks && simple_ctx->blocks->freesize < size))
+ {
+ /* alloc a new block */
+ block = simple_ctx->external_alloc(simple_ctx->initBlockSize + sizeof(AllocBlockData) - 1);
+ if (block == NULL)
+ {
+ MemoryContextStats(TopMemoryContext);
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory"),
+ errdetail("Failed on request of size %lu.",
+ (unsigned long) simple_ctx->initBlockSize + sizeof(AllocBlockData) - 1)));
+ }
+ block->freesize = simple_ctx->initBlockSize;
+ block->freeptr = block->data;
+ block->next = simple_ctx->blocks;
+ simple_ctx->blocks = block;
+ }
+ else
+ block = simple_ctx->blocks;
+
+ Assert(size > block->freesize)
+ newPointer = block->freeptr;
+ block->freeptr += size;
+ block->freesize -= size;
+
+ #ifdef RANDOMIZE_ALLOCATED_MEMORY
+ randomize_mem((char *) newPointer, size);
+ #endif
+ simple_ctx->isReset = false;
+
+ return newPointer;
+ }
+
+ /*
+ * SimpleAllocStats
+ */
+ static void
+ SimpleAllocStats(MemoryContext context, int level)
+ {
+ SimpleAlloc simple_ctx = (SimpleAlloc) context;
+ AllocBlock block;
+ long nblocks = 0;
+ long totalspace = 0;
+ long freespace = 0;
+ int i;
+
+
+ for (block = simple_ctx->blocks; block != NULL; block = block->next)
+ {
+ nblocks++;
+ totalspace += simple_ctx->initBlockSize + sizeof(AllocBlockData) - 1;
+ freespace += block->freesize;
+ }
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+
+ fprintf(stderr,
+ "%s: %lu total in %ld blocks; %lu free; %lu used\n",
+ simple_ctx->header.name, totalspace, nblocks, freespace,
+ totalspace - freespace);
+ }
+
+ static void *
+ SimpleAllocRealloc(MemoryContext context, void *pointer, Size size)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("simple allocator can't realloc memory")));
+ return NULL; /* be compiler quite */
+ }
+
+ static void
+ SimpleAllocFree(MemoryContext context, void *pointer)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("simple allocator can't release memory")));
+ }
+
+ static bool
+ SimpleAllocIsEmpty(MemoryContext context)
+ {
+ return ((SimpleAlloc) context)->isReset;
+ }
+
+ static Size
+ SimpleAllocGetChunkSpace(MemoryContext context, void *pointer)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("simple allocator has not chunks")));
+ return 0; /* be compile quite */
+ }
+
+ #ifdef MEMORY_CONTEXT_CHECKING
+ static void
+ SimpleAllocCheck(MemoryContext context)
+ {
+ /* do nothing */
+ }
+
+ #endif
*** ./src/include/nodes/memnodes.h.orig 2010-01-02 17:58:04.000000000 +0100
--- ./src/include/nodes/memnodes.h 2010-03-15 14:07:38.597323708 +0100
***************
*** 72,77 ****
*/
#define MemoryContextIsValid(context) \
((context) != NULL && \
! (IsA((context), AllocSetContext)))
#endif /* MEMNODES_H */
--- 72,77 ----
*/
#define MemoryContextIsValid(context) \
((context) != NULL && \
! (IsA((context), AllocSetContext) || IsA((context), SimpleAllocContext)))
#endif /* MEMNODES_H */
*** ./src/include/nodes/nodes.h.orig 2010-01-05 22:53:59.000000000 +0100
--- ./src/include/nodes/nodes.h 2010-03-15 14:06:20.021447204 +0100
***************
*** 234,239 ****
--- 234,240 ----
*/
T_MemoryContext = 600,
T_AllocSetContext,
+ T_SimpleAllocContext,
/*
* TAGS FOR VALUE NODES (value.h)
*** ./src/include/tsearch/dicts/spell.h.orig 2010-01-02 17:58:09.000000000 +0100
--- ./src/include/tsearch/dicts/spell.h 2010-03-15 15:16:21.662447289 +0100
***************
*** 161,169 ****
} IspellDict;
extern TSLexeme *NINormalizeWord(IspellDict *Conf, char *word);
! extern void NIImportAffixes(IspellDict *Conf, const char *filename);
! extern void NIImportDictionary(IspellDict *Conf, const char *filename);
! extern void NISortDictionary(IspellDict *Conf);
! extern void NISortAffixes(IspellDict *Conf);
#endif
--- 161,169 ----
} IspellDict;
extern TSLexeme *NINormalizeWord(IspellDict *Conf, char *word);
! extern void NIImportAffixes(IspellDict *Conf, const char *filename, MemoryContext *simple_ctx, MemoryContext *temp_ctx);
! extern void NIImportDictionary(IspellDict *Conf, const char *filename, MemoryContext *simple_ctx, MemoryContext *temp_ctx);
! extern void NISortDictionary(IspellDict *Conf, MemoryContext *simple_ctx, MemoryContext *temp_ctx);
! extern void NISortAffixes(IspellDict *Conf, MemoryContext *simple_ctx, MemoryContext *temp_ctx);
#endif
*** ./src/include/utils/memutils.h.orig 2010-03-15 14:33:58.000000000 +0100
--- ./src/include/utils/memutils.h 2010-03-15 16:20:24.280321906 +0100
***************
*** 136,139 ****
--- 136,147 ----
#define ALLOCSET_SMALL_INITSIZE (1 * 1024)
#define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
+ extern MemoryContext SimpleAllocContextCreate(MemoryContext parent,
+ const char *name,
+ Size initBlockSize,
+ void *(*external_alloc) (Size size),
+ void (*external_free) (void *));
+
+ #define SIMPLEALLOC_LARGE_INITSIZE (1024 * 128)
+
#endif /* MEMUTILS_H */