Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
excit
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
argo
excit
Commits
a97d5c7c
Commit
a97d5c7c
authored
Jan 03, 2019
by
Nicolas Denoyelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
split files and add tleaf iterator
parent
4e08270a
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
2349 additions
and
1764 deletions
+2349
-1764
src/Makefile.am
src/Makefile.am
+1
-1
src/cons.c
src/cons.c
+326
-0
src/cons.h
src/cons.h
+34
-0
src/excit.c
src/excit.c
+230
-1677
src/excit.h
src/excit.h
+113
-86
src/hilbert2d.c
src/hilbert2d.c
+244
-0
src/hilbert2d.h
src/hilbert2d.h
+26
-0
src/prod.c
src/prod.c
+392
-0
src/prod.h
src/prod.h
+25
-0
src/range.c
src/range.c
+216
-0
src/range.h
src/range.h
+27
-0
src/repeat.c
src/repeat.c
+176
-0
src/repeat.h
src/repeat.h
+26
-0
src/slice.c
src/slice.c
+197
-0
src/slice.h
src/slice.h
+26
-0
src/tleaf.c
src/tleaf.c
+259
-0
src/tleaf.h
src/tleaf.h
+31
-0
No files found.
src/Makefile.am
View file @
a97d5c7c
...
...
@@ -2,6 +2,6 @@ AM_CFLAGS = -Wall -Werror -pedantic
lib_LTLIBRARIES
=
libexcit.la
libexcit_la_SOURCES
=
excit.c
excit.h
libexcit_la_SOURCES
=
excit.c
tleaf.c range.c slice.c repeat.c prod.c cons.c hilbert2d.c
include_HEADERS
=
excit.h
src/cons.c
0 → 100644
View file @
a97d5c7c
#include "cons.h"
#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; }
static
void
circular_fifo_add
(
struct
circular_fifo_s
*
fifo
,
ssize_t
elem
)
{
if
(
fifo
->
size
==
fifo
->
length
)
{
fifo
->
start
=
(
fifo
->
start
+
1
)
%
fifo
->
length
;
fifo
->
end
=
(
fifo
->
end
+
1
)
%
fifo
->
length
;
}
else
{
fifo
->
end
=
(
fifo
->
end
+
1
)
%
fifo
->
length
;
fifo
->
size
++
;
}
fifo
->
buffer
[
fifo
->
end
]
=
elem
;
}
static
void
circular_fifo_dump
(
const
struct
circular_fifo_s
*
fifo
,
ssize_t
*
vals
)
{
ssize_t
i
;
ssize_t
j
;
for
(
i
=
0
,
j
=
fifo
->
start
;
i
<
fifo
->
size
;
i
++
)
{
vals
[
i
]
=
fifo
->
buffer
[
j
];
j
=
(
j
+
1
)
%
fifo
->
length
;
}
}
struct
excit_func_table_s
excit_cons_func_table
=
{
cons_it_alloc
,
cons_it_free
,
cons_it_copy
,
cons_it_next
,
cons_it_peek
,
cons_it_size
,
cons_it_rewind
,
cons_it_split
,
cons_it_nth
,
cons_it_rank
,
cons_it_pos
};
int
cons_it_alloc
(
excit_t
data
)
{
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
it
->
it
=
NULL
;
it
->
n
=
0
;
it
->
fifo
.
length
=
0
;
it
->
fifo
.
start
=
0
;
it
->
fifo
.
end
=
-
1
;
it
->
fifo
.
size
=
0
;
it
->
fifo
.
buffer
=
NULL
;
return
EXCIT_SUCCESS
;
}
void
cons_it_free
(
excit_t
data
)
{
struct
cons_it_s
*
it
;
if
(
data
==
NULL
)
{
return
;
}
int
err
=
excit_get_data
(
data
,
(
void
**
)(
&
it
));
if
(
err
!=
EXCIT_SUCCESS
)
{
return
;
}
if
(
it
==
NULL
){
return
;
}
excit_free
(
it
->
it
);
free
(
it
->
fifo
.
buffer
);
}
int
cons_it_copy
(
excit_t
ddst
,
const
excit_t
dsrc
)
{
struct
cons_it_s
*
dst
;
EXCIT_DATA
(
ddst
,
dst
);
const
struct
cons_it_s
*
src
;
EXCIT_DATA
(
dsrc
,
src
);
excit_t
copy
=
excit_dup
(
src
->
it
);
if
(
!
copy
)
return
-
EXCIT_EINVAL
;
dst
->
it
=
copy
;
dst
->
n
=
src
->
n
;
dst
->
fifo
.
length
=
src
->
fifo
.
length
;
dst
->
fifo
.
start
=
src
->
fifo
.
start
;
dst
->
fifo
.
end
=
src
->
fifo
.
end
;
dst
->
fifo
.
size
=
src
->
fifo
.
size
;
dst
->
fifo
.
buffer
=
(
ssize_t
*
)
malloc
(
src
->
fifo
.
length
*
sizeof
(
ssize_t
));
if
(
!
dst
->
fifo
.
buffer
)
{
excit_free
(
copy
);
return
-
EXCIT_ENOMEM
;
}
for
(
int
i
=
0
;
i
<
dst
->
fifo
.
length
;
i
++
)
dst
->
fifo
.
buffer
[
i
]
=
src
->
fifo
.
buffer
[
i
];
return
EXCIT_SUCCESS
;
}
int
cons_it_size
(
const
excit_t
data
,
ssize_t
*
size
)
{
const
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
ssize_t
tmp_size
=
0
;
int
err
=
excit_size
(
it
->
it
,
&
tmp_size
);
if
(
err
)
return
err
;
*
size
=
tmp_size
-
(
it
->
n
-
1
);
return
EXCIT_SUCCESS
;
}
int
cons_it_split
(
const
excit_t
data
,
ssize_t
n
,
excit_t
*
results
)
{
ssize_t
size
;
int
err
=
cons_it_size
(
data
,
&
size
);
if
(
err
)
return
err
;
if
(
size
<
n
)
return
-
EXCIT_EDOM
;
if
(
!
results
)
return
EXCIT_SUCCESS
;
excit_t
range
=
excit_alloc
(
EXCIT_RANGE
);
if
(
!
range
)
return
-
EXCIT_ENOMEM
;
err
=
excit_range_init
(
range
,
0
,
size
-
1
,
1
);
if
(
err
)
goto
error1
;
err
=
excit_split
(
range
,
n
,
results
);
if
(
err
)
goto
error1
;
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
excit_t
tmp
,
tmp2
;
tmp
=
excit_dup
(
data
);
if
(
!
tmp
)
goto
error2
;
tmp2
=
results
[
i
];
results
[
i
]
=
excit_alloc
(
EXCIT_SLICE
);
if
(
!
results
[
i
])
{
excit_free
(
tmp2
);
goto
error2
;
}
err
=
excit_slice_init
(
results
[
i
],
tmp
,
tmp2
);
if
(
err
)
{
excit_free
(
tmp2
);
goto
error2
;
}
}
excit_free
(
range
);
return
EXCIT_SUCCESS
;
error2:
for
(;
i
>=
0
;
i
--
)
excit_free
(
results
[
i
]);
error1:
excit_free
(
range
);
return
err
;
}
int
cons_it_nth
(
const
excit_t
data
,
ssize_t
n
,
ssize_t
*
indexes
)
{
ssize_t
size
;
int
err
=
cons_it_size
(
data
,
&
size
);
if
(
err
)
return
err
;
if
(
n
<
0
||
n
>=
size
)
return
-
EXCIT_EDOM
;
const
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
int
dim
=
excit_get_dimension
(
it
->
it
);
if
(
indexes
)
{
for
(
int
i
=
0
;
i
<
it
->
n
;
i
++
)
{
err
=
excit_nth
(
it
->
it
,
n
+
i
,
indexes
+
dim
*
i
);
if
(
err
)
return
err
;
}
}
return
EXCIT_SUCCESS
;
}
int
cons_it_rank
(
const
excit_t
data
,
const
ssize_t
*
indexes
,
ssize_t
*
n
)
{
const
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
ssize_t
inner_n
,
inner_n_tmp
;
int
err
=
excit_rank
(
it
->
it
,
indexes
,
&
inner_n
);
if
(
err
)
return
err
;
int
dim
=
excit_get_dimension
(
it
->
it
);
for
(
int
i
=
1
;
i
<
it
->
n
;
i
++
)
{
err
=
excit_rank
(
it
->
it
,
indexes
+
dim
*
i
,
&
inner_n_tmp
);
if
(
err
)
return
err
;
if
(
inner_n_tmp
!=
inner_n
+
1
)
return
-
EXCIT_EINVAL
;
inner_n
=
inner_n_tmp
;
}
if
(
n
)
*
n
=
inner_n
-
(
it
->
n
-
1
);
return
EXCIT_SUCCESS
;
}
int
cons_it_pos
(
const
excit_t
data
,
ssize_t
*
n
)
{
ssize_t
inner_n
;
const
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
int
err
=
excit_pos
(
it
->
it
,
&
inner_n
);
if
(
err
)
return
err
;
if
(
n
)
*
n
=
inner_n
-
(
it
->
n
-
1
);
return
EXCIT_SUCCESS
;
}
int
cons_it_peek
(
const
excit_t
data
,
ssize_t
*
indexes
)
{
const
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
int
err
;
int
dim
=
excit_get_dimension
(
it
->
it
);
int
n
=
it
->
n
;
if
(
indexes
)
{
circular_fifo_dump
(
&
it
->
fifo
,
indexes
);
err
=
excit_peek
(
it
->
it
,
indexes
+
dim
*
(
n
-
1
));
}
else
err
=
excit_peek
(
it
->
it
,
NULL
);
if
(
err
)
return
err
;
return
EXCIT_SUCCESS
;
}
int
cons_it_next
(
excit_t
data
,
ssize_t
*
indexes
)
{
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
int
err
;
int
dim
=
excit_get_dimension
(
it
->
it
);
int
n
=
it
->
n
;
if
(
indexes
)
{
circular_fifo_dump
(
&
it
->
fifo
,
indexes
);
err
=
excit_next
(
it
->
it
,
indexes
+
dim
*
(
n
-
1
));
}
else
err
=
excit_next
(
it
->
it
,
NULL
);
if
(
err
)
return
err
;
if
(
indexes
)
for
(
int
i
=
dim
*
(
n
-
1
);
i
<
dim
*
n
;
i
++
)
circular_fifo_add
(
&
it
->
fifo
,
indexes
[
i
]);
return
EXCIT_SUCCESS
;
}
int
cons_it_rewind
(
excit_t
data
)
{
struct
cons_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
int
err
=
excit_rewind
(
it
->
it
);
if
(
err
)
return
err
;
it
->
fifo
.
start
=
0
;
it
->
fifo
.
end
=
-
1
;
it
->
fifo
.
size
=
0
;
for
(
int
i
=
0
;
i
<
it
->
n
-
1
;
i
++
)
{
int
err
;
err
=
excit_next
(
it
->
it
,
it
->
fifo
.
buffer
+
excit_get_dimension
(
it
->
it
)
*
i
);
if
(
err
)
return
err
;
it
->
fifo
.
size
+=
excit_get_dimension
(
it
->
it
);
it
->
fifo
.
end
+=
excit_get_dimension
(
it
->
it
);
}
return
EXCIT_SUCCESS
;
}
int
excit_cons_init
(
excit_t
it
,
excit_t
src
,
ssize_t
n
)
{
ssize_t
src_size
;
int
err
;
if
(
!
it
||
!
src
||
n
<=
0
)
return
-
EXCIT_EINVAL
;
err
=
excit_size
(
src
,
&
src_size
);
if
(
err
)
return
err
;
if
(
src_size
<
n
)
return
-
EXCIT_EINVAL
;
struct
cons_it_s
*
cons_it
;
EXCIT_DATA
(
it
,
cons_it
);
free
(
cons_it
->
fifo
.
buffer
);
excit_free
(
cons_it
->
it
);
excit_set_dimension
(
it
,
excit_get_dimension
(
src
)
*
n
);
cons_it
->
it
=
src
;
cons_it
->
n
=
n
;
cons_it
->
fifo
.
length
=
excit_get_dimension
(
src
)
*
(
n
-
1
);
cons_it
->
fifo
.
buffer
=
(
ssize_t
*
)
malloc
(
cons_it
->
fifo
.
length
*
sizeof
(
ssize_t
));
if
(
!
cons_it
->
fifo
.
buffer
)
return
-
EXCIT_ENOMEM
;
err
=
cons_it_rewind
(
it
);
if
(
err
)
{
free
(
cons_it
->
fifo
.
buffer
);
return
err
;
}
return
EXCIT_SUCCESS
;
}
src/cons.h
0 → 100644
View file @
a97d5c7c
#ifndef CONS_H
#define CONS_H
#include "excit.h"
struct
circular_fifo_s
{
ssize_t
length
;
ssize_t
start
;
ssize_t
end
;
ssize_t
size
;
ssize_t
*
buffer
;
};
struct
cons_it_s
{
excit_t
it
;
ssize_t
n
;
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
src/excit.c
View file @
a97d5c7c
This diff is collapsed.
Click to expand it.
src/excit.h
View file @
a97d5c7c
#ifndef EXCIT_H
#define EXCIT_H 1
#include <stdlib.h>
/*
* The different types of iterator supported. All iterators use the same
* integer type (ssize_t) for values.
*/
enum
excit_type_e
{
EXCIT_INVALID
,
/*!< Tag for invalid iterators */
EXCIT_RANGE
,
/*!< Iterator over a range of values */
EXCIT_CONS
,
/*!< Sliding window iterator */
EXCIT_REPEAT
,
/*!< Ierator that stutters a certain amount of times */
EXCIT_HILBERT2D
,
/*!< Hilbert space filing curve */
EXCIT_PRODUCT
,
/*!< Iterator over the catesian product of iterators */
EXCIT_SLICE
,
/*!< Iterator using another iterator to index a third */
EXCIT_USER
,
/*!< User-defined iterator */
EXCIT_TYPE_MAX
/*!< Guard */
EXCIT_INVALID
,
/*!< Tag for invalid iterators */
EXCIT_RANGE
,
/*!< Iterator over a range of values */
EXCIT_CONS
,
/*!< Sliding window iterator */
EXCIT_REPEAT
,
/*!< Ierator that stutters a certain amount of times */
EXCIT_HILBERT2D
,
/*!< Hilbert space filing curve */
EXCIT_PRODUCT
,
/*!< Iterator over the catesian product of iterators */
EXCIT_SLICE
,
/*!< Iterator using another iterator to index a third */
EXCIT_TLEAF
,
/*!< Iterator on leaves of a balanced tree */
EXCIT_USER
,
/*!< User-defined iterator */
EXCIT_TYPE_MAX
/*!< Guard */
};
/*
...
...
@@ -26,13 +29,13 @@ const char * excit_type_name(enum excit_type_e type);
* The different possible return codes of an excit function.
*/
enum
excit_error_e
{
EXCIT_SUCCESS
,
/*!< Sucess */
EXCIT_STOPIT
,
/*!< Iteration space is depleted */
EXCIT_ENOMEM
,
/*!< Out of memory */
EXCIT_EINVAL
,
/*!< Parameter has an invalid value */
EXCIT_EDOM
,
/*!< Parameter is out of possible domain */
EXCIT_ENOTSUP
,
/*!< Operation is not supported */
EXCIT_ERROR_MAX
/*!< Guard */
EXCIT_SUCCESS
,
/*!< Sucess */
EXCIT_STOPIT
,
/*!< Iteration space is depleted */
EXCIT_ENOMEM
,
/*!< Out of memory */
EXCIT_EINVAL
,
/*!< Parameter has an invalid value */
EXCIT_EDOM
,
/*!< Parameter is out of possible domain */
EXCIT_ENOTSUP
,
/*!< Operation is not supported */
EXCIT_ERROR_MAX
/*!< Guard */
};
/*
...
...
@@ -50,16 +53,23 @@ typedef struct excit_s *excit_t;
******************************************************************************/
/*
* Sets the dimension of a
user-defined
iterator.
* "it": a
user-defined
iterator.
* Sets the dimension of a
(user-defined)
iterator.
* "it": a
(user-defined)
iterator.
* "dimension": the new dimension of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
excit_set_dimension
(
excit_t
it
,
ssize_t
dimension
);
/*
* Gets the inner data pointer of a user-defined iterator.
* "it": a user-defined iterator.
* Gets the dimension of an iterator.
* "it": the iterator.
* Returns the dimension or -1 if it is NULL.
*/
ssize_t
excit_get_dimension
(
excit_t
it
);
/*
* Gets the inner data pointer of a (user-defined) iterator.
* "it": a (user-defined) iterator.
* "data": a pointer to a pointer variable where the result will be written.
* Returns EXCIT_SUCCESS or an error code.
*/
...
...
@@ -72,71 +82,71 @@ int excit_get_data(excit_t it, void **data);
* -EXCIT_ENOTSUP.
*/
struct
excit_func_table_s
{
/*
* This function is called during excit_alloc, after the memory
* allocation, the inner data pointer will already be set.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
alloc
)(
excit_t
it
);
/*
* This function is called during excit_free. After this function is
* called the iterator and the data will be freed.
*/
void
(
*
free
)(
excit_t
it
);
/*
* This funciton is called during excit_dup. It is responsible for
* duplicating the content of the inner data between src_it and dst_it.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
copy
)(
excit_t
dst_it
,
const
excit_t
src_it
);
/*
* This function is responsible for implementing the next functionality
* of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/
int
(
*
next
)(
excit_t
it
,
ssize_t
*
indexes
);
/*
* This function is responsible for implementing the peek functionality
* of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/
int
(
*
peek
)(
const
excit_t
it
,
ssize_t
*
indexes
);
/*
* This function is responsible for implementing the size functionality
* of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
size
)(
const
excit_t
it
,
ssize_t
*
size
);
/*
* This function is responsible for implementing the rewind
* functionality of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
rewind
)(
excit_t
it
);
/*
* This function is responsible for implementing the split
* functionality of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
split
)(
const
excit_t
it
,
ssize_t
n
,
excit_t
*
results
);
/*
* This function is responsible for implementing the nth functionality
* of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
nth
)(
const
excit_t
it
,
ssize_t
n
,
ssize_t
*
indexes
);
/*
* This function is responsible for implementing the rank functionality
* of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
rank
)(
const
excit_t
it
,
const
ssize_t
*
indexes
,
ssize_t
*
n
);
/*
* This function is responsible for implementing the pos functionality
* of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/
int
(
*
pos
)(
const
excit_t
it
,
ssize_t
*
n
);
/*
* This function is called during excit_alloc, after the memory
* allocation, the inner data pointer will already be set.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
alloc
)(
excit_t
it
);
/*
* This function is called during excit_free. After this function is
* called the iterator and the data will be freed.
*/
void
(
*
free
)(
excit_t
it
);
/*
* This funciton is called during excit_dup. It is responsible for
* duplicating the content of the inner data between src_it and dst_it.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
copy
)(
excit_t
dst_it
,
const
excit_t
src_it
);
/*
* This function is responsible for implementing the next functionality
* of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/
int
(
*
next
)(
excit_t
it
,
ssize_t
*
indexes
);
/*
* This function is responsible for implementing the peek functionality
* of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/
int
(
*
peek
)(
const
excit_t
it
,
ssize_t
*
indexes
);
/*
* This function is responsible for implementing the size functionality
* of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
size
)(
const
excit_t
it
,
ssize_t
*
size
);
/*
* This function is responsible for implementing the rewind
* functionality of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
rewind
)(
excit_t
it
);
/*
* This function is responsible for implementing the split
* functionality of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
split
)(
const
excit_t
it
,
ssize_t
n
,
excit_t
*
results
);
/*
* This function is responsible for implementing the nth functionality
* of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
nth
)(
const
excit_t
it
,
ssize_t
n
,
ssize_t
*
indexes
);
/*
* This function is responsible for implementing the rank functionality
* of the iterator.
* Returns EXCIT_SUCCESS or an error code.
*/
int
(
*
rank
)(
const
excit_t
it
,
const
ssize_t
*
indexes
,
ssize_t
*
n
);
/*
* This function is responsible for implementing the pos functionality
* of the iterator.
* Returns EXCIT_SUCCESS, EXCIT_STOPIT or an error code.
*/
int
(
*
pos
)(
const
excit_t
it
,
ssize_t
*
n
);
};
/*
...
...
@@ -245,7 +255,7 @@ int excit_size(const excit_t it, ssize_t *size);
* "it": an iterator.
* "n": number of iterators desired.
* "results": an array of at least n excit_t, or NULL in which case no iterator
* is created.
/
* is created.
* Returns EXCIT_SUCCESS, -EXCIT_EDOM if the source iterator is too small to be
* subdivised in the wanted number or an error code.
*/
...
...
@@ -383,4 +393,21 @@ int excit_product_split_dim(const excit_t it, ssize_t dim, ssize_t n,
* Returns EXCIT_SUCCESS or an error code.
*/
int
excit_slice_init
(
excit_t
it
,
excit_t
src
,
excit_t
indexer
);
enum
tleaf_it_policy_e
{
ROUND_ROBIN
,
/* Iterate on tree leaves in a round-robin fashion */
SCATTER
/* Iterate on tree leaves such spreading as much as possible */
};
/*
* Initialize a tleaf iterator by giving its depth, levels arity and iteration policy.
* "it": a tleaf iterator
* "depth": the total number of levels of the tree, including leaves
* "arity": For each level, the number of children attached to a node. Leaves have no children, hence last level arity must be 0.
* "iter_policy": A policy for iteration on leaves.
*/
int
excit_tleaf_init
(
excit_t
it
,
const
ssize_t
depth
,
const
ssize_t
*
arity
,
const
enum
tleaf_it_policy_e
iter_policy
);
#endif
src/hilbert2d.c
0 → 100644
View file @
a97d5c7c
#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
;
}
}
//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
;
}
//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
;
}
}
/* End helper functions */
int
hilbert2d_it_alloc
(
excit_t
data
)
{
struct
hilbert2d_it_s
*
it
;
EXCIT_DATA
(
data
,
it
);
it
->
n
=
0
;
it
->
range_it
=
NULL
;
return
EXCIT_SUCCESS
;
}
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
;
}
excit_free
(
it
->
range_it
);
}
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
;
}