2121
2222/*
2323 * Initialization requires a lot of memory that's not needed
24- * after the initialization is done.In init function ,
25- * CurrentMemoryContext isa long lived memory context associated
26- * with the dictionary cache entry, so we use a temporary context
27- *for theshort-lived stuff .
24+ * after the initialization is done.During initialization ,
25+ * CurrentMemoryContext isthe long- lived memory context associated
26+ * with the dictionary cache entry. We keep the short-lived stuff
27+ *in theConf->buildCxt context .
2828 */
29- static MemoryContext tmpCtx = NULL ;
29+ #define tmpalloc (sz ) MemoryContextAlloc(Conf->buildCxt, (sz))
30+ #define tmpalloc0 (sz ) MemoryContextAllocZero(Conf->buildCxt, (sz))
3031
31- #define tmpalloc (sz ) MemoryContextAlloc(tmpCtx, (sz))
32- #define tmpalloc0 (sz ) MemoryContextAllocZero(tmpCtx, (sz))
33-
34- static void
35- checkTmpCtx (void )
32+ /*
33+ * Prepare for constructing an ISpell dictionary.
34+ *
35+ * The IspellDict struct is assumed to be zeroed when allocated.
36+ */
37+ void
38+ NIStartBuild (IspellDict * Conf )
3639{
3740/*
38- *XXX: This assumes that CurrentMemoryContext doesn't have any children
39- *other than the one we create here .
41+ *The temp context is a child of CurTransactionContext, so that it will
42+ *go away automatically on error .
4043 */
41- if (CurrentMemoryContext -> firstchild == NULL )
42- {
43- tmpCtx = AllocSetContextCreate (CurrentMemoryContext ,
44- "Ispell dictionary init context" ,
45- ALLOCSET_DEFAULT_MINSIZE ,
46- ALLOCSET_DEFAULT_INITSIZE ,
47- ALLOCSET_DEFAULT_MAXSIZE );
48- }
49- else
50- tmpCtx = CurrentMemoryContext -> firstchild ;
44+ Conf -> buildCxt = AllocSetContextCreate (CurTransactionContext ,
45+ "Ispell dictionary init context" ,
46+ ALLOCSET_DEFAULT_MINSIZE ,
47+ ALLOCSET_DEFAULT_INITSIZE ,
48+ ALLOCSET_DEFAULT_MAXSIZE );
5149}
5250
51+ /*
52+ * Clean up when dictionary construction is complete.
53+ */
54+ void
55+ NIFinishBuild (IspellDict * Conf )
56+ {
57+ /* Release no-longer-needed temp memory */
58+ MemoryContextDelete (Conf -> buildCxt );
59+ /* Just for cleanliness, zero the now-dangling pointers */
60+ Conf -> buildCxt = NULL ;
61+ Conf -> Spell = NULL ;
62+ }
63+
64+
65+ /*
66+ * Apply lowerstr(), producing a temporary result (in the buildCxt).
67+ */
5368static char *
54- lowerstr_ctx (char * src )
69+ lowerstr_ctx (IspellDict * Conf , const char * src )
5570{
5671MemoryContext saveCtx ;
5772char * dst ;
5873
59- saveCtx = MemoryContextSwitchTo (tmpCtx );
74+ saveCtx = MemoryContextSwitchTo (Conf -> buildCxt );
6075dst = lowerstr (src );
6176MemoryContextSwitchTo (saveCtx );
6277
@@ -120,6 +135,7 @@ strbcmp(const unsigned char *s1, const unsigned char *s2)
120135
121136return 0 ;
122137}
138+
123139static int
124140strbncmp (const unsignedchar * s1 ,const unsignedchar * s2 ,size_t count )
125141{
@@ -196,8 +212,6 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
196212tsearch_readline_state trst ;
197213char * line ;
198214
199- checkTmpCtx ();
200-
201215if (!tsearch_readline_begin (& trst ,filename ))
202216ereport (ERROR ,
203217(errcode (ERRCODE_CONFIG_FILE_ERROR ),
@@ -242,7 +256,7 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
242256}
243257s += pg_mblen (s );
244258}
245- pstr = lowerstr_ctx (line );
259+ pstr = lowerstr_ctx (Conf , line );
246260
247261NIAddSpell (Conf ,pstr ,flag );
248262pfree (pstr );
@@ -545,8 +559,6 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
545559char scanbuf [BUFSIZ ];
546560char * recoded ;
547561
548- checkTmpCtx ();
549-
550562/* read file to find any flag */
551563memset (Conf -> flagval ,0 ,sizeof (Conf -> flagval ));
552564Conf -> usecompound = false;
@@ -624,7 +636,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
624636
625637if (ptype )
626638pfree (ptype );
627- ptype = lowerstr_ctx (type );
639+ ptype = lowerstr_ctx (Conf , type );
628640if (scanread < 4 || (STRNCMP (ptype ,"sfx" )&& STRNCMP (ptype ,"pfx" )))
629641gotonextline ;
630642
@@ -646,7 +658,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
646658
647659if (strlen (sflag )!= 1 || flag != * sflag || flag == 0 )
648660gotonextline ;
649- prepl = lowerstr_ctx (repl );
661+ prepl = lowerstr_ctx (Conf , repl );
650662/* affix flag */
651663if ((ptr = strchr (prepl ,'/' ))!= NULL )
652664{
@@ -658,8 +670,8 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
658670ptr ++ ;
659671}
660672}
661- pfind = lowerstr_ctx (find );
662- pmask = lowerstr_ctx (mask );
673+ pfind = lowerstr_ctx (Conf , find );
674+ pmask = lowerstr_ctx (Conf , mask );
663675if (t_iseq (find ,'0' ))
664676* pfind = '\0' ;
665677if (t_iseq (repl ,'0' ))
@@ -702,8 +714,6 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
702714bool oldformat = false;
703715char * recoded = NULL ;
704716
705- checkTmpCtx ();
706-
707717if (!tsearch_readline_begin (& trst ,filename ))
708718ereport (ERROR ,
709719(errcode (ERRCODE_CONFIG_FILE_ERROR ),
@@ -945,8 +955,6 @@ NISortDictionary(IspellDict *Conf)
945955int naffix = 0 ;
946956int curaffix ;
947957
948- checkTmpCtx ();
949-
950958/* compress affixes */
951959
952960/* Count the number of different flags used in the dictionary */
@@ -985,8 +993,6 @@ NISortDictionary(IspellDict *Conf)
985993
986994qsort ((void * )Conf -> Spell ,Conf -> nspell ,sizeof (SPELL * ),cmpspell );
987995Conf -> Dictionary = mkSPNode (Conf ,0 ,Conf -> nspell ,0 );
988-
989- Conf -> Spell = NULL ;
990996}
991997
992998static AffixNode *
@@ -1123,8 +1129,6 @@ NISortAffixes(IspellDict *Conf)
11231129CMPDAffix * ptr ;
11241130int firstsuffix = Conf -> naffixes ;
11251131
1126- checkTmpCtx ();
1127-
11281132if (Conf -> naffixes == 0 )
11291133return ;
11301134