Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/regex')
-rw-r--r--src/backend/regex/regc_nfa.c66
1 files changed, 62 insertions, 4 deletions
diff --git a/src/backend/regex/regc_nfa.c b/src/backend/regex/regc_nfa.c
index 6d77c59e121..059cf64df07 100644
--- a/src/backend/regex/regc_nfa.c
+++ b/src/backend/regex/regc_nfa.c
@@ -777,6 +777,10 @@ sortouts_cmp(const void *a, const void *b)
* However, if we have a whole lot of arcs to deal with, retail duplicate
* checks become too slow. In that case we proceed by sorting and merging
* the arc lists, and then we can indeed just update the arcs in-place.
+ *
+ * On the other hand, it's also true that this is frequently called with
+ * a brand-new newState that has no existing in-arcs. In that case,
+ * de-duplication is unnecessary, so we can just blindly move all the arcs.
*/
static void
moveins(struct nfa *nfa,
@@ -785,7 +789,18 @@ moveins(struct nfa *nfa,
{
assert(oldState != newState);
- if (!BULK_ARC_OP_USE_SORT(oldState->nins, newState->nins))
+ if (newState->nins == 0)
+ {
+ /* No need for de-duplication */
+ struct arc *a;
+
+ while ((a = oldState->ins) != NULL)
+ {
+ createarc(nfa, a->type, a->co, a->from, newState);
+ freearc(nfa, a);
+ }
+ }
+ else if (!BULK_ARC_OP_USE_SORT(oldState->nins, newState->nins))
{
/* With not too many arcs, just do them one at a time */
struct arc *a;
@@ -869,6 +884,11 @@ moveins(struct nfa *nfa,
/*
* copyins - copy in arcs of a state to another state
+ *
+ * The comments for moveins() apply here as well. However, in current
+ * usage, this is *only* called with brand-new target states, so that
+ * only the "no need for de-duplication" code path is ever reached.
+ * We keep the rest #ifdef'd out in case it's needed in the future.
*/
static void
copyins(struct nfa *nfa,
@@ -876,8 +896,18 @@ copyins(struct nfa *nfa,
struct state *newState)
{
assert(oldState != newState);
+ assert(newState->nins == 0); /* see comment above */
+
+ if (newState->nins == 0)
+ {
+ /* No need for de-duplication */
+ struct arc *a;
- if (!BULK_ARC_OP_USE_SORT(oldState->nins, newState->nins))
+ for (a = oldState->ins; a != NULL; a = a->inchain)
+ createarc(nfa, a->type, a->co, a->from, newState);
+ }
+#ifdef NOT_USED /* see comment above */
+ else if (!BULK_ARC_OP_USE_SORT(oldState->nins, newState->nins))
{
/* With not too many arcs, just do them one at a time */
struct arc *a;
@@ -944,6 +974,7 @@ copyins(struct nfa *nfa,
createarc(nfa, a->type, a->co, a->from, newState);
}
}
+#endif /* NOT_USED */
}
/*
@@ -1058,7 +1089,18 @@ moveouts(struct nfa *nfa,
{
assert(oldState != newState);
- if (!BULK_ARC_OP_USE_SORT(oldState->nouts, newState->nouts))
+ if (newState->nouts == 0)
+ {
+ /* No need for de-duplication */
+ struct arc *a;
+
+ while ((a = oldState->outs) != NULL)
+ {
+ createarc(nfa, a->type, a->co, newState, a->to);
+ freearc(nfa, a);
+ }
+ }
+ else if (!BULK_ARC_OP_USE_SORT(oldState->nouts, newState->nouts))
{
/* With not too many arcs, just do them one at a time */
struct arc *a;
@@ -1142,6 +1184,8 @@ moveouts(struct nfa *nfa,
/*
* copyouts - copy out arcs of a state to another state
+ *
+ * See comments for copyins()
*/
static void
copyouts(struct nfa *nfa,
@@ -1149,8 +1193,18 @@ copyouts(struct nfa *nfa,
struct state *newState)
{
assert(oldState != newState);
+ assert(newState->nouts == 0); /* see comment above */
+
+ if (newState->nouts == 0)
+ {
+ /* No need for de-duplication */
+ struct arc *a;
- if (!BULK_ARC_OP_USE_SORT(oldState->nouts, newState->nouts))
+ for (a = oldState->outs; a != NULL; a = a->outchain)
+ createarc(nfa, a->type, a->co, newState, a->to);
+ }
+#ifdef NOT_USED /* see comment above */
+ else if (!BULK_ARC_OP_USE_SORT(oldState->nouts, newState->nouts))
{
/* With not too many arcs, just do them one at a time */
struct arc *a;
@@ -1217,6 +1271,7 @@ copyouts(struct nfa *nfa,
createarc(nfa, a->type, a->co, newState, a->to);
}
}
+#endif /* NOT_USED */
}
/*
@@ -1975,6 +2030,7 @@ combine(struct nfa *nfa,
else if (a->co == RAINBOW)
{
/* con is incompatible if it's for a pseudocolor */
+ /* (this is hypothetical; we make no such constraints today) */
if (nfa->cm->cd[con->co].flags & PSEUDO)
return INCOMPATIBLE;
/* otherwise, constraint constrains arc to be only its color */
@@ -2001,6 +2057,7 @@ combine(struct nfa *nfa,
else if (a->co == RAINBOW)
{
/* con is incompatible if it's for a pseudocolor */
+ /* (this is hypothetical; we make no such constraints today) */
if (nfa->cm->cd[con->co].flags & PSEUDO)
return INCOMPATIBLE;
/* otherwise, constraint constrains arc to be only its color */
@@ -3562,6 +3619,7 @@ carc_cmp(const void *a, const void *b)
return -1;
if (aa->to > bb->to)
return +1;
+ /* This is unreached, since there should be no duplicate arcs now: */
return 0;
}