ref: 87053f0fe08729886e284c4e651c67d575182688
parent: f0aa2bfef6b39d26792d66be56565fca32d4a842
author: qwx <qwx@sciops.net>
date: Wed Jun 21 02:24:19 EDT 2023
archive another shitty vector impl unsharded version, just a simple buffer; like the old vec.c, error-prone interface because of the counter-intuitive way elements are added; could be improved, but we can do better than this anyway
--- /dev/null
+++ b/vecarr.c
@@ -1,0 +1,118 @@
+#include <u.h>
+#include <libc.h>
+#include "asif.h"
+
+static Vecarr *
+checksize(Vecarr *v)
+{
+ assert(v->len * v->elsz <= v->bufsz);
+ if((v->len + 1) * v->elsz < v->bufsz)
+ return v;
+ v->buf = erealloc(v->buf, v->bufsz * 2, v->bufsz);
+ v->bufsz *= 2;
+ v->tail = (uchar *)v->buf + v->len * v->elsz;
+ return v;
+}
+
+void
+vecarrnuke(Vecarr *v)
+{
+ if(v == nil)
+ return;
+ memset(v->buf, 0xf1, v->bufsz); /* FIXME: just let pool do it? */
+ free(v->buf);
+ v->buf = nil;
+ v->tail = nil;
+}
+
+usize
+vecarrindexof(Vecarr *v, void *p)
+{
+ uintptr x;
+
+ assert(v != nil && p >= v->buf && p < (uchar *)v->buf + v->elsz * v->len);
+ x = (uchar *)p - (uchar *)v->buf;
+ if(x % v->elsz != 0)
+ panic("vecarrindexof: invalid pointer");
+ return x / v->elsz;
+}
+
+void *
+vecarrget(Vecarr *v, usize i)
+{
+ void *n;
+
+ if(i >= v->len || v->len == 0){
+ werrstr("vecarrget %#p[%zd]: out of bounds", v, i);
+ return nil;
+ }
+ n = (uchar*)v->buf + i * v->elsz;
+ return n;
+}
+
+void *
+vecarrpoptail(Vecarr *v)
+{
+ void *n;
+
+ assert(v->len > 0);
+ n = v->tail;
+ v->len--;
+ v->tail = (uchar *)v->tail - v->elsz;
+ return n;
+}
+
+void *
+vecarrp(Vecarr *v, usize i)
+{
+ void *p;
+
+ p = (uchar *)v->buf + v->elsz * i;
+ assert(p >= v->buf && p < (uchar *)v->buf + v->elsz * v->len);
+ return p;
+}
+
+void
+vecarrresize(Vecarr *v, usize nel)
+{
+ assert(v->elsz > 0);
+ if(nel == v->len)
+ return;
+ v->buf = erealloc(v->buf, nel * v->elsz, v->bufsz);
+ v->len = nel;
+ v->bufsz = v->len * v->elsz;
+ v->tail = (uchar *)v->buf + v->bufsz;
+}
+
+void *
+vecarrcopy(Vecarr *v, void *p, usize *ip)
+{
+ usize i;
+ uchar *t;
+
+ assert((uintptr)p > v->elsz);
+ checksize(v);
+ i = v->elsz * v->len;
+ t = (uchar *)v->buf + i;
+ memcpy(t, p, v->elsz);
+ v->len++;
+ if(ip != nil)
+ *ip = i / v->elsz;
+ v->tail = t + v->elsz;
+ return (void *)t;
+}
+
+Vecarr
+vecarr(usize elsz, usize len)
+{
+ Vecarr v;
+
+ assert(elsz > 0);
+ memset(&v, 0, sizeof v);
+ v.elsz = elsz;
+ v.len = 0;
+ v.bufsz = (len > 2 ? len : 2) * elsz;
+ v.buf = emalloc(v.bufsz);
+ v.tail = v.buf;
+ return v;
+}