shithub: asif

Download patch

ref: 87053f0fe08729886e284c4e651c67d575182688
parent: f0aa2bfef6b39d26792d66be56565fca32d4a842
author: qwx <[email protected]>
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;
+}