eina_matrixsparse: welcome sparse matrix implementation and tests.

Sparse Matrix was implemented and tested by Rafael Antognolli and
myself in order to implement optimized large sparse matrix walk in
some products, one of them WebKit-EFL optimizations.

We have done extensive tests, with good code coverage. Similar to
lists/inlists, we keep pointer to last known element and similar to
iterators we keep reference to last accessed row and cell inside
rows. This allows fast sequential access (for i... for j... m[i,j]),
that is our most common usage case.

Rows are kept in a list, with cells inside that row as another
list. It's not similar to most book implementations where cells keep
reference to their sibling cells in other rows as well, we opted to
not do that to save some pointers and make algorithms simpler, still
do great for our use case.

This code was developed on behalf of our client, that wants to remain
unnamed so far. Thanks client ;-)



SVN revision: 42243
This commit is contained in:
Gustavo Sverzut Barbieri 2009-09-04 13:43:44 +00:00
parent d8acbfc6f6
commit 643958705b
11 changed files with 2192 additions and 2 deletions

View File

@ -232,6 +232,7 @@ case "$host_os" in
;;
esac
EFL_CHECK_COVERAGE([${enable_tests}], [enable_coverage="yes"], [enable_coverage="no"])
EINA_CFLAGS="${EFL_COVERAGE_CFLAGS}"
case "${host_os}" in
cegcc*)
@ -348,7 +349,6 @@ EINA_CHECK_MODULE([pass-through], [yes], [pass through])
### Unit tests, coverage and benchmarking
EFL_CHECK_TESTS([enable_tests="yes"], [enable_tests="no"])
EFL_CHECK_COVERAGE([${enable_tests}], [enable_coverage="yes"], [enable_coverage="no"])
EFL_CHECK_BENCHMARK([enable_benchmark="yes"], [enable_benchmark="no"])
EINA_BENCH_MODULE([evas], [${enable_benchmark}], [evas], [enable_benchmark_evas="yes"], [enable_benchmark_evas="no"])
EINA_BENCH_MODULE([ecore], [${enable_benchmark}], [ecore], [enable_benchmark_ecore="yes"], [enable_benchmark_ecore="no"])

View File

@ -181,6 +181,7 @@ extern "C" {
#include "eina_cpu.h"
#include "eina_tiler.h"
#include "eina_hamster.h"
#include "eina_matrixsparse.h"
#ifdef __cplusplus
}

View File

