Commit b8a35329 authored by Nicolas Denoyelle's avatar Nicolas Denoyelle

Merge branch 'master' into tleaf

parents a56b4120 2f228ce7
......@@ -2,6 +2,6 @@ AM_CFLAGS = -Wall -Werror -pedantic
lib_LTLIBRARIES = libexcit.la
libexcit_la_SOURCES = excit.c tleaf.c range.c slice.c repeat.c prod.c cons.c hilbert2d.c
libexcit_la_SOURCES = excit.c slice.c prod.c cons.c repeat.c hilbert2d.c range.c
include_HEADERS = excit.h
This diff is collapsed.
#ifndef CONS_H
#define CONS_H
#ifndef EXCIT_CONS_H
#define EXCIT_CONS_H
#include "excit.h"
#include "dev/excit.h"
struct circular_fifo_s {
ssize_t length;
ssize_t start;
ssize_t end;
ssize_t size;
ssize_t *buffer;
ssize_t length;
ssize_t start;
ssize_t end;
ssize_t size;
ssize_t *buffer;
};
struct cons_it_s {
......@@ -17,18 +18,6 @@ struct cons_it_s {
struct circular_fifo_s fifo;
};
int cons_it_alloc(excit_t data);
void cons_it_free(excit_t data);
int cons_it_copy(excit_t ddst, const excit_t dsrc);
int cons_it_size(const excit_t data, ssize_t *size);
int cons_it_split(const excit_t data, ssize_t n, excit_t *results);
int cons_it_nth(const excit_t data, ssize_t n, ssize_t *indexes);
int cons_it_rank(const excit_t data, const ssize_t *indexes, ssize_t *n);
int cons_it_pos(const excit_t data, ssize_t *n);
int cons_it_peek(const excit_t data, ssize_t *indexes);
int cons_it_next(excit_t data, ssize_t *indexes);
int cons_it_rewind(excit_t data);
extern struct excit_func_table_s excit_cons_func_table;
#endif
#endif //EXCIT_CONS_H
#ifndef EXCIT_DEV_H
#define EXCIT_DEV_H
#include "../excit.h"
struct excit_s {
struct excit_func_table_s *func_table;
ssize_t dimension;
enum excit_type_e type;
void *data;
};
#endif
#include <stdlib.h>
#include "excit.h"
#include "dev/excit.h"
#include "slice.h"
#include "range.h"
#include "repeat.h"
#include "prod.h"
#include "cons.h"
#include "repeat.h"
#include "hilbert2d.h"
#include "tleaf.h"
#include "range.h"
#define CASE(val) case val: return #val; break;
#define CASE(val) case val: return #val; break
const char * excit_type_name(enum excit_type_e type)
const char *excit_type_name(enum excit_type_e type)
{
switch (type) {
CASE(EXCIT_RANGE)
CASE(EXCIT_CONS)
CASE(EXCIT_REPEAT)
CASE(EXCIT_HILBERT2D)
CASE(EXCIT_PRODUCT)
CASE(EXCIT_SLICE)
CASE(EXCIT_TLEAF)
CASE(EXCIT_USER)
CASE(EXCIT_TYPE_MAX)
default:
return NULL;
}
switch (type) {
CASE(EXCIT_RANGE);
CASE(EXCIT_CONS);
CASE(EXCIT_REPEAT);
CASE(EXCIT_HILBERT2D);
CASE(EXCIT_PRODUCT);
CASE(EXCIT_SLICE);
CASE(EXCIT_USER);
CASE(EXCIT_TYPE_MAX);
default:
return NULL;
}
}
const char * excit_error_name(enum excit_error_e err)
const char *excit_error_name(enum excit_error_e err)
{
switch (err) {
CASE(EXCIT_SUCCESS)
CASE(EXCIT_STOPIT)
CASE(EXCIT_ENOMEM)
CASE(EXCIT_EINVAL)
CASE(EXCIT_EDOM)
CASE(EXCIT_ENOTSUP)
CASE(EXCIT_ERROR_MAX)
default:
return NULL;
}
switch (err) {
CASE(EXCIT_SUCCESS);
CASE(EXCIT_STOPIT);
CASE(EXCIT_ENOMEM);
CASE(EXCIT_EINVAL);
CASE(EXCIT_EDOM);
CASE(EXCIT_ENOTSUP);
CASE(EXCIT_ERROR_MAX);
default:
return NULL;
}
}
#undef CASE
struct excit_s {
struct excit_func_table_s *func_table;
ssize_t dimension;
enum excit_type_e type;
void *data;
};
int excit_set_dimension(excit_t it, ssize_t dimension)
{
if (!it)
......@@ -61,54 +53,46 @@ int excit_set_dimension(excit_t it, ssize_t dimension)
return EXCIT_SUCCESS;
}
ssize_t excit_get_dimension(excit_t it)
{
if(it)
{
return it->dimension;
} else {
return -1;
}
}
int excit_get_data(excit_t it, void **data)
{
if (!it)
return -EXCIT_EINVAL;
/* if (it->type != EXCIT_USER) */
/* return -EXCIT_ENOTSUP; */ // WHY !!!
*data = it->data;
return EXCIT_SUCCESS;
if (!it)
return -EXCIT_EINVAL;
if (it->type != EXCIT_USER)
return -EXCIT_ENOTSUP;
*data = it->data;
return EXCIT_SUCCESS;
}
int excit_set_func_table(excit_t it, struct excit_func_table_s *func_table)
{
if (!it)
return -EXCIT_EINVAL;
it->func_table = func_table;
return EXCIT_SUCCESS;
if (!it)
return -EXCIT_EINVAL;
it->func_table = func_table;
return EXCIT_SUCCESS;
}
int excit_get_func_table(excit_t it, struct excit_func_table_s **func_table)
{
if (!it)
return -EXCIT_EINVAL;
*func_table = it->func_table;
return EXCIT_SUCCESS;
if (!it)
return -EXCIT_EINVAL;
*func_table = it->func_table;
return EXCIT_SUCCESS;
}
#define ALLOC_EXCIT(op) { \
it = malloc(sizeof(struct excit_s) + sizeof(struct op## _it_s)); \
if (!it) \
return NULL; \
it->data = (void *)((char *)it + sizeof(struct excit_s)); \
if (!excit_ ##op## _func_table.alloc) \
goto error; \
it->func_table = &excit_ ##op## _func_table; \
it->dimension = 0; \
if (excit_ ##op## _func_table.alloc(it)) \
goto error; \
}
/*--------------------------------------------------------------------*/
#define ALLOC_EXCIT(op) { \
it = malloc(sizeof(struct excit_s) + sizeof(struct op## _it_s)); \
if (!it) \
return NULL; \
it->data = (void *)((char *)it + sizeof(struct excit_s)); \
if (!excit_ ##op## _func_table.alloc) \
goto error; \
it->func_table = &excit_ ##op## _func_table; \
it->dimension = 0; \
if (excit_ ##op## _func_table.alloc(it)) \
goto error; \
}
excit_t excit_alloc(enum excit_type_e type)
{
......@@ -172,18 +156,17 @@ error:
excit_t excit_dup(excit_t it)
{
excit_t result = NULL;
if (!it || !it->data || !it->func_table
|| !it->func_table->copy)
return NULL;
result = excit_alloc(it->type);
if (!result)
return NULL;
result->dimension = it->dimension;
if (it->func_table->copy(result, it))
goto error;
return result;
excit_t result = NULL;
if (!it || !it->data || !it->func_table || !it->func_table->copy)
return NULL;
result = excit_alloc(it->type);
if (!result)
return NULL;
result->dimension = it->dimension;
if (it->func_table->copy(result, it))
goto error;
return result;
error:
excit_free(result);
return NULL;
......
This diff is collapsed.
#include "dev/excit.h"
#include "hilbert2d.h"
struct excit_func_table_s excit_hilbert2d_func_table = {
hilbert2d_it_alloc,
hilbert2d_it_free,
hilbert2d_it_copy,
hilbert2d_it_next,
hilbert2d_it_peek,
hilbert2d_it_size,
hilbert2d_it_rewind,
hilbert2d_it_split,
hilbert2d_it_nth,
hilbert2d_it_rank,
hilbert2d_it_pos
};
#define EXCIT_DATA(data, it) \
if(data == NULL) { return EXCIT_EINVAL; } \
do{ \
int err = excit_get_data(data, (void**)(&it)); \
if(err != EXCIT_SUCCESS) { return err; } \
} while(0); \
if(it == NULL){ return EXCIT_EINVAL; }
/* Helper functions from: https://en.wikipedia.org/wiki/Hilbert_curve */
//rotate/flip a quadrant appropriately
static void rot(ssize_t n, ssize_t *x, ssize_t *y, ssize_t rx, ssize_t ry)
{
if (ry == 0) {
if (rx == 1) {
*x = n - 1 - *x;
*y = n - 1 - *y;
}
//Swap x and y
ssize_t t = *x;
*x = *y;
*y = t;
}
if (ry == 0) {
if (rx == 1) {
*x = n - 1 - *x;
*y = n - 1 - *y;
}
//Swap x and y
ssize_t t = *x;
*x = *y;
*y = t;
}
}
//convert (x,y) to d
static ssize_t xy2d(ssize_t n, ssize_t x, ssize_t y)
{
ssize_t rx, ry, s, d = 0;
for (s = n / 2; s > 0; s /= 2) {
rx = (x & s) > 0;
ry = (y & s) > 0;
d += s * s * ((3 * rx) ^ ry);
rot(s, &x, &y, rx, ry);
}
return d;
ssize_t rx, ry, s, d = 0;
for (s = n / 2; s > 0; s /= 2) {
rx = (x & s) > 0;
ry = (y & s) > 0;
d += s * s * ((3 * rx) ^ ry);
rot(s, &x, &y, rx, ry);
}
return d;
}
//convert d to (x,y)
static void d2xy(ssize_t n, ssize_t d, ssize_t *x, ssize_t *y)
{
ssize_t rx, ry, s, t = d;
*x = *y = 0;
for (s = 1; s < n; s *= 2) {
rx = 1 & (t / 2);
ry = 1 & (t ^ rx);
rot(s, x, y, rx, ry);
*x += s * rx;
*y += s * ry;
t /= 4;
}
ssize_t rx, ry, s, t = d;
*x = *y = 0;
for (s = 1; s < n; s *= 2) {
rx = 1 & (t / 2);
ry = 1 & (t ^ rx);
rot(s, x, y, rx, ry);
*x += s * rx;
*y += s * ry;
t /= 4;
}
}
/* End helper functions */
int hilbert2d_it_alloc(excit_t data)
static int hilbert2d_it_alloc(excit_t data)
{
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
it->n = 0;
it->range_it = NULL;
return EXCIT_SUCCESS;
it->n = 0;
it->range_it = NULL;
return EXCIT_SUCCESS;
}
void hilbert2d_it_free(excit_t data)
static void hilbert2d_it_free(excit_t data)
{
struct hilbert2d_it_s *it;
if(data == NULL) { return ; }
int err = excit_get_data(data, (void**)(&it));
if(err != EXCIT_SUCCESS) { return; }
if(it == NULL){ return; }
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
excit_free(it->range_it);
excit_free(it->range_it);
}
int hilbert2d_it_copy(excit_t ddst, const excit_t dsrc)
static int hilbert2d_it_copy(excit_t ddst, const excit_t dsrc)
{
struct hilbert2d_it_s *dst;
EXCIT_DATA(ddst, dst);
const struct hilbert2d_it_s *src;
EXCIT_DATA(dsrc, src);
excit_t copy = excit_dup(src->range_it);
if (!copy)
return -EXCIT_EINVAL;
dst->range_it = copy;
dst->n = src->n;
return EXCIT_SUCCESS;
struct hilbert2d_it_s *dst = (struct hilbert2d_it_s *)ddst->data;
const struct hilbert2d_it_s *src =
(const struct hilbert2d_it_s *)dsrc->data;
excit_t copy = excit_dup(src->range_it);
if (!copy)
return -EXCIT_EINVAL;
dst->range_it = copy;
dst->n = src->n;
return EXCIT_SUCCESS;
}
int hilbert2d_it_rewind(excit_t data)
static int hilbert2d_it_rewind(excit_t data)
{
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
return excit_rewind(it->range_it);
return excit_rewind(it->range_it);
}
int hilbert2d_it_peek(const excit_t data, ssize_t *val)
static int hilbert2d_it_peek(const excit_t data, ssize_t *val)
{
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
ssize_t d;
int err;
err = excit_peek(it->range_it, &d);
if (err)
return err;
if (val)
d2xy(it->n, d, val, val + 1);
return EXCIT_SUCCESS;
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
ssize_t d;
int err;
err = excit_peek(it->range_it, &d);
if (err)
return err;
if (val)
d2xy(it->n, d, val, val + 1);
return EXCIT_SUCCESS;
}
int hilbert2d_it_next(excit_t data, ssize_t *val)
static int hilbert2d_it_next(excit_t data, ssize_t *val)
{
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
ssize_t d;
int err = excit_next(it->range_it, &d);
if (err)
return err;
if (val)
d2xy(it->n, d, val, val + 1);
return EXCIT_SUCCESS;
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
ssize_t d;
int err = excit_next(it->range_it, &d);
if (err)
return err;
if (val)
d2xy(it->n, d, val, val + 1);
return EXCIT_SUCCESS;
}
int hilbert2d_it_size(const excit_t data, ssize_t *size)
static int hilbert2d_it_size(const excit_t data, ssize_t *size)
{
const struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
return excit_size(it->range_it, size);
const struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
return excit_size(it->range_it, size);
}
int hilbert2d_it_nth(const excit_t data, ssize_t n, ssize_t *val)
static int hilbert2d_it_nth(const excit_t data, ssize_t n, ssize_t *val)
{
ssize_t d;
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
int err = excit_nth(it->range_it, n, &d);
if (err)
return err;
if (val)
d2xy(it->n, d, val, val + 1);
return EXCIT_SUCCESS;
ssize_t d;
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
int err = excit_nth(it->range_it, n, &d);
if (err)
return err;
if (val)
d2xy(it->n, d, val, val + 1);
return EXCIT_SUCCESS;
}
int hilbert2d_it_rank(const excit_t data, const ssize_t *indexes,
ssize_t *n)
static int hilbert2d_it_rank(const excit_t data, const ssize_t *indexes,
ssize_t *n)
{
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
if (indexes[0] < 0 || indexes[0] >= it->n || indexes[1] < 0
|| indexes[1] >= it->n)
return -EXCIT_EINVAL;
ssize_t d = xy2d(it->n, indexes[0], indexes[1]);
if (indexes[0] < 0 || indexes[0] >= it->n || indexes[1] < 0
|| indexes[1] >= it->n)
return -EXCIT_EINVAL;
ssize_t d = xy2d(it->n, indexes[0], indexes[1]);
return excit_rank(it->range_it, &d, n);
return excit_rank(it->range_it, &d, n);
}
int hilbert2d_it_pos(const excit_t data, ssize_t *n)
static int hilbert2d_it_pos(const excit_t data, ssize_t *n)
{
struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
return excit_pos(it->range_it, n);
return excit_pos(it->range_it, n);
}
int hilbert2d_it_split(const excit_t data, ssize_t n, excit_t *results)
static int hilbert2d_it_split(const excit_t data, ssize_t n, excit_t *results)
{
const struct hilbert2d_it_s *it;
EXCIT_DATA(data, it);
int err = excit_split(it->range_it, n, results);
if (err)
return err;
if (!results)
return EXCIT_SUCCESS;
for (int i = 0; i < n; i++) {
excit_t tmp;
tmp = results[i];
results[i] = excit_alloc(EXCIT_HILBERT2D);
if (!results[i]) {
excit_free(tmp);
err = -EXCIT_ENOMEM;
goto error;
}
excit_set_dimension(results[i], 2);
struct hilbert2d_it_s *res_it;
EXCIT_DATA(results[i], res_it);
res_it->n = it->n;
res_it->range_it = tmp;
}
return EXCIT_SUCCESS;
const struct hilbert2d_it_s *it = (struct hilbert2d_it_s *)data->data;
int err = excit_split(it->range_it, n, results);
if (err)
return err;
if (!results)
return EXCIT_SUCCESS;
for (int i = 0; i < n; i++) {
excit_t tmp;
tmp = results[i];
results[i] = excit_alloc(EXCIT_HILBERT2D);
if (!results[i]) {
excit_free(tmp);
err = -EXCIT_ENOMEM;
goto error;
}
results[i]->dimension = 2;
struct hilbert2d_it_s *res_it =
(struct hilbert2d_it_s *)results[i]->data;
res_it->n = it->n;
res_it->range_it = tmp;
}
return EXCIT_SUCCESS;
error:
for (int i = 0; i < n; i++)
excit_free(results[i]);
return err;
for (int i = 0; i < n; i++)
excit_free(results[i]);
return err;
}
int excit_hilbert2d_init(excit_t it, ssize_t order)
{
struct hilbert2d_it_s *hilbert2d_it;
if (!it || order <= 0)
return -EXCIT_EINVAL;
excit_set_dimension(it, 2);
EXCIT_DATA(it, hilbert2d_it);
hilbert2d_it->range_it = excit_alloc(EXCIT_RANGE);
if (!hilbert2d_it->range_it)
return -EXCIT_ENOMEM;
int n = 1 << order;
int err = excit_range_init(hilbert2d_it->range_it, 0, n * n - 1, 1);
if (err)
return err;
hilbert2d_it->n = n;
return EXCIT_SUCCESS;
struct hilbert2d_it_s *hilbert2d_it;
if (!it || it->type != EXCIT_HILBERT2D || order <= 0)
return -EXCIT_EINVAL;
it->dimension = 2;
hilbert2d_it = (struct hilbert2d_it_s *)it->data;
hilbert2d_it->range_it = excit_alloc(EXCIT_RANGE);
if (!hilbert2d_it->range_it)
return -EXCIT_ENOMEM;
int n = 1 << order;
int err = excit_range_init(hilbert2d_it->range_it, 0, n * n - 1, 1);
if (err)
return err;
hilbert2d_it->n = n;
return EXCIT_SUCCESS;
}
struct excit_func_table_s excit_hilbert2d_func_table = {
hilbert2d_it_alloc,
hilbert2d_it_free,
hilbert2d_it_copy,
hilbert2d_it_next,
hilbert2d_it_peek,
hilbert2d_it_size,
hilbert2d_it_rewind,
hilbert2d_it_split,
hilbert2d_it_nth,
hilbert2d_it_rank,
hilbert2d_it_pos
};
#ifndef HILBERT2D_H
#define HILBERT2D_H
#ifndef EXCIT_HILBERT2D_H
#define EXCIT_HILBERT2D_H
#include "excit.h"
struct hilbert2d_it_s {
ssize_t n;
excit_t range_it;
ssize_t n;
excit_t range_it;
};
int hilbert2d_it_alloc(excit_t data);
void hilbert2d_it_free(excit_t data);
int hilbert2d_it_copy(excit_t ddst, const excit_t dsrc);
int hilbert2d_it_rewind(excit_t data);
int hilbert2d_it_peek(const excit_t data, ssize_t *val);
int hilbert2d_it_next(excit_t data, ssize_t *val);
int hilbert2d_it_size(const excit_t data, ssize_t *size);
int hilbert2d_it_nth(const excit_t data, ssize_t n, ssize_t *val);
int hilbert2d_it_rank(const excit_t data, const ssize_t *indexes, ssize_t *n);
int hilbert2d_it_pos(const excit_t data, ssize_t *n);
int hilbert2d_it_split(const excit_t data, ssize_t n, excit_t *results);
extern struct excit_func_table_s excit_hilbert2d_func_table;
#endif
#endif //EXCIT_HILBERT2D_H
This diff is collapsed.
#ifndef PROD_H
#define PROD_H
#ifndef EXCIT_PROD_H
#define EXCIT_PROD_H
#include "excit.h"
#include "dev/excit.h"
struct prod_it_s {
ssize_t count;
excit_t *its;
};
int prod_it_alloc(excit_t data);
void prod_it_free(excit_t data);
int prod_it_copy(excit_t dst, const excit_t src);
int prod_it_rewind(excit_t data);
int prod_it_size(const excit_t data, ssize_t *size);
int prod_it_nth(const excit_t data, ssize_t n, ssize_t *indexes);
int prod_it_rank(const excit_t data, const ssize_t *indexes, ssize_t *n);
int prod_it_pos(const excit_t data, ssize_t *n);
int prod_it_peek(const excit_t data, ssize_t *indexes);
int prod_it_next(excit_t data, ssize_t *indexes);
int prod_it_split(const excit_t data, ssize_t n, excit_t *results);
extern struct excit_func_table_s excit_prod_func_table;
struct excit_func_table_s excit_prod_func_table;
#endif
#endif //EXCIT_PROD_H