shithub: asif

Download patch

ref: 2603b42d0f2caa502411848f7c4062e290dde2dd
parent: b5baeb3dc3f2d6e45d0b2da3b2e82cad103c1789
author: qwx <qwx@sciops.net>
date: Tue Feb 22 19:14:03 EST 2022

add shitty vectors from sce

--- a/asif.h
+++ b/asif.h
@@ -16,6 +16,22 @@
 void	vinsert(VArray*, char*);
 VArray*	valloc(ulong, int);
 
+typedef struct Vector Vector;
+struct Vector{
+	void *p;
+	ulong n;
+	ulong elsz;
+	ulong bufsz;
+	ulong totsz;
+	int firstempty;
+};
+void	freevec(Vector*);
+void	clearvec(Vector*);
+void	popsparsevec(Vector*, int);
+void*	pushsparsevec(Vector*, void*);
+void*	pushvec(Vector*, void*);
+void*	newvec(Vector*, int, int);
+
 u32int	next32pow2(u32int);
 int	lsb64(uvlong);
 int	msb64(uvlong);
--- /dev/null
+++ b/vec.c
@@ -1,0 +1,92 @@
+#include <u.h>
+#include <libc.h>
+#include "asif.h"
+
+enum{
+	Nvecinc = 64,
+};
+
+void
+freevec(Vector *v)
+{
+	if(v == nil)
+		return;
+	free(v->p);
+}
+
+void
+clearvec(Vector *v)
+{
+	assert(v != nil);
+	if(v->p == nil)
+		return;
+	memset(v->p, 0, v->totsz);
+	v->firstempty = 0;
+	v->n = 0;
+}
+
+static void *
+growvec(Vector *v, int n)
+{
+	assert(v != nil);
+	if(n < v->bufsz)
+		return (uchar *)v->p + n * v->elsz;
+	v->p = erealloc(v->p, v->totsz + Nvecinc * v->elsz, v->totsz);
+	v->bufsz += Nvecinc;
+	v->totsz += Nvecinc * v->elsz;
+	return (uchar *)v->p + n * v->elsz;
+}
+
+void
+popsparsevec(Vector *v, int n)
+{
+	assert(v != nil && v->elsz > 0 && n >= 0 && n < v->n);
+	memset((uchar *)v->p + n * v->elsz, 0, v->elsz);
+	if(n < v->firstempty)
+		v->firstempty = n;
+}
+
+/* assumes that zeroed element means empty; could fill with
+ * magic values instead */
+void *
+pushsparsevec(Vector *v, void *e)
+{
+	int n;
+	uchar *p, *q;
+
+	assert(v != nil && v->elsz > 0);
+	n = v->firstempty;
+	p = growvec(v, n);
+	for(n++, q=p+v->elsz; n<v->n; n++, q+=v->elsz)
+		if(memcmp(p, q, v->elsz) == 0)
+			break;
+	v->firstempty = n;
+	memcpy(p, e, v->elsz);
+	v->n++;
+	return p;
+}
+
+void *
+pushvec(Vector *v, void *e)
+{
+	uchar *p;
+
+	assert(v != nil && v->elsz > 0);
+	p = growvec(v, v->n);
+	memcpy(p, e, v->elsz);
+	v->n++;
+	v->firstempty = v->n;
+	return p;
+}
+
+void *
+newvec(Vector *v, int nel, int elsz)
+{
+	assert(v != nil && elsz > 0);
+	v->elsz = elsz;
+	nel = nel + Nvecinc-1 & ~(Nvecinc-1);
+	v->bufsz = nel;
+	v->totsz = nel * elsz;
+	v->p = emalloc(v->totsz);
+	return v->p;
+}