@ -0,0 +1,116 @@
/* EINA - EFL data type library
* Copyright (C) 2009 Gustavo Sverzut Barbieri
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EINA_MATRIXSPARSE_H_
#define EINA_MATRIXSPARSE_H_
#include <stdlib.h>
#include "eina_config.h"
#include "eina_types.h"
#include "eina_iterator.h"
#include "eina_accessor.h"
/**
* @addtogroup Eina_Data_Types_Group Data Types
*
* @{
*/
/**
* @addtogroup Eina_Containers_Group Containers
*
* @{
*/
/**
* @defgroup Eina_Matrixsparse_Group Sparse Matrix
*
* @{
*/
/**
* @typedef Eina_Matrixsparse
* Type for a generic sparse matrix.
*/
typedef struct _Eina_Matrixsparse Eina_Matrixsparse;
/**
* @typedef Eina_Matrixsparse_Row
* Type for a generic sparse matrix row, opaque for users.
*/
typedef struct _Eina_Matrixsparse_Row Eina_Matrixsparse_Row;
/**
* @typedef Eina_Matrixsparse_Cell
* Type for a generic sparse matrix cell, opaque for users.
*/
typedef struct _Eina_Matrixsparse_Cell Eina_Matrixsparse_Cell;
typedef struct _Eina_Matrixsparse_Item_Cell Eina_Matrixsparse_Item_Cell;
typedef struct _Eina_Matrixsparse_Item_Row Eina_Matrixsparse_Item_Row;
/* init */
EAPI int eina_matrixsparse_init(void);
EAPI int eina_matrixsparse_shutdown(void);
/* constructors and destructors */
EAPI Eina_Matrixsparse *eina_matrixsparse_new(unsigned long rows, unsigned long cols, void (*free_func)(void *user_data, void *cell_data), const void *user_data);
EAPI void eina_matrixsparse_free(Eina_Matrixsparse *m);
/* size manipulation */
EAPI void eina_matrixsparse_size_get(const Eina_Matrixsparse *m, unsigned long *rows, unsigned long *cols);
EAPI Eina_Bool eina_matrixsparse_size_set(Eina_Matrixsparse *m, unsigned long rows, unsigned long cols);
/* data getting */
EAPI Eina_Bool eina_matrixsparse_cell_idx_get(const Eina_Matrixsparse *m, unsigned long row, unsigned long col, Eina_Matrixsparse_Cell **cell);
EAPI void *eina_matrixsparse_cell_data_get(const Eina_Matrixsparse_Cell *cell);
EAPI void *eina_matrixsparse_data_idx_get(const Eina_Matrixsparse *m, unsigned long row, unsigned long col);
EAPI Eina_Bool eina_matrixsparse_cell_position_get(const Eina_Matrixsparse_Cell *cell, unsigned long *row, unsigned long *col);
/* data setting */
EAPI Eina_Bool eina_matrixsparse_cell_data_replace(Eina_Matrixsparse_Cell *cell, const void *data, void **p_old);
EAPI Eina_Bool eina_matrixsparse_cell_data_set(Eina_Matrixsparse_Cell *cell, const void *data);
EAPI Eina_Bool eina_matrixsparse_data_idx_replace(Eina_Matrixsparse *m, unsigned long row, unsigned long col, const void *data, void **p_old);
EAPI Eina_Bool eina_matrixsparse_data_idx_set(Eina_Matrixsparse *m, unsigned long row, unsigned long col, const void *data);
/* data deleting */
EAPI Eina_Bool eina_matrixsparse_row_idx_clear(Eina_Matrixsparse *m, unsigned long row);
EAPI Eina_Bool eina_matrixsparse_column_idx_clear(Eina_Matrixsparse *m, unsigned long col);
EAPI Eina_Bool eina_matrixsparse_cell_idx_clear(Eina_Matrixsparse *m, unsigned long row, unsigned long col);
EAPI Eina_Bool eina_matrixsparse_cell_clear(Eina_Matrixsparse_Cell *cell);
/* iterators */
EAPI Eina_Iterator *eina_matrixsparse_iterator_new(const Eina_Matrixsparse *m);
EAPI Eina_Iterator *eina_matrixsparse_iterator_complete_new(const Eina_Matrixsparse *m);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* EINA_MATRIXSPARSE_H_ */

View File

@ -71,6 +71,17 @@
#define EINA_MAGIC_TILER 0x98761240
#define EINA_MAGIC_TILER_ITERATOR 0x98761241
#define EINA_MAGIC_MATRIXSPARSE 0x98761242
#define EINA_MAGIC_MATRIXSPARSE_ROW 0x98761243
#define EINA_MAGIC_MATRIXSPARSE_CELL 0x98761244
#define EINA_MAGIC_MATRIXSPARSE_ITERATOR 0x98761245
#define EINA_MAGIC_MATRIXSPARSE_ROW_ITERATOR 0x98761246
#define EINA_MAGIC_MATRIXSPARSE_ROW_ACCESSOR 0x98761247
#define EINA_MAGIC_MATRIXSPARSE_CELL_ITERATOR 0x98761248
#define EINA_MAGIC_MATRIXSPARSE_CELL_ACCESSOR 0x98761249
/* undef the following, we want out version */
#undef FREE
#define FREE(ptr) \

View File

@ -19,6 +19,7 @@ eina_inlist.c \
eina_file.c \
eina_mempool.c \
eina_list.c \
eina_matrixsparse.c \
eina_module.c \
eina_value.c \
eina_array.c \

View File

