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
efb65eea
Commit
efb65eea
authored
Jan 24, 2019
by
Nicolas Denoyelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add index iterator
parent
a6c0a842
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
369 additions
and
2 deletions
+369
-2
src/Makefile.am
src/Makefile.am
+1
-1
src/excit.c
src/excit.c
+5
-0
src/excit.h
src/excit.h
+10
-0
src/index.c
src/index.c
+241
-0
src/index.h
src/index.h
+19
-0
tests/Makefile.am
tests/Makefile.am
+2
-1
tests/excit_index.c
tests/excit_index.c
+91
-0
No files found.
src/Makefile.am
View file @
efb65eea
...
...
@@ -2,6 +2,6 @@ AM_CFLAGS = -Wall -Werror -pedantic
lib_LTLIBRARIES
=
libexcit.la
libexcit_la_SOURCES
=
excit.c composition.c prod.c cons.c repeat.c hilbert2d.c range.c tleaf.c
libexcit_la_SOURCES
=
excit.c composition.c prod.c cons.c repeat.c hilbert2d.c range.c
index.c
tleaf.c
include_HEADERS
=
excit.h
src/excit.c
View file @
efb65eea
...
...
@@ -7,6 +7,7 @@
#include "repeat.h"
#include "hilbert2d.h"
#include "range.h"
#include "index.h"
#include "tleaf.h"
#define CASE(val) case val: return #val; break
...
...
@@ -14,6 +15,7 @@
const
char
*
excit_type_name
(
enum
excit_type_e
type
)
{
switch
(
type
)
{
CASE
(
EXCIT_INDEX
);
CASE
(
EXCIT_RANGE
);
CASE
(
EXCIT_CONS
);
CASE
(
EXCIT_REPEAT
);
...
...
@@ -100,6 +102,9 @@ excit_t excit_alloc(enum excit_type_e type)
excit_t
it
=
NULL
;
switch
(
type
)
{
case
EXCIT_INDEX
:
ALLOC_EXCIT
(
index
);
break
;
case
EXCIT_RANGE
:
ALLOC_EXCIT
(
range
);
break
;
...
...
src/excit.h
View file @
efb65eea
...
...
@@ -31,6 +31,11 @@
enum
excit_type_e
{
/*!< Tag for invalid iterators */
EXCIT_INVALID
,
/*!<
* Iterator over an array of indexes.
* If indexes are uniques, the iterator is made inversible (see excit_rank()).
*/
EXCIT_INDEX
,
/*!<
* Iterator over a range of values.
* See function excit_range_init for further details on iterator
...
...
@@ -383,6 +388,11 @@ int excit_skip(excit_t it);
*/
int
excit_cyclic_next
(
excit_t
it
,
ssize_t
*
indexes
,
int
*
looped
);
/*
* Initialize an index iterator with a set of indexes.
*/
int
excit_index_init
(
excit_t
it
,
const
ssize_t
len
,
const
ssize_t
*
index
);
/*
* Initializes a range iterator to iterate from first to last (included) by step.
* "it": a range iterator.
...
...
src/index.c
0 → 100644
View file @
efb65eea
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dev/excit.h"
#include "index.h"
static
int
comp_index_val
(
const
void
*
a_ptr
,
const
void
*
b_ptr
)
{
const
struct
index_s
*
a
=
a_ptr
;
const
struct
index_s
*
b
=
b_ptr
;
if
(
a
->
sorted_value
<
b
->
sorted_value
)
return
-
1
;
if
(
a
->
sorted_value
>
b
->
sorted_value
)
return
1
;
return
0
;
}
static
struct
index_s
*
make_index
(
const
ssize_t
len
,
const
ssize_t
*
values
)
{
ssize_t
i
;
struct
index_s
*
index
=
malloc
((
len
+
1
)
*
sizeof
(
*
index
));
if
(
index
==
NULL
)
return
NULL
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
index
[
i
].
sorted_value
=
values
[
i
];
index
[
i
].
sorted_index
=
i
;
}
qsort
(
index
,
len
,
sizeof
(
*
index
),
comp_index_val
);
for
(
i
=
0
;
i
<
len
;
i
++
)
index
[
i
].
value
=
values
[
i
];
/* STOPIT guard */
index
[
len
].
value
=
index
[
len
-
1
].
value
;
index
[
len
].
sorted_value
=
index
[
len
-
1
].
sorted_value
;
index
[
len
].
sorted_index
=
index
[
len
-
1
].
sorted_index
;
return
index
;
}
static
inline
struct
index_s
*
copy_index
(
const
ssize_t
len
,
const
struct
index_s
*
x
)
{
struct
index_s
*
index
=
malloc
((
len
+
1
)
*
sizeof
(
*
index
));
if
(
index
==
NULL
)
return
NULL
;
memcpy
(
index
,
x
,
(
len
+
1
)
*
sizeof
(
*
x
));
return
index
;
}
static
inline
struct
index_s
*
search_index
(
const
ssize_t
val
,
const
ssize_t
len
,
const
struct
index_s
*
x
)
{
struct
index_s
key
=
{
0
,
val
,
0
};
return
bsearch
(
&
key
,
x
,
len
,
sizeof
(
*
x
),
comp_index_val
);
}
static
inline
ssize_t
search_index_pos
(
const
ssize_t
val
,
const
ssize_t
len
,
const
struct
index_s
*
x
)
{
struct
index_s
*
found
=
search_index
(
val
,
len
,
x
);
if
(
found
==
NULL
)
return
-
1
;
return
found
->
sorted_index
;
}
/******************************************************************************/
static
int
index_it_alloc
(
excit_t
it
)
{
it
->
dimension
=
1
;
struct
index_it_s
*
data_it
=
it
->
data
;
data_it
->
pos
=
0
;
data_it
->
len
=
0
;
data_it
->
inversible
=
0
;
data_it
->
index
=
NULL
;
return
EXCIT_SUCCESS
;
}
static
void
index_it_free
(
excit_t
it
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
if
(
data_it
->
index
!=
NULL
)
free
(
data_it
->
index
);
}
static
int
index_it_size
(
const
excit_t
it
,
ssize_t
*
size
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
*
size
=
data_it
->
len
;
return
EXCIT_SUCCESS
;
}
static
int
index_it_rewind
(
excit_t
it
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
data_it
->
pos
=
0
;
return
EXCIT_SUCCESS
;
}
static
int
index_it_copy
(
excit_t
dst_it
,
const
excit_t
src_it
)
{
int
err
=
EXCIT_SUCCESS
;
struct
index_it_s
*
dst
=
dst_it
->
data
;
struct
index_it_s
*
src
=
src_it
->
data
;
dst
->
pos
=
src
->
pos
;
dst
->
len
=
src
->
len
;
if
(
src
->
len
==
0
)
return
EXCIT_SUCCESS
;
if
(
src
->
index
!=
NULL
)
{
dst
->
index
=
copy_index
(
src
->
len
,
src
->
index
);
if
(
dst
->
index
==
NULL
)
{
err
=
-
EXCIT_ENOMEM
;
goto
exit_with_values
;
}
}
return
EXCIT_SUCCESS
;
exit_with_values:
free
(
dst
->
index
);
dst
->
index
=
NULL
;
return
err
;
}
static
int
index_it_pos
(
const
excit_t
it
,
ssize_t
*
value
)
{
if
(
value
==
NULL
)
return
EXCIT_SUCCESS
;
struct
index_it_s
*
data_it
=
it
->
data
;
*
value
=
data_it
->
pos
;
if
(
data_it
->
pos
>=
data_it
->
len
)
return
EXCIT_STOPIT
;
return
EXCIT_SUCCESS
;
}
static
int
index_it_nth
(
const
excit_t
it
,
ssize_t
n
,
ssize_t
*
indexes
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
if
(
n
<
0
||
n
>=
data_it
->
len
)
return
-
EXCIT_EDOM
;
if
(
indexes
)
*
indexes
=
data_it
->
index
[
n
].
value
;
return
EXCIT_SUCCESS
;
}
static
int
index_it_peek
(
const
excit_t
it
,
ssize_t
*
value
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
if
(
value
)
*
value
=
data_it
->
index
[
data_it
->
pos
].
value
;
if
(
data_it
->
pos
>=
data_it
->
len
)
return
EXCIT_STOPIT
;
return
EXCIT_SUCCESS
;
}
static
int
index_it_next
(
excit_t
it
,
ssize_t
*
indexes
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
if
(
indexes
)
*
indexes
=
data_it
->
index
[
data_it
->
pos
].
value
;
if
(
data_it
->
pos
>=
data_it
->
len
)
return
EXCIT_STOPIT
;
data_it
->
pos
++
;
return
EXCIT_SUCCESS
;
}
static
int
index_it_rank
(
const
excit_t
it
,
const
ssize_t
*
indexes
,
ssize_t
*
n
)
{
struct
index_it_s
*
data_it
=
it
->
data
;
if
(
!
data_it
->
inversible
)
return
-
EXCIT_ENOTSUP
;
if
(
indexes
==
NULL
)
return
EXCIT_SUCCESS
;
if
(
*
indexes
<
data_it
->
index
[
0
].
sorted_value
||
*
indexes
>=
data_it
->
index
[
data_it
->
len
-
1
].
sorted_value
)
return
-
EXCIT_EDOM
;
if
(
n
!=
NULL
)
*
n
=
search_index_pos
(
*
indexes
,
data_it
->
len
,
data_it
->
index
);
return
EXCIT_SUCCESS
;
}
int
excit_index_init
(
excit_t
it
,
const
ssize_t
len
,
const
ssize_t
*
index
)
{
ssize_t
i
;
if
(
it
==
NULL
||
it
->
data
==
NULL
)
return
-
EXCIT_EINVAL
;
struct
index_it_s
*
data_it
=
it
->
data
;
data_it
->
len
=
len
;
data_it
->
index
=
make_index
(
len
,
index
);
if
(
data_it
->
index
==
NULL
)
return
-
EXCIT_ENOMEM
;
// Check for duplicates
data_it
->
inversible
=
1
;
for
(
i
=
1
;
i
<
len
;
i
++
)
if
(
data_it
->
index
[
i
].
sorted_value
==
data_it
->
index
[
i
-
1
].
sorted_value
)
{
data_it
->
inversible
=
0
;
break
;
}
return
EXCIT_SUCCESS
;
}
struct
excit_func_table_s
excit_index_func_table
=
{
index_it_alloc
,
index_it_free
,
index_it_copy
,
index_it_next
,
index_it_peek
,
index_it_size
,
index_it_rewind
,
NULL
,
index_it_nth
,
index_it_rank
,
index_it_pos
};
src/index.h
0 → 100644
View file @
efb65eea
#ifndef EXCIT_INDEX_H
#define EXCIT_INDEX_H
struct
index_s
{
ssize_t
value
;
ssize_t
sorted_value
;
ssize_t
sorted_index
;
};
struct
index_it_s
{
ssize_t
pos
;
ssize_t
len
;
struct
index_s
*
index
;
int
inversible
;
};
extern
struct
excit_func_table_s
excit_index_func_table
;
#endif //EXCIT_INDEX_H
tests/Makefile.am
View file @
efb65eea
...
...
@@ -6,6 +6,7 @@ AM_LDFLAGS = ../src/libexcit.la
LIBHSOURCES
=
excit_test.h
LIBCSOURCES
=
excit_test.c
excit_index_SOURCES
=
$(LIBHSOURCES)
$(LIBCSOURCES)
excit_index.c
excit_range_SOURCES
=
$(LIBHSOURCES)
$(LIBCSOURCES)
excit_range.c
excit_product_SOURCES
=
$(LIBHSOURCES)
$(LIBCSOURCES)
excit_product.c
excit_repeat_SOURCES
=
$(LIBHSOURCES)
$(LIBCSOURCES)
excit_repeat.c
...
...
@@ -14,7 +15,7 @@ excit_tleaf_SOURCES = $(LIBHSOURCES) $(LIBCSOURCES) excit_tleaf.c
excit_hilbert2d_SOURCES
=
$(LIBHSOURCES)
$(LIBCSOURCES)
excit_hilbert2d.c
excit_composition_SOURCES
=
$(LIBHSOURCES)
$(LIBCSOURCES)
excit_composition.c
UNIT_TESTS
=
excit_range excit_product excit_repeat excit_cons excit_hilbert2d excit_composition excit_tleaf
UNIT_TESTS
=
excit_range excit_product excit_repeat excit_cons excit_hilbert2d excit_composition excit_
index excit_
tleaf
# all tests
check_PROGRAMS
=
$(UNIT_TESTS)
...
...
tests/excit_index.c
0 → 100644
View file @
efb65eea
#include <assert.h>
#include <stdlib.h>
#include <sys/time.h>
#include "excit.h"
#include "excit_test.h"
#define NTESTS 1
#define MAX_LEN 4096
#define MIN_LEN 16
static
void
rand_seed
(
void
)
{
struct
timeval
tv
;
unsigned
int
us
;
gettimeofday
(
&
tv
,
NULL
);
us
=
(
unsigned
int
)(
1000000
*
tv
.
tv_sec
+
tv
.
tv_usec
);
srand
(
us
);
}
static
void
shuffle
(
const
ssize_t
len
,
ssize_t
*
x
)
{
ssize_t
i
,
swap
,
rnd
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
swap
=
x
[
i
];
rnd
=
rand
()
%
(
len
-
i
);
x
[
i
]
=
x
[
i
+
rnd
];
x
[
i
+
rnd
]
=
swap
;
}
}
static
ssize_t
*
make_unique_index
(
const
ssize_t
len
)
{
ssize_t
i
;
ssize_t
*
index
=
malloc
(
len
*
sizeof
(
*
index
));
assert
(
index
!=
NULL
);
for
(
i
=
0
;
i
<
len
;
i
++
)
index
[
i
]
=
i
;
shuffle
(
len
,
index
);
return
index
;
}
static
ssize_t
*
make_index
(
const
ssize_t
len
)
{
ssize_t
i
;
ssize_t
*
index
=
malloc
(
len
*
sizeof
(
*
index
));
assert
(
index
!=
NULL
);
for
(
i
=
0
;
i
<
len
;
i
++
)
index
[
i
]
=
rand
()
%
len
;
return
index
;
}
void
run_tests
(
const
ssize_t
len
,
const
ssize_t
*
index
)
{
ssize_t
i
=
0
;
excit_t
it
;
while
(
synthetic_tests
[
i
])
{
it
=
excit_alloc
(
EXCIT_INDEX
);
assert
(
it
!=
NULL
);
assert
(
excit_index_init
(
it
,
len
,
index
)
==
EXCIT_SUCCESS
);
synthetic_tests
[
i
]
(
it
);
excit_free
(
it
);
i
++
;
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
ssize_t
n
=
NTESTS
;
rand_seed
();
while
(
n
--
)
{
ssize_t
len
=
MIN_LEN
+
rand
()
%
(
MAX_LEN
-
MIN_LEN
);
ssize_t
*
uind
=
make_unique_index
(
len
);
run_tests
(
len
,
uind
);
free
(
uind
);
ssize_t
*
ind
=
make_index
(
len
);
run_tests
(
len
,
ind
);
free
(
ind
);
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment