From 2b05f07c1fc545954bfd10d7b46fc13422f802c9 Mon Sep 17 00:00:00 2001 From: alex-s168 Date: Thu, 4 Sep 2025 19:17:52 +0200 Subject: [PATCH] wip --- adj_matrix.c | 12 +++ common.h | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 adj_matrix.c create mode 100644 common.h diff --git a/adj_matrix.c b/adj_matrix.c new file mode 100644 index 0000000..73587a6 --- /dev/null +++ b/adj_matrix.c @@ -0,0 +1,12 @@ +#include "common.h" + +int main(int argc, char **argv) { + char buf[512]; + char *dest; + + while (( dest = slowgraph_next_edge(stdin, buf, slowgraph_lenof(buf), 0) )) { + printf("%s -> %s\n", buf, dest); + } + + return 0; +} diff --git a/common.h b/common.h new file mode 100644 index 0000000..b461d93 --- /dev/null +++ b/common.h @@ -0,0 +1,201 @@ +#ifndef SLOWGRAPH_COMMON_H +#define SLOWGRAPH_COMMON_H + +#include +#include +#include +#include +#include + +#define slowgraph_lenof(x) (sizeof((x)) / sizeof(*(x))) + +static unsigned +slowgraph_hash(char const *buf) { + unsigned res = 5381; + for (; *buf; buf++) { + res = (res << 5) + res + *buf; + } + return res; +} + +static unsigned +slowgraph_hashn(void const *bufp, int len) { + char const* buf = (char const *) bufp; + unsigned res = 5381; + for (; buf != buf + len; buf ++) { + res = (res << 5) + res + *buf; + } + return res; +} + +static char * +slowgraph_next_edge( + FILE* inp, + char* buf, int bufn, + void (*opt_attr_clbk)(char* node, char* key, char* val)) +{ + int c; + char *n, *k, *v, *retv = 0; + + c = fgetc(inp); + + for (;;) { + if (c == EOF) { + retv = 0; + break; + } + + for (; isspace(c); c = fgetc(inp)) + ; + + if (c == '#') { + c = fgetc(inp); + if (c == '#' && opt_attr_clbk && buf == fgets(buf, bufn, inp)) { + n = strtok(buf+1, " \r\n"); + k = strtok(0, " \r\n"); + v = strtok(0, " \r\n"); + opt_attr_clbk(n, k, v); + } else { + for (; c != EOF && c != '\n'; c = fgetc(inp)) + ; + c = fgetc(inp); + } + continue; + } + + for (k = buf; c != EOF && !isspace(c); k ++) { + *k = c; + c = fgetc(inp); + } + + *k++=0; + + for (; isspace(c); c = fgetc(inp)) + ; + + for (v = k; c != EOF && !isspace(c); v ++) { + *v = c; + c = fgetc(inp); + } + *v = 0; + + retv = k; + break; + } + + ungetc(c, inp); + return retv; +} + +typedef struct SlowGraph SlowGraph; +typedef struct SlowGraphNode SlowGraphNode; +typedef struct SlowGraphEdge SlowGraphEdge; +typedef struct SlowGraphAttr SlowGraphAttr; + +struct SlowGraphAttr { + SlowGraphAttr* next; + unsigned hash; + char *key, *val; +}; + +static char* +SlowGraphAttr_find(SlowGraphAttr* a, unsigned hash) { + for (; a; a = a->next) + if (a->hash == hash) + return a->val; + return 0; +} + +struct SlowGraphNode { + SlowGraphNode *next; + + unsigned name_hash; + char *name; + SlowGraphAttr* attr; + SlowGraphEdge* children; + + unsigned gc_used : 1; +}; + +struct SlowGraphEdge { + SlowGraphEdge *next; + unsigned cost; + unsigned aig_inv : 1; + unsigned user_attr; + + SlowGraphNode *node; +}; + +struct SlowGraph { + SlowGraphNode *first; +}; + +// Step 1: call SlowGraph_markAllUnused(graph) +// +// Step 2: manually mark input nodes as used +// +// Step 3: call SlowGraph_gcUnused(graph) // only deletes nodes not used by manually marked used nodes +static void +SlowGraph_markAllUnused(SlowGraph *graph) { + SlowGraphNode *n; + for (n = graph->first; n; n = n->next) + n->gc_used = 0; +} + +// Step 1: call SlowGraph_markAllUnused(graph) +// +// Step 2: manually mark input nodes as used +// +// Step 3: call SlowGraph_gcUnused(graph) // only deletes nodes not used by manually marked used nodes +static void +SlowGraph_gcUnused(SlowGraph *graph) { + int changed = 0; + SlowGraphNode *n, *o, **prev; + SlowGraphEdge *e, *oe; + SlowGraphAttr *a, *oa; + + do { + for (n = graph->first; n; n = n->next) { + if (n->gc_used) { + for (e = n->children; e; e = e->next) { + if (!e->node->gc_used) { + e->node->gc_used = 1; + changed = 1; + } + } + } + } + } while (changed); + + prev = &graph->first; + for (n = graph->first; n; ) { + if (n->gc_used) { + prev = &n->next; + n = n->next; + } else { + o = n; + n = n->next; + *prev = n; + + for (e = o->children; e; ) { + oe = e; + e = e->next; + free(oe); + } + + for (a = o->attr; a; ) { + oa = a; + a = a->next; + + free(a->key); + free(a->val); + free(a); + } + + free(o->name); + free(o); + } + } +} + +#endif