wip
This commit is contained in:
12
adj_matrix.c
Normal file
12
adj_matrix.c
Normal file
@@ -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;
|
||||
}
|
201
common.h
Normal file
201
common.h
Normal file
@@ -0,0 +1,201 @@
|
||||
#ifndef SLOWGRAPH_COMMON_H
|
||||
#define SLOWGRAPH_COMMON_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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
|
Reference in New Issue
Block a user