Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9b910de

Browse files
committed
Clean up temporary-memory management during ispell dictionary loading.
Add explicit initialization and cleanup functions to spell.c, and keepall working state in the already-existing ISpellDict struct. This lets usget rid of a static variable along with some extremely shaky assumptionsabout usage of child memory contexts.This commit is just code beautification and has no impact on functionalityor performance, but it opens the way to a less-grotty implementation ofPavel's memory-saving hack, which will follow shortly.
1 parentbdf4579 commit9b910de

File tree

3 files changed

+62
-51
lines changed

3 files changed

+62
-51
lines changed

‎src/backend/tsearch/dict_ispell.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include"tsearch/ts_public.h"
2020
#include"tsearch/ts_utils.h"
2121
#include"utils/builtins.h"
22-
#include"utils/memutils.h"
2322

2423

2524
typedefstruct
@@ -40,6 +39,8 @@ dispell_init(PG_FUNCTION_ARGS)
4039

4140
d= (DictISpell*)palloc0(sizeof(DictISpell));
4241

42+
NIStartBuild(&(d->obj));
43+
4344
foreach(l,dictoptions)
4445
{
4546
DefElem*defel= (DefElem*)lfirst(l);
@@ -102,7 +103,7 @@ dispell_init(PG_FUNCTION_ARGS)
102103
errmsg("missing DictFile parameter")));
103104
}
104105

105-
MemoryContextDeleteChildren(CurrentMemoryContext);
106+
NIFinishBuild(&(d->obj));
106107

107108
PG_RETURN_POINTER(d);
108109
}

‎src/backend/tsearch/spell.c

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,57 @@
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 longlived 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-
staticMemoryContexttmpCtx=NULL;
29+
#definetmpalloc(sz) MemoryContextAlloc(Conf->buildCxt, (sz))
30+
#definetmpalloc0(sz) MemoryContextAllocZero(Conf->buildCxt, (sz))
3031

31-
#definetmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
32-
#definetmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
33-
34-
staticvoid
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+
*/
5368
staticchar*
54-
lowerstr_ctx(char*src)
69+
lowerstr_ctx(IspellDict*Conf,constchar*src)
5570
{
5671
MemoryContextsaveCtx;
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
return0;
122137
}
138+
123139
staticint
124140
strbncmp(constunsignedchar*s1,constunsignedchar*s2,size_tcount)
125141
{
@@ -196,8 +212,6 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
196212
tsearch_readline_statetrst;
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
charscanbuf[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
gotonextline;
630642

@@ -646,7 +658,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
646658

647659
if (strlen(sflag)!=1||flag!=*sflag||flag==0)
648660
gotonextline;
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
boololdformat= 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
intnaffix=0;
946956
intcuraffix;
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

992998
staticAffixNode*
@@ -1123,8 +1129,6 @@ NISortAffixes(IspellDict *Conf)
11231129
CMPDAffix*ptr;
11241130
intfirstsuffix=Conf->naffixes;
11251131

1126-
checkTmpCtx();
1127-
11281132
if (Conf->naffixes==0)
11291133
return;
11301134

‎src/include/tsearch/dicts/spell.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,6 @@ typedef struct
138138
intnaffixes;
139139
AFFIX*Affix;
140140

141-
/*
142-
* Temporary array of all words in the dict file. Only used during
143-
* initialization
144-
*/
145-
SPELL**Spell;
146-
intnspell;/* number of valid entries in Spell array */
147-
intmspell;/* allocated length of Spell array */
148-
149141
AffixNode*Suffix;
150142
AffixNode*Prefix;
151143

@@ -158,12 +150,26 @@ typedef struct
158150

159151
unsignedcharflagval[256];
160152
boolusecompound;
153+
154+
/*
155+
* Remaining fields are only used during dictionary construction;
156+
* they are set up by NIStartBuild and cleared by NIFinishBuild.
157+
*/
158+
MemoryContextbuildCxt;/* temp context for construction */
159+
160+
/* Temporary array of all words in the dict file */
161+
SPELL**Spell;
162+
intnspell;/* number of valid entries in Spell array */
163+
intmspell;/* allocated length of Spell array */
161164
}IspellDict;
162165

163166
externTSLexeme*NINormalizeWord(IspellDict*Conf,char*word);
167+
168+
externvoidNIStartBuild(IspellDict*Conf);
164169
externvoidNIImportAffixes(IspellDict*Conf,constchar*filename);
165170
externvoidNIImportDictionary(IspellDict*Conf,constchar*filename);
166171
externvoidNISortDictionary(IspellDict*Conf);
167172
externvoidNISortAffixes(IspellDict*Conf);
173+
externvoidNIFinishBuild(IspellDict*Conf);
168174

169175
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp