summaryrefslogtreecommitdiff
path: root/src/libs6rc/s6rc_graph_closure.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-06-04 20:48:10 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-06-04 20:48:10 +0000
commit4b31caa9cdaef67c70bc7fb43963ba68b7bf5bb1 (patch)
treeb9d634a9199d7f69ae4e1f35d88edac63d04abcf /src/libs6rc/s6rc_graph_closure.c
downloads6-rc-4b31caa9cdaef67c70bc7fb43963ba68b7bf5bb1.tar.xz
Initial commit
Diffstat (limited to 'src/libs6rc/s6rc_graph_closure.c')
-rw-r--r--src/libs6rc/s6rc_graph_closure.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/libs6rc/s6rc_graph_closure.c b/src/libs6rc/s6rc_graph_closure.c
new file mode 100644
index 0000000..0ec2def
--- /dev/null
+++ b/src/libs6rc/s6rc_graph_closure.c
@@ -0,0 +1,39 @@
+/* ISC license. */
+
+#include <skalibs/bitarray.h>
+#include <s6-rc/s6rc-db.h>
+#include <s6-rc/s6rc-utils.h>
+
+typedef struct recinfo_s recinfo_t, *recinfo_t_ref ;
+struct recinfo_s
+{
+ s6rc_db_t const *db ;
+ unsigned int n ;
+ unsigned char *bits ;
+ unsigned char *mark ;
+ unsigned char mask ;
+ unsigned char h : 1 ;
+} ;
+
+static void s6rc_graph_closure_rec (recinfo_t *recinfo, unsigned int i)
+{
+ if (!bitarray_peek(recinfo->mark, i))
+ {
+ unsigned int j = recinfo->db->services[i].ndeps[recinfo->h] ;
+ bitarray_set(recinfo->mark, i) ;
+ while (j--) s6rc_graph_closure_rec(recinfo, recinfo->db->deps[recinfo->h * recinfo->db->ndeps + recinfo->db->services[i].deps[recinfo->h] + j]) ;
+ recinfo->bits[i] |= recinfo->mask ;
+ }
+}
+
+void s6rc_graph_closure (s6rc_db_t const *db, unsigned char *bits, unsigned int bitno, int h)
+{
+ unsigned int n = db->nshort + db->nlong ;
+ unsigned int m = bitarray_div8(n) ;
+ unsigned char mark[m] ;
+ recinfo_t info = { .db = db, .n = n, .bits = bits, .mark = mark, .mask = 1 << (bitno & 7), .h = !!h } ;
+ register unsigned int i = n ;
+ byte_zero(mark, m) ;
+ while (i--)
+ if (bits[i] & info.mask) s6rc_graph_closure_rec(&info, i) ;
+}