Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4f51429

Browse files
committed
Update tsearch regex memory management.
Now that our regex engine uses palloc(), it's not necessary to set up a special memory context callback to free compiled regexes. The regex has no resources other than the memory that is already going to be freed in bulk. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CA%2BhUKGK3PGKwcKqzoosamn36YW-fsuTdOPPF1i_rtEO%3DnEYKSg%40mail.gmail.com
1 parent bea3d7e commit 4f51429

File tree

2 files changed

+13
-39
lines changed

2 files changed

+13
-39
lines changed

src/backend/tsearch/spell.c

+7-27
Original file line numberDiff line numberDiff line change
@@ -655,17 +655,6 @@ FindWord(IspellDict *Conf, const char *word, const char *affixflag, int flag)
655655
return 0;
656656
}
657657

658-
/*
659-
* Context reset/delete callback for a regular expression used in an affix
660-
*/
661-
static void
662-
regex_affix_deletion_callback(void *arg)
663-
{
664-
aff_regex_struct *pregex = (aff_regex_struct *) arg;
665-
666-
pg_regfree(&(pregex->regex));
667-
}
668-
669658
/*
670659
* Adds a new affix rule to the Affix field.
671660
*
@@ -728,7 +717,6 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
728717
int err;
729718
pg_wchar *wmask;
730719
char *tmask;
731-
aff_regex_struct *pregex;
732720

733721
Affix->issimple = 0;
734722
Affix->isregis = 0;
@@ -743,31 +731,23 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
743731
wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen);
744732

745733
/*
746-
* The regex engine stores its stuff using malloc not palloc, so we
747-
* must arrange to explicitly clean up the regex when the dictionary's
748-
* context is cleared. That means the regex_t has to stay in a fixed
749-
* location within the context; we can't keep it directly in the AFFIX
750-
* struct, since we may sort and resize the array of AFFIXes.
734+
* The regex and all internal state created by pg_regcomp are
735+
* allocated in the dictionary's memory context, and will be freed
736+
* automatically when it is destroyed.
751737
*/
752-
Affix->reg.pregex = pregex = palloc(sizeof(aff_regex_struct));
753-
754-
err = pg_regcomp(&(pregex->regex), wmask, wmasklen,
738+
Affix->reg.pregex = palloc(sizeof(regex_t));
739+
err = pg_regcomp(Affix->reg.pregex, wmask, wmasklen,
755740
REG_ADVANCED | REG_NOSUB,
756741
DEFAULT_COLLATION_OID);
757742
if (err)
758743
{
759744
char errstr[100];
760745

761-
pg_regerror(err, &(pregex->regex), errstr, sizeof(errstr));
746+
pg_regerror(err, Affix->reg.pregex, errstr, sizeof(errstr));
762747
ereport(ERROR,
763748
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
764749
errmsg("invalid regular expression: %s", errstr)));
765750
}
766-
767-
pregex->mcallback.func = regex_affix_deletion_callback;
768-
pregex->mcallback.arg = (void *) pregex;
769-
MemoryContextRegisterResetCallback(CurrentMemoryContext,
770-
&pregex->mcallback);
771751
}
772752

773753
Affix->flagflags = flagflags;
@@ -2161,7 +2141,7 @@ CheckAffix(const char *word, size_t len, AFFIX *Affix, int flagflags, char *neww
21612141
data = (pg_wchar *) palloc((newword_len + 1) * sizeof(pg_wchar));
21622142
data_len = pg_mb2wchar_with_len(newword, data, newword_len);
21632143

2164-
if (pg_regexec(&(Affix->reg.pregex->regex), data, data_len,
2144+
if (pg_regexec(Affix->reg.pregex, data, data_len,
21652145
0, NULL, 0, NULL, 0) == REG_OKAY)
21662146
{
21672147
pfree(data);

src/include/tsearch/dicts/spell.h

+6-12
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,6 @@ typedef struct spell_struct
8181

8282
#define SPELLHDRSZ (offsetof(SPELL, word))
8383

84-
/*
85-
* If an affix uses a regex, we have to store that separately in a struct
86-
* that won't move around when arrays of affixes are enlarged or sorted.
87-
* This is so that it can be found to be cleaned up at context destruction.
88-
*/
89-
typedef struct aff_regex_struct
90-
{
91-
regex_t regex;
92-
MemoryContextCallback mcallback;
93-
} aff_regex_struct;
94-
9584
/*
9685
* Represents an entry in an affix list.
9786
*/
@@ -108,7 +97,12 @@ typedef struct aff_struct
10897
char *repl;
10998
union
11099
{
111-
aff_regex_struct *pregex;
100+
/*
101+
* Arrays of AFFIX are moved and sorted. We'll use a pointer to
102+
* regex_t to keep this struct small, and avoid assuming that regex_t
103+
* is movable.
104+
*/
105+
regex_t *pregex;
112106
Regis regis;
113107
} reg;
114108
} AFFIX;

0 commit comments

Comments
 (0)