Skip to content

Commit 31c47e4

Browse files
Basic delete_rows operation for node table
1 parent 4a93c49 commit 31c47e4

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

c/tests/test_tables.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,64 @@ test_node_table_update_row(void)
14901490
tsk_node_table_free(&table);
14911491
}
14921492

1493+
static void
1494+
test_node_table_delete_rows(void)
1495+
{
1496+
int ret;
1497+
tsk_id_t ret_id;
1498+
tsk_node_table_t table;
1499+
tsk_node_table_t copy;
1500+
tsk_node_t row;
1501+
bool delete[3] = { 0, 0, 0 };
1502+
tsk_id_t id_map[3];
1503+
const char *metadata = "ABC";
1504+
1505+
ret = tsk_node_table_init(&table, 0);
1506+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1507+
1508+
ret_id = tsk_node_table_add_row(&table, 0, 1.0, 2, 3, metadata, 1);
1509+
CU_ASSERT_FATAL(ret_id >= 0);
1510+
ret_id = tsk_node_table_add_row(&table, 1, 2.0, 3, 4, metadata, 2);
1511+
CU_ASSERT_FATAL(ret_id >= 0);
1512+
ret_id = tsk_node_table_add_row(&table, 2, 3.0, 4, 5, metadata, 3);
1513+
CU_ASSERT_FATAL(ret_id >= 0);
1514+
1515+
ret = tsk_node_table_copy(&table, &copy, 0);
1516+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1517+
1518+
ret = tsk_node_table_delete_rows(&copy, delete, 0, id_map);
1519+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1520+
CU_ASSERT_TRUE(tsk_node_table_equals(&copy, &table, 0));
1521+
1522+
delete[0] = 1;
1523+
delete[1] = 1;
1524+
delete[2] = 1;
1525+
ret = tsk_node_table_delete_rows(&copy, delete, 0, id_map);
1526+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1527+
CU_ASSERT_EQUAL_FATAL(copy.num_rows, 0);
1528+
1529+
ret = tsk_node_table_copy(&table, &copy, TSK_NO_INIT);
1530+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1531+
delete[0] = 1;
1532+
delete[1] = 0;
1533+
delete[2] = 1;
1534+
ret = tsk_node_table_delete_rows(&copy, delete, 0, id_map);
1535+
CU_ASSERT_EQUAL_FATAL(ret, 0);
1536+
CU_ASSERT_EQUAL_FATAL(copy.num_rows, 1);
1537+
1538+
ret = tsk_node_table_get_row(&copy, 0, &row);
1539+
CU_ASSERT_EQUAL_FATAL(row.flags, 1);
1540+
CU_ASSERT_EQUAL_FATAL(row.time, 2.0);
1541+
CU_ASSERT_EQUAL_FATAL(row.population, 3);
1542+
CU_ASSERT_EQUAL_FATAL(row.individual, 4);
1543+
CU_ASSERT_EQUAL_FATAL(row.metadata_length, 2);
1544+
CU_ASSERT_EQUAL_FATAL(row.metadata[0], 'A');
1545+
CU_ASSERT_EQUAL_FATAL(row.metadata[1], 'B');
1546+
1547+
tsk_node_table_free(&copy);
1548+
tsk_node_table_free(&table);
1549+
}
1550+
14931551
static void
14941552
test_edge_table_with_options(tsk_flags_t options)
14951553
{
@@ -10426,6 +10484,7 @@ main(int argc, char **argv)
1042610484
CU_TestInfo tests[] = {
1042710485
{ "test_node_table", test_node_table },
1042810486
{ "test_node_table_update_row", test_node_table_update_row },
10487+
{ "test_node_table_delete_rows", test_node_table_delete_rows },
1042910488
{ "test_node_table_takeset", test_node_table_takeset },
1043010489
{ "test_edge_table", test_edge_table },
1043110490
{ "test_edge_table_update_row", test_edge_table_update_row },

c/tskit/tables.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,6 +2271,46 @@ tsk_node_table_get_row(const tsk_node_table_t *self, tsk_id_t index, tsk_node_t
22712271
return ret;
22722272
}
22732273

2274+
int
2275+
tsk_node_table_delete_rows(tsk_node_table_t *self, bool *delete_rows,
2276+
tsk_flags_t TSK_UNUSED(options), tsk_id_t *id_map)
2277+
{
2278+
int ret;
2279+
tsk_node_table_t copy;
2280+
tsk_node_t node;
2281+
tsk_size_t j;
2282+
tsk_id_t ret_id;
2283+
2284+
ret = tsk_node_table_copy(self, &copy, 0);
2285+
if (ret != 0) {
2286+
goto out;
2287+
}
2288+
ret = tsk_node_table_clear(self);
2289+
if (ret != 0) {
2290+
goto out;
2291+
}
2292+
for (j = 0; j < copy.num_rows; j++) {
2293+
if (id_map != NULL) {
2294+
id_map[j] = TSK_NULL;
2295+
}
2296+
if (!delete_rows[j]) {
2297+
tsk_node_table_get_row_unsafe(&copy, (tsk_id_t) j, &node);
2298+
ret_id = tsk_node_table_add_row(self, node.flags, node.time, node.population,
2299+
node.individual, node.metadata, node.metadata_length);
2300+
if (ret_id < 0) {
2301+
ret = (int) ret_id;
2302+
goto out;
2303+
}
2304+
if (id_map != NULL) {
2305+
id_map[j] = ret_id;
2306+
}
2307+
}
2308+
}
2309+
out:
2310+
tsk_node_table_free(&copy);
2311+
return ret;
2312+
}
2313+
22742314
static int
22752315
tsk_node_table_dump(const tsk_node_table_t *self, kastore_t *store, tsk_flags_t options)
22762316
{

c/tskit/tables.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,35 @@ and is not checked for compatibility with any existing schema on this table.
13891389
int tsk_node_table_extend(tsk_node_table_t *self, const tsk_node_table_t *other,
13901390
tsk_size_t num_rows, const tsk_id_t *row_indexes, tsk_flags_t options);
13911391

1392+
/**
1393+
@brief Deletes rows specified by a boolean array.
1394+
1395+
@rst
1396+
Deletes rows from this table and (optionally) return the mapping from IDs
1397+
in the current table to the updated table. The rows to delete are specified
1398+
by a boolean array, such that for each row ``j`` if ``delete_rows[j]`` is
1399+
true (or more generally non-zero), then row ``j`` will be removed.
1400+
1401+
If the ``id_map`` argument is non-null, this array will be updated
1402+
to represent the mapping between IDs before and after row deletion.
1403+
For row ``j``, ``id_map[j]`` will contain the new ID for row ``j``
1404+
if it is retained, or :c:macro:`TSK_NULL` if the row has been removed.
1405+
Thus, ``id_map`` must be an array of at least ``num_rows`` :c:type:`tsk_id_t`
1406+
values.
1407+
@endrst
1408+
1409+
@param self A pointer to a tsk_node_table_t object.
1410+
@param delete_rows Array of boolean flags describing whether a particular
1411+
row should be deleted or not. Must be at least ``num_rows`` long.
1412+
@param options Bitwise option flags. Currently unused; should be
1413+
set to zero to ensure compatibility with later versions of tskit.
1414+
@param id_map An array in which to store the mapping between new
1415+
and old IDs. If NULL, this will be ignored.
1416+
@return Return 0 on success or a negative value on failure.
1417+
*/
1418+
int tsk_node_table_delete_rows(
1419+
tsk_node_table_t *self, bool *delete_rows, tsk_flags_t options, tsk_id_t *id_map);
1420+
13921421
/**
13931422
@brief Returns true if the data in the specified table is identical to the data
13941423
in this table.

0 commit comments

Comments
 (0)