Skip to content

Commit aa4c87b

Browse files
committed
node table
1 parent 6b74680 commit aa4c87b

File tree

2 files changed

+136
-22
lines changed

2 files changed

+136
-22
lines changed

c/tests/test_tables.c

+108
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,113 @@ test_node_table(void)
12871287
free(individual);
12881288
}
12891289

1290+
static void
1291+
test_node_table_takeset(void)
1292+
{
1293+
int ret = 0;
1294+
tsk_id_t ret_id;
1295+
tsk_node_table_t source_table, table;
1296+
tsk_size_t num_rows = 100;
1297+
tsk_id_t j;
1298+
tsk_flags_t *flags;
1299+
double *time;
1300+
tsk_id_t *population;
1301+
tsk_id_t *individual;
1302+
char *metadata;
1303+
tsk_size_t *metadata_offset;
1304+
const char *test_metadata = "test";
1305+
tsk_size_t test_metadata_length = 4;
1306+
tsk_size_t zeros[num_rows + 1];
1307+
tsk_id_t neg_ones[num_rows];
1308+
1309+
tsk_memset(zeros, 0, (num_rows + 1) * sizeof(tsk_size_t));
1310+
tsk_memset(neg_ones, 0xff, num_rows * sizeof(tsk_id_t));
1311+
/* Make a table to copy from */
1312+
ret = tsk_node_table_init(&source_table, 0);
1313+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1314+
for (j = 0; j < (tsk_id_t) num_rows; j++) {
1315+
ret_id = tsk_node_table_add_row(&source_table, (tsk_flags_t) j, (double) j + 1,
1316+
j + 2, j + 3, test_metadata, test_metadata_length);
1317+
CU_ASSERT_EQUAL_FATAL(ret_id, j);
1318+
}
1319+
1320+
/* Prepare arrays to be taken */
1321+
flags = tsk_malloc(num_rows * sizeof(tsk_flags_t));
1322+
CU_ASSERT_FATAL(flags != NULL);
1323+
tsk_memcpy(flags, source_table.flags, num_rows * sizeof(tsk_flags_t));
1324+
time = tsk_malloc(num_rows * sizeof(double));
1325+
CU_ASSERT_FATAL(time != NULL);
1326+
tsk_memcpy(time, source_table.time, num_rows * sizeof(double));
1327+
population = tsk_malloc(num_rows * sizeof(tsk_id_t));
1328+
CU_ASSERT_FATAL(population != NULL);
1329+
tsk_memcpy(population, source_table.population, num_rows * sizeof(tsk_id_t));
1330+
individual = tsk_malloc(num_rows * sizeof(tsk_id_t));
1331+
CU_ASSERT_FATAL(individual != NULL);
1332+
tsk_memcpy(individual, source_table.individual, num_rows * sizeof(tsk_id_t));
1333+
metadata = tsk_malloc(num_rows * test_metadata_length * sizeof(char));
1334+
CU_ASSERT_FATAL(metadata != NULL);
1335+
tsk_memcpy(
1336+
metadata, source_table.metadata, num_rows * test_metadata_length * sizeof(char));
1337+
metadata_offset = tsk_malloc((num_rows + 1) * sizeof(tsk_size_t));
1338+
CU_ASSERT_FATAL(metadata_offset != NULL);
1339+
tsk_memcpy(metadata_offset, source_table.metadata_offset,
1340+
(num_rows + 1) * sizeof(tsk_size_t));
1341+
1342+
ret = tsk_node_table_init(&table, 0);
1343+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1344+
1345+
/* Add one row so that we can check takeset frees it */
1346+
ret_id = tsk_node_table_add_row(
1347+
&table, (tsk_flags_t) 1, 2, 3, 4, test_metadata, test_metadata_length);
1348+
CU_ASSERT_EQUAL_FATAL(ret_id, 0);
1349+
1350+
ret = tsk_node_table_takeset_columns(&table, num_rows, flags, time, population,
1351+
individual, metadata, metadata_offset);
1352+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1353+
CU_ASSERT_TRUE(tsk_node_table_equals(&source_table, &table, 0));
1354+
1355+
/* Test error states, all of these must not take the array, or free existing */
1356+
/* metadata and metadata offset must be simultaneously NULL or not */
1357+
ret = tsk_node_table_takeset_columns(
1358+
&table, num_rows, flags, time, population, individual, NULL, metadata_offset);
1359+
CU_ASSERT_EQUAL(ret, TSK_ERR_BAD_PARAM_VALUE);
1360+
ret = tsk_node_table_takeset_columns(
1361+
&table, num_rows, flags, time, population, individual, metadata, NULL);
1362+
CU_ASSERT_EQUAL(ret, TSK_ERR_BAD_PARAM_VALUE);
1363+
1364+
/* Truncation after takeset keeps memory and max_rows */
1365+
ret = tsk_node_table_clear(&table);
1366+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1367+
CU_ASSERT_EQUAL_FATAL(table.max_rows, num_rows);
1368+
1369+
flags = tsk_malloc(num_rows * sizeof(tsk_flags_t));
1370+
CU_ASSERT_FATAL(flags != NULL);
1371+
tsk_memcpy(flags, source_table.flags, num_rows * sizeof(tsk_flags_t));
1372+
time = tsk_malloc(num_rows * sizeof(double));
1373+
CU_ASSERT_FATAL(time != NULL);
1374+
tsk_memcpy(time, source_table.time, num_rows * sizeof(double));
1375+
/* if metadata and offset are both null, all entries are zero length,
1376+
individual and population default to -1 */
1377+
num_rows = 10;
1378+
ret = tsk_node_table_takeset_columns(
1379+
&table, num_rows, flags, time, NULL, NULL, NULL, NULL);
1380+
CU_ASSERT_EQUAL(ret, 0);
1381+
CU_ASSERT_EQUAL(table.num_rows, num_rows);
1382+
// CU_ASSERT_EQUAL(
1383+
// tsk_memcmp(table.population, neg_ones, num_rows * sizeof(tsk_id_t)), 0);
1384+
// CU_ASSERT_EQUAL(
1385+
// tsk_memcmp(table.individual, neg_ones, num_rows * sizeof(tsk_id_t)), 0);
1386+
CU_ASSERT_EQUAL(
1387+
tsk_memcmp(table.metadata_offset, zeros, (num_rows + 1) * sizeof(tsk_size_t)),
1388+
0);
1389+
CU_ASSERT_EQUAL(table.metadata_length, 0);
1390+
1391+
ret = tsk_node_table_free(&table);
1392+
CU_ASSERT_EQUAL(ret, 0);
1393+
ret = tsk_node_table_free(&source_table);
1394+
CU_ASSERT_EQUAL(ret, 0);
1395+
}
1396+
12901397
static void
12911398
test_node_table_update_row(void)
12921399
{
@@ -9353,6 +9460,7 @@ main(int argc, char **argv)
93539460
CU_TestInfo tests[] = {
93549461
{ "test_node_table", test_node_table },
93559462
{ "test_node_table_update_row", test_node_table_update_row },
9463+
{ "test_node_table_takeset", test_node_table_takeset },
93569464
{ "test_edge_table", test_edge_table },
93579465
{ "test_edge_table_update_row", test_edge_table_update_row },
93589466
{ "test_edge_table_update_row_no_metadata",

c/tskit/tables.c

+28-22
Original file line numberDiff line numberDiff line change
@@ -1834,21 +1834,43 @@ tsk_node_table_copy(
18341834
return ret;
18351835
}
18361836

1837+
int TSK_WARN_UNUSED
1838+
tsk_node_table_set_columns(tsk_node_table_t *self, tsk_size_t num_rows,
1839+
const tsk_flags_t *flags, const double *time, const tsk_id_t *population,
1840+
const tsk_id_t *individual, const char *metadata, const tsk_size_t *metadata_offset)
1841+
{
1842+
int ret;
1843+
1844+
ret = tsk_node_table_clear(self);
1845+
if (ret != 0) {
1846+
goto out;
1847+
}
1848+
ret = tsk_node_table_append_columns(
1849+
self, num_rows, flags, time, population, individual, metadata, metadata_offset);
1850+
out:
1851+
return ret;
1852+
}
1853+
18371854
int TSK_WARN_UNUSED
18381855
tsk_node_table_takeset_columns(tsk_node_table_t *self, tsk_size_t num_rows,
18391856
tsk_flags_t *flags, double *time, tsk_id_t *population, tsk_id_t *individual,
18401857
char *metadata, tsk_size_t *metadata_offset)
18411858
{
1842-
int ret;
1843-
1844-
tsk_node_table_free_columns(self);
1859+
int ret = 0;
18451860

1846-
/* Check the mandatory columns */
1861+
/* We need to check all the inputs before we start freeing or taking memory */
18471862
if (flags == NULL || time == NULL) {
1848-
/* TODO TSK_ERR_MANDATORY_COLUMN_MISSING */
18491863
ret = TSK_ERR_BAD_PARAM_VALUE;
18501864
goto out;
18511865
}
1866+
ret = check_ragged_column(num_rows, metadata, metadata_offset);
1867+
if (ret != 0) {
1868+
goto out;
1869+
}
1870+
1871+
tsk_node_table_free_columns(self);
1872+
self->num_rows = num_rows;
1873+
self->max_rows = num_rows;
18521874
self->flags = flags;
18531875
self->time = time;
18541876

@@ -1860,6 +1882,7 @@ tsk_node_table_takeset_columns(tsk_node_table_t *self, tsk_size_t num_rows,
18601882
if (ret != 0) {
18611883
goto out;
18621884
}
1885+
18631886
ret = takeset_ragged_column(num_rows, metadata, metadata_offset,
18641887
(void *) &self->metadata, &self->metadata_offset, &self->metadata_length);
18651888
if (ret != 0) {
@@ -1869,23 +1892,6 @@ tsk_node_table_takeset_columns(tsk_node_table_t *self, tsk_size_t num_rows,
18691892
return ret;
18701893
}
18711894

1872-
int TSK_WARN_UNUSED
1873-
tsk_node_table_set_columns(tsk_node_table_t *self, tsk_size_t num_rows,
1874-
const tsk_flags_t *flags, const double *time, const tsk_id_t *population,
1875-
const tsk_id_t *individual, const char *metadata, const tsk_size_t *metadata_offset)
1876-
{
1877-
int ret;
1878-
1879-
ret = tsk_node_table_clear(self);
1880-
if (ret != 0) {
1881-
goto out;
1882-
}
1883-
ret = tsk_node_table_append_columns(
1884-
self, num_rows, flags, time, population, individual, metadata, metadata_offset);
1885-
out:
1886-
return ret;
1887-
}
1888-
18891895
int
18901896
tsk_node_table_append_columns(tsk_node_table_t *self, tsk_size_t num_rows,
18911897
const tsk_flags_t *flags, const double *time, const tsk_id_t *population,

0 commit comments

Comments
 (0)