ref: 13a7d1ca0b2e2fe5fae116d92e475ff0bfad6a9a
dir: /vec.c/
#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;
}