@ -31,6 +31,7 @@
#include "eina_hash.h"
#include "eina_stringshare.h"
#include "eina_list.h"
#include "eina_matrixsparse.h"
#include "eina_array.h"
#include "eina_counter.h"
#include "eina_benchmark.h"
@ -89,6 +90,7 @@ static int _eina_log_dom = -1;
* @li eina_hash_init()
* @li eina_stringshare_init()
* @li eina_list_init()
* @li eina_matrixsparse_init()
* @li eina_array_init()
* @li eina_counter_init()
* @li eina_benchmark_init()
@ -144,6 +146,11 @@ eina_init(void)
ERR("Could not initialize eina list module.");
goto list_init_error;
}
if (!eina_matrixsparse_init())
{
ERR("Could not initialize eina matrixsparse module.");
goto matrixsparse_init_error;
}
if (!eina_array_init())
{
ERR("Could not initialize eina array module.");
@ -182,6 +189,8 @@ eina_init(void)
counter_init_error:
eina_array_shutdown();
array_init_error:
eina_matrixsparse_shutdown();
matrixsparse_init_error:
eina_list_shutdown();
list_init_error:
eina_stringshare_shutdown();
@ -214,6 +223,7 @@ eina_init(void)
* @li eina_benchmark_shutdown()
* @li eina_counter_shutdown()
* @li eina_array_shutdown()
* @li eina_matrixsparse_shutdown()
* @li eina_list_shutdown()
* @li eina_stringshare_shutdown()
* @li eina_hash_shutdown()
@ -235,6 +245,7 @@ eina_shutdown(void)
eina_benchmark_shutdown();
eina_counter_shutdown();
eina_array_shutdown();
eina_matrixsparse_shutdown();
eina_list_shutdown();
eina_stringshare_shutdown();
eina_hash_shutdown();

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,8 @@ eina_test_file.c \
eina_test_benchmark.c \
eina_test_mempool.c \
eina_test_rectangle.c \
eina_test_list.c
eina_test_list.c \
eina_test_matrixsparse.c
eina_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeina.la

View File

@ -53,6 +53,7 @@ static const Eina_Test_Case etc[] = {
{ "Benchmark", eina_test_benchmark },
{ "Mempool", eina_test_mempool },
{ "Rectangle", eina_test_rectangle },
{ "Matrix Sparse", eina_test_matrixsparse },
{ NULL, NULL }
};

View File

@ -41,5 +41,6 @@ void eina_test_file(TCase *tc);
void eina_test_benchmark(TCase *tc);
void eina_test_mempool(TCase *tc);
void eina_test_rectangle(TCase *tc);
void eina_test_matrixsparse(TCase *tc);
#endif /* EINA_SUITE_H_ */

View File

@ -0,0 +1,481 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "eina_matrixsparse.h"
#include "eina_suite.h"
#define MAX_ROWS 10
#define MAX_COLS 10
static void eina_matrixsparse_free_cell_cb(void *user_data, void *cell_data)
{
long *value = cell_data;
long **data = user_data;
}
static void matrixsparse_initialize(Eina_Matrixsparse *matrix, long data[MAX_ROWS][MAX_COLS], unsigned long nrows, unsigned long ncols)
{
unsigned long i, j;
Eina_Bool r;
for (i = 0; i < nrows; i++)
for (j = 0; j < ncols; j++)
if (data[i][j] != 0)
{
r = eina_matrixsparse_data_idx_set(matrix, i, j, &data[i][j]);
fail_if(r == EINA_FALSE);
}
}
static void matrixsparse_check(Eina_Matrixsparse *matrix, long data[MAX_ROWS][MAX_COLS], unsigned long nrows, unsigned long ncols)
{
unsigned long i, j;
long *test1;
for (i = 0; i < MAX_ROWS; i++)
for (j = 0; j < MAX_COLS; j++)
{
if (data[i][j] != 0)
{
test1 = eina_matrixsparse_data_idx_get(matrix, i, j);
fail_if(test1 == NULL || *test1 != data[i][j]);
}
else
{
test1 = eina_matrixsparse_data_idx_get(matrix, i, j);
fail_if(test1 != NULL);
}
}
}
START_TEST(eina_test_simple)
{
Eina_Matrixsparse *matrix = NULL;
Eina_Matrixsparse_Cell *cell = NULL;
Eina_Bool r;
long *test1, value, value2, value3, value4;
unsigned long i, j;
unsigned long nrows, ncols, row, col;
long data[MAX_ROWS][MAX_COLS];
for (i = 0; i < MAX_ROWS; i++)
for (j = 0; j < MAX_COLS; j++)
data[i][j] = 0;
data[0][3] = 3;
data[1][3] = 13;
data[1][6] = 16;
data[1][9] = 19;
data[1][8] = 18;
data[1][7] = 17;
data[2][8] = 28;
data[2][7] = 27;
data[2][6] = 26;
data[3][5] = 35;
data[3][6] = 36;
data[3][7] = 37;
data[3][9] = 39;
data[3][0] = 30;
data[4][6] = 46;
data[4][8] = 48;
data[4][2] = 42;
data[4][3] = 43;
data[4][7] = 47;
data[5][3] = 53;
data[6][3] = 63;
data[6][4] = 64;
data[6][6] = 66;
data[7][3] = 73;
data[7][7] = 77;
data[8][8] = 88;
value = -1;
value2 = -2;
value3 = -3;
value4 = -4;
eina_matrixsparse_init();
matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS,
eina_matrixsparse_free_cell_cb, data);
fail_if(matrix == NULL);
r = eina_matrixsparse_cell_idx_get(matrix, 3, 5, &cell);
fail_if(r == EINA_FALSE);
fail_if(cell != NULL);
matrixsparse_initialize(matrix, data, MAX_ROWS, MAX_COLS);
/* data fetching */
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 0);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][0]);
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 5);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][5]);
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 6);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][6]);
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 1);
fail_if(test1 != NULL);
r = eina_matrixsparse_cell_idx_get(matrix, 3, 5, &cell);
fail_if(r == EINA_FALSE);
fail_if(cell == NULL);
test1 = eina_matrixsparse_cell_data_get(cell);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][5]);
r = eina_matrixsparse_cell_position_get(cell, &row, &col);
fail_if(r == EINA_FALSE);
fail_if(row != 3 || col != 5);
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 3);
fail_if(*test1 != data[4][3]);
test1 = eina_matrixsparse_data_idx_get(matrix, 1, 3);
fail_if(*test1 != data[1][3]);
/* data changing */
r = eina_matrixsparse_data_idx_set(matrix, 1, 9, &data[1][9]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_replace(matrix, 4, 3, &value, &test1);
fail_if(r == EINA_FALSE);
fail_if(test1 == NULL);
fail_if(*test1 != data[4][3]);
data[4][3] = value;
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 3);
fail_if(test1 == NULL || *test1 != value);
r = eina_matrixsparse_cell_data_replace(cell, &value2, &test1);
fail_if(r == EINA_FALSE);
fail_if(test1 == NULL);
fail_if(*test1 != data[3][5]);
data[3][5] = value2;
test1 = eina_matrixsparse_data_idx_get(matrix, 3, 5);
fail_if(test1 == NULL);
fail_if(*test1 != value2);
r = eina_matrixsparse_cell_idx_get(matrix, 4, 2, &cell);
fail_if(r == EINA_FALSE || cell == NULL);
r = eina_matrixsparse_cell_data_set(cell, &value3);
fail_if(r == EINA_FALSE);
data[4][2] = value3;
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 2);
fail_if(test1 == NULL || *test1 != value3);
r = eina_matrixsparse_data_idx_replace(matrix, 6, 5, &value4, &test1);
fail_if(r == EINA_FALSE || test1 != NULL);
data[6][5] = value4;
/* cell deletion */
r = eina_matrixsparse_row_idx_clear(matrix, 4);
fail_if(r == EINA_FALSE);
data[4][6] = 0;
data[4][8] = 0;
data[4][2] = 0;
data[4][3] = 0;
data[4][7] = 0;
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 3);
fail_if(test1 != NULL);
test1 = eina_matrixsparse_data_idx_get(matrix, 4, 8);
fail_if(test1 != NULL);
test1 = eina_matrixsparse_data_idx_get(matrix, 5, 3);
fail_if(*test1 != data[5][3]);
r = eina_matrixsparse_column_idx_clear(matrix, 3);
fail_if(r != EINA_TRUE);
data[0][3] = 0;
data[1][3] = 0;
data[4][3] = 0;
data[5][3] = 0;
data[6][3] = 0;
data[7][3] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 3, 5);
fail_if(r != EINA_TRUE);
data[3][5] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 3, 9);
fail_if(r != EINA_TRUE);
data[3][9] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 4, 3);
fail_if(r != EINA_TRUE);
data[4][3] = 0;
r = eina_matrixsparse_cell_idx_get(matrix, 3, 7, &cell);
fail_if(r == EINA_FALSE);
fail_if(cell == NULL);
r = eina_matrixsparse_cell_clear(cell);
fail_if(r == EINA_FALSE);
data[3][7] = 0;
r = eina_matrixsparse_cell_idx_get(matrix, 2, 7, &cell);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_cell_idx_clear(matrix, 2, 8);
fail_if(r == EINA_FALSE);
data[2][8] = 0;
r = eina_matrixsparse_cell_idx_clear(matrix, 2, 7);
fail_if(r == EINA_FALSE);
data[2][7] = 0;
r = eina_matrixsparse_cell_idx_get(matrix, 7, 7, &cell);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_row_idx_clear(matrix, 8);
fail_if(r == EINA_FALSE);
data[8][8] = 0;
r = eina_matrixsparse_row_idx_clear(matrix, 7);
fail_if(r == EINA_FALSE);
data[7][3] = 0;
data[7][7] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
eina_matrixsparse_free(matrix);
eina_matrixsparse_shutdown();
}
END_TEST
START_TEST(eina_test_resize)
{
Eina_Matrixsparse *matrix = NULL;
Eina_Matrixsparse_Cell *cell = NULL;
Eina_Bool r;
long *test1;
unsigned long i, j;
unsigned long nrows, ncols;
long data[MAX_ROWS][MAX_COLS];
for (i = 0; i < MAX_ROWS; i++)
for (j = 0; j < MAX_COLS; j++)
data[i][j] = 0;
eina_matrixsparse_init();
matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS,
eina_matrixsparse_free_cell_cb, data);
fail_if(matrix == NULL);
/* cell insertion */
data[0][5] = 5;
data[1][0] = 10;
data[1][3] = 13;
data[1][6] = 16;
data[1][9] = 19;
data[1][8] = 18;
data[1][7] = 17;
data[2][8] = 28;
data[2][7] = 27;
data[2][6] = 26;
data[3][0] = 30;
data[3][5] = 35;
data[3][6] = 36;
data[3][7] = 37;
data[3][9] = 39;
data[3][0] = 30;
data[4][8] = 48;
data[4][2] = 42;
data[4][3] = 43;
data[4][7] = 47;
data[4][6] = 46;
data[5][3] = 53;
data[6][3] = 63;
data[6][4] = 64;
data[6][6] = 66;
data[7][3] = 73;
data[7][7] = 77;
data[8][8] = 88;
matrixsparse_initialize(matrix, data, MAX_ROWS, MAX_COLS);
eina_matrixsparse_size_get(matrix, &nrows, &ncols);
fail_if(nrows != MAX_ROWS || ncols != MAX_COLS);
r = eina_matrixsparse_size_set(matrix, nrows - 2, ncols - 2);
fail_if(r == EINA_FALSE);
data[1][9] = 0;
data[1][8] = 0;
data[2][8] = 0;
data[3][9] = 0;
data[4][8] = 0;
data[8][8] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 5, 1);
fail_if(r == EINA_FALSE);
data[0][5] = 0;
data[1][3] = 0;
data[1][6] = 0;
data[1][7] = 0;
data[2][7] = 0;
data[2][6] = 0;
data[3][5] = 0;
data[3][6] = 0;
data[3][7] = 0;
data[4][2] = 0;
data[4][3] = 0;
data[4][7] = 0;
data[4][6] = 0;
data[5][3] = 0;
data[6][3] = 0;
data[6][4] = 0;
data[6][6] = 0;
data[7][3] = 0;
data[7][7] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 1, 1);
fail_if(r == EINA_FALSE);
data[3][0] = 0;
data[1][0] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 5, 4);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 2, &data[4][2]);
fail_if(r == EINA_FALSE);
data[4][2] = 42;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
r = eina_matrixsparse_size_set(matrix, 5, 1);
fail_if(r == EINA_FALSE);
data[4][2] = 0;
matrixsparse_check(matrix, data, MAX_ROWS, MAX_COLS);
eina_matrixsparse_free(matrix);
eina_matrixsparse_shutdown();
}
END_TEST
START_TEST(eina_test_iterators)
{
Eina_Matrixsparse *matrix = NULL;
Eina_Matrixsparse_Cell *cell = NULL;
Eina_Iterator *it = NULL;
Eina_Bool r;
long *test1, value;
unsigned long i, j;
unsigned long row, col;
long data[MAX_ROWS][MAX_COLS];
value = 0;
for (i = 0; i < MAX_ROWS; i++)
{
for (j = 0; j < MAX_COLS; j++)
{
data[i][j] = value++;
printf("%4ld ", data[i][j]);
}
printf("\n");
}
eina_matrixsparse_init();
matrix = eina_matrixsparse_new(MAX_ROWS, MAX_COLS,
eina_matrixsparse_free_cell_cb, data);
fail_if(matrix == NULL);
r = eina_matrixsparse_data_idx_set(matrix, 3, 5, &data[3][5]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 6, &data[3][6]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 7, &data[3][7]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 9, &data[3][9]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 3, 0, &data[3][0]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 6, &data[4][6]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 8, &data[4][8]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 2, &data[4][2]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 3, &data[4][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 4, 7, &data[4][7]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 6, 4, &data[6][4]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 5, 3, &data[5][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 6, 3, &data[6][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 7, 3, &data[7][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 0, 3, &data[0][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 1, 3, &data[1][3]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 1, 6, &data[1][6]);
fail_if(r == EINA_FALSE);
r = eina_matrixsparse_data_idx_set(matrix, 1, 9, &data[1][9]);
fail_if(r == EINA_FALSE);
it = eina_matrixsparse_iterator_new(matrix);
fail_if(it == NULL);
EINA_ITERATOR_FOREACH(it, cell)
{
fail_if(cell == NULL);
r = eina_matrixsparse_cell_position_get(cell, &row, &col);
fail_if(r == EINA_FALSE);
test1 = eina_matrixsparse_cell_data_get(cell);
fail_if(test1 == NULL || *test1 != data[row][col]);
}
eina_iterator_free(it);
it = eina_matrixsparse_iterator_complete_new(matrix);
fail_if(it == NULL);
EINA_ITERATOR_FOREACH(it, cell)
{
fail_if(cell == NULL);
r = eina_matrixsparse_cell_position_get(cell, &row, &col);
fail_if(r == EINA_FALSE);
test1 = eina_matrixsparse_cell_data_get(cell);
if (test1)
fail_if(*test1 != data[row][col]);
}
eina_iterator_free(it);
eina_matrixsparse_free(matrix);
eina_matrixsparse_shutdown();
}
END_TEST
void
eina_test_matrixsparse(TCase *tc)
{
tcase_add_test(tc, eina_test_simple);
tcase_add_test(tc, eina_test_resize);
tcase_add_test(tc, eina_test_iterators);
}