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

Lines changed: 7 additions & 27 deletions
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

Lines changed: 6 additions & 12 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy