2121
2222/*
2323 * Initialization requires a lot of memory that's not needed
24- * after the initialization is done. In init function ,
25- * CurrentMemoryContext is a long lived memory context associated
26- * with the dictionary cache entry, so we use a temporary context
27- * for the short-lived stuff .
24+ * after the initialization is done. During initialization ,
25+ * CurrentMemoryContext is the long- lived memory context associated
26+ * with the dictionary cache entry. We keep the short-lived stuff
27+ * in the Conf->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{
5671 MemoryContext saveCtx ;
5772 char * dst ;
5873
59- saveCtx = MemoryContextSwitchTo (tmpCtx );
74+ saveCtx = MemoryContextSwitchTo (Conf -> buildCxt );
6075 dst = lowerstr (src );
6176 MemoryContextSwitchTo (saveCtx );
6277
@@ -120,6 +135,7 @@ strbcmp(const unsigned char *s1, const unsigned char *s2)
120135
121136 return 0 ;
122137}
138+
123139static int
124140strbncmp (const unsigned char * s1 , const unsigned char * s2 , size_t count )
125141{
@@ -196,8 +212,6 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
196212 tsearch_readline_state trst ;
197213 char * line ;
198214
199- checkTmpCtx ();
200-
201215 if (!tsearch_readline_begin (& trst , filename ))
202216 ereport (ERROR ,
203217 (errcode (ERRCODE_CONFIG_FILE_ERROR ),
@@ -242,7 +256,7 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
242256 }
243257 s += pg_mblen (s );
244258 }
245- pstr = lowerstr_ctx (line );
259+ pstr = lowerstr_ctx (Conf , line );
246260
247261 NIAddSpell (Conf , pstr , flag );
248262 pfree (pstr );
@@ -545,8 +559,6 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
545559 char scanbuf [BUFSIZ ];
546560 char * recoded ;
547561
548- checkTmpCtx ();
549-
550562 /* read file to find any flag */
551563 memset (Conf -> flagval , 0 , sizeof (Conf -> flagval ));
552564 Conf -> usecompound = false;
@@ -624,7 +636,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
624636
625637 if (ptype )
626638 pfree (ptype );
627- ptype = lowerstr_ctx (type );
639+ ptype = lowerstr_ctx (Conf , type );
628640 if (scanread < 4 || (STRNCMP (ptype , "sfx" ) && STRNCMP (ptype , "pfx" )))
629641 goto nextline ;
630642
@@ -646,7 +658,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
646658
647659 if (strlen (sflag ) != 1 || flag != * sflag || flag == 0 )
648660 goto nextline ;
649- prepl = lowerstr_ctx (repl );
661+ prepl = lowerstr_ctx (Conf , repl );
650662 /* affix flag */
651663 if ((ptr = strchr (prepl , '/' )) != NULL )
652664 {
@@ -658,8 +670,8 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
658670 ptr ++ ;
659671 }
660672 }
661- pfind = lowerstr_ctx (find );
662- pmask = lowerstr_ctx (mask );
673+ pfind = lowerstr_ctx (Conf , find );
674+ pmask = lowerstr_ctx (Conf , mask );
663675 if (t_iseq (find , '0' ))
664676 * pfind = '\0' ;
665677 if (t_iseq (repl , '0' ))
@@ -702,8 +714,6 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
702714 bool oldformat = false;
703715 char * recoded = NULL ;
704716
705- checkTmpCtx ();
706-
707717 if (!tsearch_readline_begin (& trst , filename ))
708718 ereport (ERROR ,
709719 (errcode (ERRCODE_CONFIG_FILE_ERROR ),
@@ -945,8 +955,6 @@ NISortDictionary(IspellDict *Conf)
945955 int naffix = 0 ;
946956 int 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
986994 qsort ((void * ) Conf -> Spell , Conf -> nspell , sizeof (SPELL * ), cmpspell );
987995 Conf -> Dictionary = mkSPNode (Conf , 0 , Conf -> nspell , 0 );
988-
989- Conf -> Spell = NULL ;
990996}
991997
992998static AffixNode *
@@ -1123,8 +1129,6 @@ NISortAffixes(IspellDict *Conf)
11231129 CMPDAffix * ptr ;
11241130 int firstsuffix = Conf -> naffixes ;
11251131
1126- checkTmpCtx ();
1127-
11281132 if (Conf -> naffixes == 0 )
11291133 return ;
11301134
0 commit comments