improve
This commit is contained in:
parent
ecf1916d78
commit
06209930f9
13 changed files with 573 additions and 241 deletions
270
src/lib/xvec.c
Normal file
270
src/lib/xvec.c
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "xvec.h"
|
||||
|
||||
int xvec_init(xvec_t* v, int count, int elsize)
|
||||
{
|
||||
if ((v == NULL) || (count <= 0) || (elsize <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
v->data = (void*)calloc(count, elsize);
|
||||
if (v->data == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
v->count = count;
|
||||
v->elsize = elsize;
|
||||
|
||||
return v->count;
|
||||
}
|
||||
|
||||
void xvec_fini(xvec_t* v)
|
||||
{
|
||||
if (v == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
FREEUP(v->data);
|
||||
memset(v, 0x0, sizeof(*v));
|
||||
}
|
||||
|
||||
int xvec_zero(xvec_t* v)
|
||||
{
|
||||
if (v == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (v->data == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(v->data, 0x0, v->count * v->elsize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xvec_resize(xvec_t* v, int new_size)
|
||||
{
|
||||
void* p = NULL;
|
||||
|
||||
if (v == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (new_size <= v->count) {
|
||||
/* do thing for shrink now */
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = (void*)realloc(v->data, new_size * v->elsize);
|
||||
if (p == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
v->data = p;
|
||||
/* zero fill the extended space */
|
||||
memset(((char*)p) + v->count * v->elsize, 0x0,
|
||||
(new_size - v->count) * v->elsize);
|
||||
v->count = new_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define X_OP(op) X_OP_##op
|
||||
#define X_OP_add +=
|
||||
#define X_OP_sub -=
|
||||
|
||||
#define DEFINE_VEC_OP(op, typ) \
|
||||
static inline int vec_##typ##_##op(typ* v1, typ* v2, int count) \
|
||||
{ \
|
||||
int i; \
|
||||
for (i = 0; i < count; i++) { \
|
||||
v1[i] X_OP(op) v2[i]; \
|
||||
} \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
DEFINE_VEC_OP(add, int)
|
||||
DEFINE_VEC_OP(sub, int)
|
||||
DEFINE_VEC_OP(add, float)
|
||||
DEFINE_VEC_OP(sub, float)
|
||||
|
||||
int xvec_op(xvec_t* v1, xvec_t* v2, xvec_op_t op)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if ((v1 == NULL) || (v2 == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (v1->elsize != v2->elsize) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case XVEC_ADD_INT:
|
||||
case XVEC_SUB_INT:
|
||||
if (v1->elsize != sizeof(int)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case XVEC_ADD_FLOAT:
|
||||
case XVEC_SUB_FLOAT:
|
||||
if (v1->elsize != sizeof(float)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (v1->count < v2->count) {
|
||||
rc = xvec_resize(v1, v2->count);
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case XVEC_ADD_INT:
|
||||
rc = vec_int_add((int*)v1->data, (int*)v2->data, v2->count);
|
||||
break;
|
||||
case XVEC_SUB_INT:
|
||||
rc = vec_int_sub((int*)v1->data, (int*)v2->data, v2->count);
|
||||
break;
|
||||
case XVEC_ADD_FLOAT:
|
||||
rc = vec_float_add((float*)v1->data, (float*)v2->data, v2->count);
|
||||
break;
|
||||
case XVEC_SUB_FLOAT:
|
||||
rc = vec_float_sub((float*)v1->data, (float*)v2->data, v2->count);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int xvec_dup(xvec_t** dst, xvec_t* src)
|
||||
{
|
||||
xvec_t* v = NULL;
|
||||
|
||||
v = (xvec_t*)calloc(1, sizeof(*v));
|
||||
*dst = v;
|
||||
|
||||
if (v == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
v->data = (void*)calloc(src->count, src->elsize);
|
||||
if (v->data == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(v->data, src->data, src->elsize * src->count);
|
||||
v->elsize = src->elsize;
|
||||
v->count = src->count;
|
||||
|
||||
return v->count;
|
||||
}
|
||||
|
||||
int xvec_put(xvec_t* v, int idx, void* data)
|
||||
{
|
||||
int rc;
|
||||
char* p;
|
||||
|
||||
if ((v == NULL) || (idx < 0) || (data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = xvec_resize(v, idx + 1);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
p = (char*)v->data;
|
||||
memcpy(p + v->elsize * idx, data, v->elsize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xvec_get(xvec_t* v, int idx, void* data)
|
||||
{
|
||||
char* p = NULL;
|
||||
|
||||
if ((v == NULL) || (idx < 0) || (data == NULL)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (idx >= v->count) {
|
||||
memset(data, 0x0, v->elsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = (char*)v->data;
|
||||
memcpy(data, p + v->elsize * idx, v->elsize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xvec_idval_init(xvec_idval_t* v, int initsize)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((v == NULL) || (initsize <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(v, 0x0, sizeof(*v));
|
||||
rc = xvec_init(&(v->idxs), initsize, sizeof(int));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = xvec_init(&(v->vals), initsize, sizeof(float));
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
v->count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xvec_idval_fini(xvec_idval_t* v)
|
||||
{
|
||||
if (v == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
xvec_fini(&(v->idxs));
|
||||
xvec_fini(&(v->vals));
|
||||
|
||||
memset(v, 0x0, sizeof(*v));
|
||||
return;
|
||||
}
|
||||
|
||||
int xvec_idval_store(xvec_idval_t* v, int idx, float val)
|
||||
{
|
||||
int rc;
|
||||
int pos;
|
||||
|
||||
if ((v == NULL) || (idx < 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pos = v->count;
|
||||
rc = xvec_put(&(v->idxs), pos, &idx);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = xvec_put(&(v->vals), pos, &val);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
v->count = pos + 1;
|
||||
|
||||
return v->count;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue