}
}
-static struct node *node_edge_inv(struct node *self, uint8_t edge, const uint8_t *str, struct node **brother, bool seen[], uint8_t *code, bool record_seen)
+static struct node *node_edge_decode(struct node *self, const uint8_t *str, struct node **brother, bool seen[], uint8_t *code)
{
struct node *node;
- if (record_seen) {
- node_sort_sons(self);
+ node_sort_sons(self);
- for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother) {
- if (!seen[str[node->from]]) {
- seen[str[node->from]] = true;
- if (*code == 0) return node;
- --*code;
- }
+ for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother) {
+ if (!seen[str[node->from]]) {
+ seen[str[node->from]] = true;
+ if (*code == 0) return node;
+ --*code;
}
- } else {
- for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother)
- if (str[node->from] == edge)
- return node;
}
return (struct node *) 0;
}
-static struct node *node_edge(struct node *self, uint8_t edge, const uint8_t *str, struct node **brother, bool seen[], uint8_t *code, bool record_seen)
+static struct node *node_edge_encode(struct node *self, size_t i, const uint8_t *str, struct node **brother, bool seen[], uint8_t *code)
{
struct node *node;
- if (record_seen) {
- node_sort_sons(self);
+ node_sort_sons(self);
- for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother) {
- if (str[node->from] == edge) return node;
- if (!seen[str[node->from]]) {
- seen[str[node->from]] = true;
- ++*code;
- }
+ for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother) {
+ if (str[node->from] == str[i]) return node;
+ if (!seen[str[node->from]]) {
+ seen[str[node->from]] = true;
+ ++*code;
}
- } else {
- for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother)
- if (str[node->from] == edge)
- return node;
}
return (struct node *) 0;
}
+static struct node *node_edge(struct node *self, size_t i, const uint8_t *str, struct node **brother)
+{
+ struct node *node;
+
+ for (*brother = (struct node *) 0, node = self->son; node; *brother = node, node = node->brother)
+ if (str[node->from] == str[i])
+ return node;
+
+ return (struct node *) 0;
+}
+
static bool node_validate_suffix(struct node *self, size_t len, const uint8_t *str, size_t i)
{
struct node *node, *brother;
size_t j;
if (len == 0) return true;
- node = node_edge(self, str[i], str, &brother, (bool *) 0, (uint8_t *) 0, false);
+ node = node_edge(self, i, str, &brother);
if (!node) return false;
for (j = node->from; j < node->to && len > 0; --len, ++j, ++i) {
if (str[j] != str[i]) return false;
++rem;
memset(seen, 0, sizeof seen);
code = 0;
- active_edge = node_edge(active_node, in[i-active_len], in, &brother, seen, &code, active_len == 0);
+ if (active_len == 0)
+ active_edge = node_edge_encode(active_node, i, in, &brother, seen, &code);
+ else
+ active_edge = node_edge(active_node, i - active_len, in, &brother);
do {
present = active_edge && in[active_edge->from+active_len] == in[i];
if (present) {
active_node = active_node->link ? active_node->link : (active_len = rem - 1, root);
if (active_len == 0 && active_node->son == nodes + n - 1)
brother = active_edge = (struct node *) 0;
+ else if (active_len == 0)
+ active_edge = node_edge_encode(active_node, i, in, &brother, seen, &code);
else
- active_edge = node_edge(active_node, in[i-active_len], in, &brother, seen, &code, active_len == 0);
+ active_edge = node_edge(active_node, i - active_len, in, &brother);
}
while (active_edge && active_edge->from + active_len >= active_edge->to) {
active_node = active_edge;
active_len -= active_node->to - active_node->from;
if (active_len == 0 && present)
brother = active_edge = (struct node *) 0;
+ else if (active_len == 0)
+ active_edge = node_edge_encode(active_node, i, in, &brother, seen, &code);
else
- active_edge = node_edge(active_node, in[i-active_len], in, &brother, seen, &code, active_len == 0 && !present);
+ active_edge = node_edge(active_node, i - active_len, in, &brother);
}
} while (rem > 0 && !present);
if (!present)
memset(seen, 0, sizeof seen);
code = in[i];
- active_edge = node_edge_inv(active_node, out[i-active_len], out, &brother, seen, &code, active_len == 0);
+ if (active_len == 0)
+ active_edge = node_edge_decode(active_node, out, &brother, seen, &code);
+ else
+ active_edge = node_edge(active_node, i - active_len, out, &brother);
do {
present = active_edge && code == 0 && (active_len == 0 || !seen[out[active_edge->from+active_len]]);
if (present) {
active_node = active_node->link ? active_node->link : (active_len = rem - 1, root);
if (active_len == 0 && active_node->son == nodes + n - 1)
brother = active_edge = (struct node *) 0;
+ else if (active_len == 0)
+ active_edge = node_edge_decode(active_node, out, &brother, seen, &code);
else
- active_edge = node_edge_inv(active_node, out[i-active_len], out, &brother, seen, &code, active_len == 0);
+ active_edge = node_edge(active_node, i - active_len, out, &brother);
}
while (active_edge && active_edge->from + active_len >= active_edge->to) {
active_node = active_edge;
active_len -= active_node->to - active_node->from;
if (active_len == 0 && present)
brother = active_edge = (struct node *) 0;
+ else if (active_len == 0)
+ active_edge = node_edge_decode(active_node, out, &brother, seen, &code);
else
- active_edge = node_edge_inv(active_node, out[i-active_len], out, &brother, seen, &code, active_len == 0);
+ active_edge = node_edge(active_node, i - active_len, out, &brother);
}
} while (rem > 0 && !present);
if (!present)