lessmem.diff
application/octet-stream
Filename: lessmem.diff
Type: application/octet-stream
Part: 0
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/regis.c | 8 | 1 |
| src/backend/tsearch/spell.c | 83 | 15 |
| src/include/tsearch/dicts/spell.h | 11 | 0 |
*** ./src/backend/tsearch/regis.c.orig 2010-07-14 11:47:33.068437888 +0200
--- ./src/backend/tsearch/regis.c 2010-07-14 14:32:47.157437908 +0200
***************
*** 16,27 ****
--- 16,34 ----
#include "tsearch/dicts/regis.h"
#include "tsearch/ts_locale.h"
+ #include "tsearch/dicts/spell.h"
#define RS_IN_ONEOF 1
#define RS_IN_ONEOF_IN 2
#define RS_IN_NONEOF 3
#define RS_IN_WAIT 4
+ extern AllocOnlyBlocksData aob;
+
+ #define aoalloc(sz) ao_alloc(&aob, (sz), false)
+ #define aoalloc0(sz) ao_alloc(&aob, (sz), true)
+ #define aostrdup(str) ao_strdup(&aob, (str))
+
/*
* Test whether a regex is of the subset supported here.
* Keep this in sync with RS_compile!
***************
*** 74,80 ****
{
RegisNode *ptr;
! ptr = (RegisNode *) palloc0(RNHDRSZ + len + 1);
if (prev)
prev->next = ptr;
return ptr;
--- 81,87 ----
{
RegisNode *ptr;
! ptr = (RegisNode *) aoalloc0(RNHDRSZ + len + 1);
if (prev)
prev->next = ptr;
return ptr;
*** ./src/backend/tsearch/spell.c.orig 2010-01-02 17:57:53.000000000 +0100
--- ./src/backend/tsearch/spell.c 2010-07-14 14:46:06.513562368 +0200
***************
*** 28,36 ****
--- 28,97 ----
*/
static MemoryContext tmpCtx = NULL;
+ #define ALLOC_ONLY_MAXSIZE 512
+
+ AllocOnlyBlocksData aob;
+ AllocOnlyBlocksData tmpaob;
+
#define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
#define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
+ #define aoalloc(sz) ao_alloc(&aob, (sz), false)
+ #define aoalloc0(sz) ao_alloc(&aob, (sz), true)
+ #define aostrdup(str) ao_strdup(&aob, (str))
+
+ #define aotmpalloc(sz) ao_alloc(&tmpaob, (sz), false)
+ #define aotpmalloc0(sz) ao_alloc(&tmpaob, (sz), true)
+ #define aotmpstrdup(str) ao_strdup(&tmpaob, (str))
+
+ /*
+ * Ispell dictionary uses a thousands small blocks and because
+ * doesn't release these blocks, we can save lot of memory via
+ * sharing mcxt blocks.
+ */
+ char *
+ ao_alloc(AllocOnlyBlocksData *aob, Size size, bool fillzero)
+ {
+ char *ptr;
+
+ size = MAXALIGN(size);
+
+ /*
+ * for "larger" blocks use a mcxt allocator. It is simple
+ * mechanism to ensure a well fragmentation of alloc only
+ * blocks.
+ */
+ if (size > ALLOC_ONLY_MAXSIZE)
+ return fillzero ? MemoryContextAllocZero(aob->ctx, size) : MemoryContextAlloc(aob->ctx, size);
+
+ if (size > aob->freesize)
+ {
+ aob->freeptr = MemoryContextAlloc(aob->ctx, ALLOCSET_DEFAULT_INITSIZE);
+ aob->freesize = ALLOCSET_DEFAULT_INITSIZE;
+ }
+
+ ptr = aob->freeptr;
+ aob->freeptr += size;
+ aob->freesize -= size;
+
+ if (fillzero)
+ memset(ptr, 0, size);
+
+ return ptr;
+ }
+
+ char *
+ ao_strdup(AllocOnlyBlocksData *aob, const char *string)
+ {
+ char *nstr;
+ Size len = strlen(string) + 1;
+
+ nstr = (char *) ao_alloc(aob, len, false);
+ memcpy(nstr, string, len);;
+
+ return nstr;
+ }
+
static void
checkTmpCtx(void)
{
***************
*** 48,53 ****
--- 109,120 ----
}
else
tmpCtx = CurrentMemoryContext->firstchild;
+
+ tmpaob.ctx = tmpCtx;
+ tmpaob.freesize = 0;
+
+ aob.ctx = CurrentMemoryContext;
+ aob.freesize = 0;
}
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++;
--- 246,253 ----
Conf->Spell = (SPELL **) tmpalloc(Conf->mspell * sizeof(SPELL *));
}
}
!
! Conf->Spell[Conf->nspell] = (SPELL *) aotmpalloc(SPELLHDRSZ + strlen(word) + 1);
strcpy(Conf->Spell[Conf->nspell]->word, word);
strncpy(Conf->Spell[Conf->nspell]->p.flag, flag, MAXFLAGLEN);
Conf->nspell++;
***************
*** 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);
--- 412,425 ----
Affix->issimple = 0;
Affix->isregis = 0;
! tmask = (char *) aotmpalloc(strlen(mask) + 3);
if (type == FF_SUFFIX)
sprintf(tmask, "%s$", mask);
else
sprintf(tmask, "^%s", mask);
masklen = strlen(tmask);
! wmask = (pg_wchar *) aotmpalloc((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);
***************
*** 375,383 ****
Affix->flag = flag;
Affix->type = type;
! Affix->find = (find && *find) ? pstrdup(find) : VoidString;
if ((Affix->replen = strlen(repl)) > 0)
! Affix->repl = pstrdup(repl);
else
Affix->repl = VoidString;
Conf->naffixes++;
--- 443,451 ----
Affix->flag = flag;
Affix->type = type;
! Affix->find = (find && *find) ? aostrdup(find) : VoidString;
if ((Affix->replen = strlen(repl)) > 0)
! Affix->repl = aostrdup(repl);
else
Affix->repl = VoidString;
Conf->naffixes++;
***************
*** 833,839 ****
}
ptr = Conf->AffixData + Conf->nAffixData;
! *ptr = palloc(strlen(Conf->AffixData[a1]) + strlen(Conf->AffixData[a2]) +
1 /* space */ + 1 /* \0 */ );
sprintf(*ptr, "%s %s", Conf->AffixData[a1], Conf->AffixData[a2]);
ptr++;
--- 901,907 ----
}
ptr = Conf->AffixData + Conf->nAffixData;
! *ptr = aoalloc(strlen(Conf->AffixData[a1]) + strlen(Conf->AffixData[a2]) +
1 /* space */ + 1 /* \0 */ );
sprintf(*ptr, "%s %s", Conf->AffixData[a1], Conf->AffixData[a2]);
ptr++;
***************
*** 878,884 ****
if (!nchar)
return NULL;
! rs = (SPNode *) palloc0(SPNHDRSZ + nchar * sizeof(SPNodeData));
rs->length = nchar;
data = rs->data;
--- 946,952 ----
if (!nchar)
return NULL;
! rs = (SPNode *) aoalloc0(SPNHDRSZ + nchar * sizeof(SPNodeData));
rs->length = nchar;
data = rs->data;
***************
*** 965,971 ****
* 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++)
--- 1033,1039 ----
* dictionary. Replace textual flag-field of Conf->Spell entries with
* indexes into Conf->AffixData array.
*/
! Conf->AffixData = (char **) aoalloc0(naffix * sizeof(char *));
curaffix = -1;
for (i = 0; i < Conf->nspell; i++)
***************
*** 974,980 ****
{
curaffix++;
Assert(curaffix < naffix);
! Conf->AffixData[curaffix] = pstrdup(Conf->Spell[i]->p.flag);
}
Conf->Spell[i]->p.d.affix = curaffix;
--- 1042,1048 ----
{
curaffix++;
Assert(curaffix < naffix);
! Conf->AffixData[curaffix] = aostrdup(Conf->Spell[i]->p.flag);
}
Conf->Spell[i]->p.d.affix = curaffix;
***************
*** 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;
--- 1082,1088 ----
aff = (AFFIX **) tmpalloc(sizeof(AFFIX *) * (high - low + 1));
naff = 0;
! rs = (AffixNode *) aoalloc0(ANHRDSZ + nchar * sizeof(AffixNodeData));
rs->length = nchar;
data = rs->data;
***************
*** 1030,1036 ****
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
--- 1098,1104 ----
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) aoalloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
***************
*** 1050,1056 ****
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
--- 1118,1124 ----
if (naff)
{
data->naff = naff;
! data->aff = (AFFIX **) aoalloc(sizeof(AFFIX *) * naff);
memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
naff = 0;
}
***************
*** 1067,1073 ****
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;
--- 1135,1141 ----
cnt = 0;
int start = (issuffix) ? startsuffix : 0;
int end = (issuffix) ? Conf->naffixes : startsuffix;
! AffixNode *Affix = (AffixNode *) aoalloc0(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;
--- 1159,1165 ----
if (cnt == 0)
return;
! Affix->data->aff = (AFFIX **) aoalloc(sizeof(AFFIX *) * cnt);
Affix->data->naff = (uint32) cnt;
cnt = 0;
***************
*** 1658,1664 ****
addNorm(TSLexeme **lres, TSLexeme **lcur, char *word, int flags, uint16 NVariant)
{
if (*lres == NULL)
! *lcur = *lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
if (*lcur - *lres < MAX_NORM - 1)
{
--- 1726,1732 ----
addNorm(TSLexeme **lres, TSLexeme **lcur, char *word, int flags, uint16 NVariant)
{
if (*lres == NULL)
! *lcur = *lres = (TSLexeme *) aoalloc(MAX_NORM * sizeof(TSLexeme));
if (*lcur - *lres < MAX_NORM - 1)
{
*** ./src/include/tsearch/dicts/spell.h.orig 2010-04-02 17:21:20.000000000 +0200
--- ./src/include/tsearch/dicts/spell.h 2010-07-14 14:23:42.210440053 +0200
***************
*** 160,169 ****
--- 160,180 ----
bool usecompound;
} IspellDict;
+ typedef struct
+ {
+ MemoryContext ctx;
+ Size freesize;
+ char *freeptr;
+ } AllocOnlyBlocksData;
+
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);
+ extern char *ao_alloc(AllocOnlyBlocksData *aob, Size size, bool fillzero);
+ extern char *ao_strdup(AllocOnlyBlocksData *aob, const char *string);
+
+
#endif