shithub: asif

ref: 2603b42d0f2caa502411848f7c4062e290dde2dd
dir: /vec.c/

View raw version
#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;
}