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
This commit is contained in:
parent
bea3d7e383
commit
4f51429dd7
@ -655,17 +655,6 @@ FindWord(IspellDict *Conf, const char *word, const char *affixflag, int flag)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Context reset/delete callback for a regular expression used in an affix
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
regex_affix_deletion_callback(void *arg)
|
|
||||||
{
|
|
||||||
aff_regex_struct *pregex = (aff_regex_struct *) arg;
|
|
||||||
|
|
||||||
pg_regfree(&(pregex->regex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds a new affix rule to the Affix field.
|
* Adds a new affix rule to the Affix field.
|
||||||
*
|
*
|
||||||
@ -728,7 +717,6 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
|
|||||||
int err;
|
int err;
|
||||||
pg_wchar *wmask;
|
pg_wchar *wmask;
|
||||||
char *tmask;
|
char *tmask;
|
||||||
aff_regex_struct *pregex;
|
|
||||||
|
|
||||||
Affix->issimple = 0;
|
Affix->issimple = 0;
|
||||||
Affix->isregis = 0;
|
Affix->isregis = 0;
|
||||||
@ -743,31 +731,23 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask,
|
|||||||
wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen);
|
wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The regex engine stores its stuff using malloc not palloc, so we
|
* The regex and all internal state created by pg_regcomp are
|
||||||
* must arrange to explicitly clean up the regex when the dictionary's
|
* allocated in the dictionary's memory context, and will be freed
|
||||||
* context is cleared. That means the regex_t has to stay in a fixed
|
* automatically when it is destroyed.
|
||||||
* location within the context; we can't keep it directly in the AFFIX
|
|
||||||
* struct, since we may sort and resize the array of AFFIXes.
|
|
||||||
*/
|
*/
|
||||||
Affix->reg.pregex = pregex = palloc(sizeof(aff_regex_struct));
|
Affix->reg.pregex = palloc(sizeof(regex_t));
|
||||||
|
err = pg_regcomp(Affix->reg.pregex, wmask, wmasklen,
|
||||||
err = pg_regcomp(&(pregex->regex), wmask, wmasklen,
|
|
||||||
REG_ADVANCED | REG_NOSUB,
|
REG_ADVANCED | REG_NOSUB,
|
||||||
DEFAULT_COLLATION_OID);
|
DEFAULT_COLLATION_OID);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
char errstr[100];
|
char errstr[100];
|
||||||
|
|
||||||
pg_regerror(err, &(pregex->regex), errstr, sizeof(errstr));
|
pg_regerror(err, Affix->reg.pregex, errstr, sizeof(errstr));
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
|
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
|
||||||
errmsg("invalid regular expression: %s", errstr)));
|
errmsg("invalid regular expression: %s", errstr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pregex->mcallback.func = regex_affix_deletion_callback;
|
|
||||||
pregex->mcallback.arg = (void *) pregex;
|
|
||||||
MemoryContextRegisterResetCallback(CurrentMemoryContext,
|
|
||||||
&pregex->mcallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Affix->flagflags = flagflags;
|
Affix->flagflags = flagflags;
|
||||||
@ -2161,7 +2141,7 @@ CheckAffix(const char *word, size_t len, AFFIX *Affix, int flagflags, char *neww
|
|||||||
data = (pg_wchar *) palloc((newword_len + 1) * sizeof(pg_wchar));
|
data = (pg_wchar *) palloc((newword_len + 1) * sizeof(pg_wchar));
|
||||||
data_len = pg_mb2wchar_with_len(newword, data, newword_len);
|
data_len = pg_mb2wchar_with_len(newword, data, newword_len);
|
||||||
|
|
||||||
if (pg_regexec(&(Affix->reg.pregex->regex), data, data_len,
|
if (pg_regexec(Affix->reg.pregex, data, data_len,
|
||||||
0, NULL, 0, NULL, 0) == REG_OKAY)
|
0, NULL, 0, NULL, 0) == REG_OKAY)
|
||||||
{
|
{
|
||||||
pfree(data);
|
pfree(data);
|
||||||
|
@ -81,17 +81,6 @@ typedef struct spell_struct
|
|||||||
|
|
||||||
#define SPELLHDRSZ (offsetof(SPELL, word))
|
#define SPELLHDRSZ (offsetof(SPELL, word))
|
||||||
|
|
||||||
/*
|
|
||||||
* If an affix uses a regex, we have to store that separately in a struct
|
|
||||||
* that won't move around when arrays of affixes are enlarged or sorted.
|
|
||||||
* This is so that it can be found to be cleaned up at context destruction.
|
|
||||||
*/
|
|
||||||
typedef struct aff_regex_struct
|
|
||||||
{
|
|
||||||
regex_t regex;
|
|
||||||
MemoryContextCallback mcallback;
|
|
||||||
} aff_regex_struct;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Represents an entry in an affix list.
|
* Represents an entry in an affix list.
|
||||||
*/
|
*/
|
||||||
@ -108,7 +97,12 @@ typedef struct aff_struct
|
|||||||
char *repl;
|
char *repl;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
aff_regex_struct *pregex;
|
/*
|
||||||
|
* Arrays of AFFIX are moved and sorted. We'll use a pointer to
|
||||||
|
* regex_t to keep this struct small, and avoid assuming that regex_t
|
||||||
|
* is movable.
|
||||||
|
*/
|
||||||
|
regex_t *pregex;
|
||||||
Regis regis;
|
Regis regis;
|
||||||
} reg;
|
} reg;
|
||||||
} AFFIX;
|
} AFFIX;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user