From: Geoffrey Allott Date: Wed, 24 Aug 2022 22:10:31 +0000 (+0100) Subject: split logic into node_edge/node_edge_{en,de}code X-Git-Url: https://git.pointlesshacks.com/?a=commitdiff_plain;h=080afb949fcca6a5df88617f518ef928a515063c;p=tANS.git split logic into node_edge/node_edge_{en,de}code --- diff --git a/src/stree.c b/src/stree.c index 37ec431..9502117 100644 --- a/src/stree.c +++ b/src/stree.c @@ -88,59 +88,58 @@ static void node_sort_sons(struct node *self) } } -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; @@ -203,7 +202,10 @@ int stree_encode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux) ++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) { @@ -227,16 +229,20 @@ int stree_encode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux) 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) @@ -289,7 +295,10 @@ int stree_decode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux) 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) { @@ -314,16 +323,20 @@ int stree_decode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux) 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)