aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/tsearch/dict_ispell.c5
-rw-r--r--src/backend/tsearch/spell.c86
-rw-r--r--src/include/tsearch/dicts/spell.h22
3 files changed, 62 insertions, 51 deletions
diff --git a/src/backend/tsearch/dict_ispell.c b/src/backend/tsearch/dict_ispell.c
index 95bf8d46324..720adb0c1ab 100644
--- a/src/backend/tsearch/dict_ispell.c
+++ b/src/backend/tsearch/dict_ispell.c
@@ -19,7 +19,6 @@
#include "tsearch/ts_public.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
-#include "utils/memutils.h"
typedef struct
@@ -40,6 +39,8 @@ dispell_init(PG_FUNCTION_ARGS)
d = (DictISpell *) palloc0(sizeof(DictISpell));
+ NIStartBuild(&(d->obj));
+
foreach(l, dictoptions)
{
DefElem *defel = (DefElem *) lfirst(l);
@@ -102,7 +103,7 @@ dispell_init(PG_FUNCTION_ARGS)
errmsg("missing DictFile parameter")));
}
- MemoryContextDeleteChildren(CurrentMemoryContext);
+ NIFinishBuild(&(d->obj));
PG_RETURN_POINTER(d);
}
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index 4b54b158f3e..cd7ada66138 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -21,42 +21,57 @@
/*
* Initialization requires a lot of memory that's not needed
- * after the initialization is done. In init function,
- * CurrentMemoryContext is a long lived memory context associated
- * with the dictionary cache entry, so we use a temporary context
- * for the short-lived stuff.
+ * after the initialization is done. During initialization,
+ * CurrentMemoryContext is the long-lived memory context associated
+ * with the dictionary cache entry. We keep the short-lived stuff
+ * in the Conf->buildCxt context.
*/
-static MemoryContext tmpCtx = NULL;
+#define tmpalloc(sz) MemoryContextAlloc(Conf->buildCxt, (sz))
+#define tmpalloc0(sz) MemoryContextAllocZero(Conf->buildCxt, (sz))
-#define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
-#define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
-
-static void
-checkTmpCtx(void)
+/*
+ * Prepare for constructing an ISpell dictionary.
+ *
+ * The IspellDict struct is assumed to be zeroed when allocated.
+ */
+void
+NIStartBuild(IspellDict *Conf)
{
/*
- * XXX: This assumes that CurrentMemoryContext doesn't have any children
- * other than the one we create here.
+ * The temp context is a child of CurTransactionContext, so that it will
+ * go away automatically on error.
*/
- if (CurrentMemoryContext->firstchild == NULL)
- {
- tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
- "Ispell dictionary init context",
- ALLOCSET_DEFAULT_MINSIZE,
- ALLOCSET_DEFAULT_INITSIZE,
- ALLOCSET_DEFAULT_MAXSIZE);
- }
- else
- tmpCtx = CurrentMemoryContext->firstchild;
+ Conf->buildCxt = AllocSetContextCreate(CurTransactionContext,
+ "Ispell dictionary init context",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
}
+/*
+ * Clean up when dictionary construction is complete.
+ */
+void
+NIFinishBuild(IspellDict *Conf)
+{
+ /* Release no-longer-needed temp memory */
+ MemoryContextDelete(Conf->buildCxt);
+ /* Just for cleanliness, zero the now-dangling pointers */
+ Conf->buildCxt = NULL;
+ Conf->Spell = NULL;
+}
+
+
+/*
+ * Apply lowerstr(), producing a temporary result (in the buildCxt).
+ */
static char *
-lowerstr_ctx(char *src)
+lowerstr_ctx(IspellDict *Conf, const char *src)
{
MemoryContext saveCtx;
char *dst;
- saveCtx = MemoryContextSwitchTo(tmpCtx);
+ saveCtx = MemoryContextSwitchTo(Conf->buildCxt);
dst = lowerstr(src);
MemoryContextSwitchTo(saveCtx);
@@ -120,6 +135,7 @@ strbcmp(const unsigned char *s1, const unsigned char *s2)
return 0;
}
+
static int
strbncmp(const unsigned char *s1, const unsigned char *s2, size_t count)
{
@@ -196,8 +212,6 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
tsearch_readline_state trst;
char *line;
- checkTmpCtx();
-
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
@@ -242,7 +256,7 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
}
s += pg_mblen(s);
}
- pstr = lowerstr_ctx(line);
+ pstr = lowerstr_ctx(Conf, line);
NIAddSpell(Conf, pstr, flag);
pfree(pstr);
@@ -545,8 +559,6 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
char scanbuf[BUFSIZ];
char *recoded;
- checkTmpCtx();
-
/* read file to find any flag */
memset(Conf->flagval, 0, sizeof(Conf->flagval));
Conf->usecompound = false;
@@ -624,7 +636,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
if (ptype)
pfree(ptype);
- ptype = lowerstr_ctx(type);
+ ptype = lowerstr_ctx(Conf, type);
if (scanread < 4 || (STRNCMP(ptype, "sfx") && STRNCMP(ptype, "pfx")))
goto nextline;
@@ -646,7 +658,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
if (strlen(sflag) != 1 || flag != *sflag || flag == 0)
goto nextline;
- prepl = lowerstr_ctx(repl);
+ prepl = lowerstr_ctx(Conf, repl);
/* affix flag */
if ((ptr = strchr(prepl, '/')) != NULL)
{
@@ -658,8 +670,8 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
ptr++;
}
}
- pfind = lowerstr_ctx(find);
- pmask = lowerstr_ctx(mask);
+ pfind = lowerstr_ctx(Conf, find);
+ pmask = lowerstr_ctx(Conf, mask);
if (t_iseq(find, '0'))
*pfind = '\0';
if (t_iseq(repl, '0'))
@@ -702,8 +714,6 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
bool oldformat = false;
char *recoded = NULL;
- checkTmpCtx();
-
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
@@ -945,8 +955,6 @@ NISortDictionary(IspellDict *Conf)
int naffix = 0;
int curaffix;
- checkTmpCtx();
-
/* compress affixes */
/* Count the number of different flags used in the dictionary */
@@ -985,8 +993,6 @@ NISortDictionary(IspellDict *Conf)
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
-
- Conf->Spell = NULL;
}
static AffixNode *
@@ -1123,8 +1129,6 @@ NISortAffixes(IspellDict *Conf)
CMPDAffix *ptr;
int firstsuffix = Conf->naffixes;
- checkTmpCtx();
-
if (Conf->naffixes == 0)
return;
diff --git a/src/include/tsearch/dicts/spell.h b/src/include/tsearch/dicts/spell.h
index c2751c1690a..421a636dc71 100644
--- a/src/include/tsearch/dicts/spell.h
+++ b/src/include/tsearch/dicts/spell.h
@@ -138,14 +138,6 @@ typedef struct
int naffixes;
AFFIX *Affix;
- /*
- * Temporary array of all words in the dict file. Only used during
- * initialization
- */
- SPELL **Spell;
- int nspell; /* number of valid entries in Spell array */
- int mspell; /* allocated length of Spell array */
-
AffixNode *Suffix;
AffixNode *Prefix;
@@ -158,12 +150,26 @@ typedef struct
unsigned char flagval[256];
bool usecompound;
+
+ /*
+ * Remaining fields are only used during dictionary construction;
+ * they are set up by NIStartBuild and cleared by NIFinishBuild.
+ */
+ MemoryContext buildCxt; /* temp context for construction */
+
+ /* Temporary array of all words in the dict file */
+ SPELL **Spell;
+ int nspell; /* number of valid entries in Spell array */
+ int mspell; /* allocated length of Spell array */
} IspellDict;
extern TSLexeme *NINormalizeWord(IspellDict *Conf, char *word);
+
+extern void NIStartBuild(IspellDict *Conf);
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 void NIFinishBuild(IspellDict *Conf);
#endif