From 12ef6eaab287cb5a434d6318d685cd49f754726b Mon Sep 17 00:00:00 2001 From: Ben Jeffery Date: Fri, 12 Nov 2021 13:15:05 +0000 Subject: [PATCH 1/2] WIP --- c/tests/test_tables.c | 121 +++++++++++++++++++++++++ c/tskit/tables.c | 206 ++++++++++++++++++++++++++++++++++++++++++ c/tskit/tables.h | 23 +++++ 3 files changed, 350 insertions(+) diff --git a/c/tests/test_tables.c b/c/tests/test_tables.c index 9463d650c3..bb6445c9ab 100644 --- a/c/tests/test_tables.c +++ b/c/tests/test_tables.c @@ -324,6 +324,125 @@ test_table_collection_simplify_errors(void) tsk_table_collection_free(&tables); } +static void +test_table_collection_reference_sequence(void) +{ + int ret; + tsk_table_collection_t tc1, tc2; + + char example_data[100] = "An example string with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_data_length = (tsk_size_t) strlen(example_data); + char example_url[100] = "An example url with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_url_length = (tsk_size_t) strlen(example_url); + char example_metadata[100] = "An example metadata with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_metadata_length = (tsk_size_t) strlen(example_metadata); + char example_schema[100] = "An example schema with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_schema_length = (tsk_size_t) strlen(example_schema); + + // Test equality + ret = tsk_table_collection_init(&tc1, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_init(&tc2, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_data( + &tc1.reference_sequence, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); + ret = tsk_reference_sequence_set_data( + &tc2.reference_sequence, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_url( + &tc1.reference_sequence, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); + ret = tsk_reference_sequence_set_url( + &tc2.reference_sequence, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_metadata( + &tc1.reference_sequence, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); + ret = tsk_reference_sequence_set_metadata( + &tc2.reference_sequence, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_metadata_schema( + &tc1.reference_sequence, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); + ret = tsk_reference_sequence_set_metadata_schema( + &tc2.reference_sequence, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + // Test copy + tsk_table_collection_free(&tc1); + tsk_table_collection_free(&tc2); + ret = tsk_table_collection_init(&tc1, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + + ret = tsk_reference_sequence_set_data( + &tc1.reference_sequence, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_copy(&tc1, &tc2, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_url( + &tc1.reference_sequence, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_copy(&tc1, &tc2, TSK_NO_INIT); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_metadata( + &tc1.reference_sequence, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_copy(&tc1, &tc2, TSK_NO_INIT); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + ret = tsk_reference_sequence_set_metadata_schema( + &tc1.reference_sequence, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_copy(&tc1, &tc2, TSK_NO_INIT); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + // Test dump and load + tsk_table_collection_free(&tc1); + tsk_table_collection_free(&tc2); + ret = tsk_table_collection_init(&tc1, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + tc1.sequence_length = 1.0; + ret = tsk_reference_sequence_set_data( + &tc1.reference_sequence, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_set_url( + &tc1.reference_sequence, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_set_metadata( + &tc1.reference_sequence, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_set_metadata_schema( + &tc1.reference_sequence, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_dump(&tc1, _tmp_file_name, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_table_collection_load(&tc2, _tmp_file_name, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + tsk_table_collection_free(&tc1); + tsk_table_collection_free(&tc2); +} + static void test_table_collection_metadata(void) { @@ -8794,6 +8913,8 @@ main(int argc, char **argv) { "test_table_collection_simplify_errors", test_table_collection_simplify_errors }, { "test_table_collection_time_units", test_table_collection_time_units }, + { "test_table_collection_reference_sequence", + test_table_collection_reference_sequence }, { "test_table_collection_metadata", test_table_collection_metadata }, { "test_simplify_tables_drops_indexes", test_simplify_tables_drops_indexes }, { "test_simplify_empty_tables", test_simplify_empty_tables }, diff --git a/c/tskit/tables.c b/c/tskit/tables.c index f63bb1a1b6..9e0aecd3e6 100644 --- a/c/tskit/tables.c +++ b/c/tskit/tables.c @@ -626,6 +626,16 @@ write_metadata_schema_header( return fprintf(out, fmt, (int) metadata_schema_length, metadata_schema); } +static int +tsk_reference_sequence_free(tsk_reference_sequence_t *self) +{ + tsk_safe_free(self->data); + tsk_safe_free(self->url); + tsk_safe_free(self->metadata); + tsk_safe_free(self->metadata_schema); + return 0; +} + /************************* * individual table *************************/ @@ -9827,6 +9837,7 @@ tsk_table_collection_free(tsk_table_collection_t *self) tsk_mutation_table_free(&self->mutations); tsk_population_table_free(&self->populations); tsk_provenance_table_free(&self->provenances); + tsk_reference_sequence_free(&self->reference_sequence); tsk_safe_free(self->indexes.edge_insertion_order); tsk_safe_free(self->indexes.edge_removal_order); tsk_safe_free(self->file_uuid); @@ -9876,6 +9887,31 @@ tsk_table_collection_equals(const tsk_table_collection_t *self, && tsk_provenance_table_equals( &self->provenances, &other->provenances, options); } + ret = ret + && self->reference_sequence.url_length == other->reference_sequence.url_length + && tsk_memcmp(self->reference_sequence.url, other->reference_sequence.url, + self->reference_sequence.url_length * sizeof(char)) + == 0; + // TODO Ignore flags + ret = ret + && self->reference_sequence.data_length + == other->reference_sequence.data_length + && tsk_memcmp(self->reference_sequence.data, other->reference_sequence.data, + self->reference_sequence.data_length * sizeof(char)) + == 0; + ret = ret + && (self->reference_sequence.metadata_length + == other->reference_sequence.metadata_length + && self->reference_sequence.metadata_schema_length + == other->reference_sequence.metadata_schema_length + && tsk_memcmp(self->reference_sequence.metadata, + other->reference_sequence.metadata, + self->reference_sequence.metadata_length * sizeof(char)) + == 0 + && tsk_memcmp(self->reference_sequence.metadata_schema, + other->reference_sequence.metadata_schema, + self->reference_sequence.metadata_schema_length * sizeof(char)) + == 0); return ret; } @@ -9903,6 +9939,40 @@ tsk_table_collection_set_metadata_schema(tsk_table_collection_t *self, metadata_schema, metadata_schema_length); } +int +tsk_reference_sequence_set_data(tsk_reference_sequence_t *self, + const char *reference_sequence, tsk_size_t reference_sequence_length) +{ + return replace_string( + &self->data, &self->data_length, reference_sequence, reference_sequence_length); +} + +int +tsk_reference_sequence_set_url(tsk_reference_sequence_t *self, + const char *reference_sequence_url, tsk_size_t reference_sequence_url_length) +{ + return replace_string(&self->url, &self->url_length, reference_sequence_url, + reference_sequence_url_length); +} + +int +tsk_reference_sequence_set_metadata(tsk_reference_sequence_t *self, + const char *reference_sequence_metadata, + tsk_size_t reference_sequence_metadata_length) +{ + return replace_string(&self->metadata, &self->metadata_length, + reference_sequence_metadata, reference_sequence_metadata_length); +} + +int +tsk_reference_sequence_set_metadata_schema(tsk_reference_sequence_t *self, + const char *reference_sequence_metadata_schema, + tsk_size_t reference_sequence_metadata_schema_length) +{ + return replace_string(&self->metadata_schema, &self->metadata_schema_length, + reference_sequence_metadata_schema, reference_sequence_metadata_schema_length); +} + int tsk_table_collection_set_indexes(tsk_table_collection_t *self, tsk_id_t *edge_insertion_order, tsk_id_t *edge_removal_order) @@ -10081,6 +10151,29 @@ tsk_table_collection_copy(const tsk_table_collection_t *self, goto out; } + // TODO separate func + ret = tsk_reference_sequence_set_data(&dest->reference_sequence, + self->reference_sequence.data, self->reference_sequence.data_length); + if (ret != 0) { + goto out; + } + ret = tsk_reference_sequence_set_url(&dest->reference_sequence, + self->reference_sequence.url, self->reference_sequence.url_length); + if (ret != 0) { + goto out; + } + ret = tsk_reference_sequence_set_metadata(&dest->reference_sequence, + self->reference_sequence.metadata, self->reference_sequence.metadata_length); + if (ret != 0) { + goto out; + } + ret = tsk_reference_sequence_set_metadata_schema(&dest->reference_sequence, + self->reference_sequence.metadata_schema, + self->reference_sequence.metadata_schema_length); + if (ret != 0) { + goto out; + } + out: return ret; } @@ -10295,6 +10388,95 @@ tsk_table_collection_load_indexes(tsk_table_collection_t *self, kastore_t *store return ret; } +static int +tsk_reference_sequence_load(tsk_reference_sequence_t *self, kastore_t *store) +{ + int ret = 0; + char *data = NULL; + char *url = NULL; + char *metadata = NULL; + char *metadata_schema = NULL; + tsk_size_t data_length, url_length, metadata_length, metadata_schema_length; + + // TODO - should be a loop + ret = kastore_containss(store, "reference_sequence/data"); + if (ret < 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + if (ret == 1) { + ret = kastore_gets_int8( + store, "reference_sequence/data", (int8_t **) &data, &data_length); + if (ret != 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + ret = tsk_reference_sequence_set_data(self, data, (tsk_size_t) data_length); + if (ret != 0) { + goto out; + } + } + + ret = kastore_containss(store, "reference_sequence/metadata"); + if (ret < 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + if (ret == 1) { + ret = kastore_gets_int8(store, "reference_sequence/metadata", + (int8_t **) &metadata, &metadata_length); + if (ret != 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + ret = tsk_reference_sequence_set_metadata( + self, metadata, (tsk_size_t) metadata_length); + if (ret != 0) { + goto out; + } + } + + ret = kastore_containss(store, "reference_sequence/metadata_schema"); + if (ret < 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + if (ret == 1) { + ret = kastore_gets_int8(store, "reference_sequence/metadata_schema", + (int8_t **) &metadata_schema, &metadata_schema_length); + if (ret != 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + ret = tsk_reference_sequence_set_metadata_schema( + self, metadata_schema, (tsk_size_t) metadata_schema_length); + if (ret != 0) { + goto out; + } + } + + ret = kastore_containss(store, "reference_sequence/url"); + if (ret < 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + if (ret == 1) { + ret = kastore_gets_int8( + store, "reference_sequence/url", (int8_t **) &url, &url_length); + if (ret != 0) { + ret = tsk_set_kas_error(ret); + goto out; + } + ret = tsk_reference_sequence_set_url(self, url, (tsk_size_t) url_length); + if (ret != 0) { + goto out; + } + } +out: + + return ret; +} + static int TSK_WARN_UNUSED tsk_table_collection_loadf_inited(tsk_table_collection_t *self, FILE *file) { @@ -10354,6 +10536,10 @@ tsk_table_collection_loadf_inited(tsk_table_collection_t *self, FILE *file) if (ret != 0) { goto out; } + ret = tsk_reference_sequence_load(&self->reference_sequence, &store); + if (ret != 0) { + goto out; + } ret = kastore_close(&store); if (ret != 0) { goto out; @@ -10454,6 +10640,22 @@ tsk_table_collection_write_format_data(const tsk_table_collection_t *self, return ret; } +static int TSK_WARN_UNUSED +tsk_reference_sequence_dump(const tsk_reference_sequence_t *self, kastore_t *store, + tsk_flags_t TSK_UNUSED(options)) +{ + write_table_col_t write_cols[] = { + { "reference_sequence/data", (void *) self->data, self->data_length, KAS_INT8 }, + { "reference_sequence/url", (void *) self->url, self->url_length, KAS_INT8 }, + { "reference_sequence/metadata", (void *) self->metadata, self->metadata_length, + KAS_INT8 }, + { "reference_sequence/metadata_schema", (void *) self->metadata_schema, + self->metadata_schema_length, KAS_INT8 }, + { .name = NULL }, + }; + return write_table_cols(store, write_cols, 0); +} + int TSK_WARN_UNUSED tsk_table_collection_dump( const tsk_table_collection_t *self, const char *filename, tsk_flags_t options) @@ -10542,6 +10744,10 @@ tsk_table_collection_dumpf( if (ret != 0) { goto out; } + ret = tsk_reference_sequence_dump(&self->reference_sequence, &store, options); + if (ret != 0) { + goto out; + } ret = kastore_close(&store); if (ret != 0) { diff --git a/c/tskit/tables.h b/c/tskit/tables.h index 7235ef71cd..a9a1e0a0be 100644 --- a/c/tskit/tables.h +++ b/c/tskit/tables.h @@ -538,6 +538,17 @@ typedef struct { tsk_size_t *record_offset; } tsk_provenance_table_t; +typedef struct { + char *data; + tsk_size_t data_length; + char *url; + tsk_size_t url_length; + char *metadata; + tsk_size_t metadata_length; + char *metadata_schema; + tsk_size_t metadata_schema_length; +} tsk_reference_sequence_t; + /** @brief A collection of tables defining the data for a tree sequence. */ @@ -554,6 +565,7 @@ typedef struct { /** @brief The metadata schema */ char *metadata_schema; tsk_size_t metadata_schema_length; + tsk_reference_sequence_t reference_sequence; /** @brief The individual table */ tsk_individual_table_t individuals; /** @brief The node table */ @@ -4104,6 +4116,17 @@ int tsk_table_collection_compute_mutation_parents( int tsk_table_collection_compute_mutation_times( tsk_table_collection_t *self, double *random, tsk_flags_t TSK_UNUSED(options)); +int tsk_reference_sequence_set_data(tsk_reference_sequence_t *self, + const char *reference_sequence, tsk_size_t reference_sequence_length); +int tsk_reference_sequence_set_url(tsk_reference_sequence_t *self, + const char *reference_sequence_url, tsk_size_t reference_sequence_url_length); +int tsk_reference_sequence_set_metadata(tsk_reference_sequence_t *self, + const char *reference_sequence_metadata, + tsk_size_t reference_sequence_metadata_length); +int tsk_reference_sequence_set_metadata_schema(tsk_reference_sequence_t *self, + const char *reference_sequence_metadata_schema, + tsk_size_t reference_sequence_metadata_schema_length); + /** @defgroup TABLE_SORTER_API_GROUP Low-level table sorter API. @{ From 5f9f994f4a148abf4b32ad5c5af678e4be79c9e5 Mon Sep 17 00:00:00 2001 From: Ben Jeffery Date: Tue, 16 Nov 2021 14:58:26 +0000 Subject: [PATCH 2/2] Ref seq as pointer --- c/CHANGELOG.rst | 4 +- c/tests/test_tables.c | 163 +++++++++++++++++++-- c/tskit/tables.c | 331 +++++++++++++++++++++++------------------- c/tskit/tables.h | 8 +- 4 files changed, 341 insertions(+), 165 deletions(-) diff --git a/c/CHANGELOG.rst b/c/CHANGELOG.rst index e15bea52c2..61d8d14f6c 100644 --- a/c/CHANGELOG.rst +++ b/c/CHANGELOG.rst @@ -53,9 +53,11 @@ :pr:`1742`). - Add ``time_units`` to ``tsk_table_collection_t`` to describe the units of the time dimension of the - tree sequence. This is then used to generate an error if ``time_units`` is ``uncalibrated`` when + tree sequence. This is then used to geerate an error if ``time_units`` is ``uncalibrated`` when using the branch lengths in statistics. (:user:`benjeffery`, :issue:`1644`, :pr:`1760`) +- Add reference sequence to table collection (:user:`benjeffery`, :issue:`146`, :pr:`1911`) + - FIXME add features for virtual root, num_edges, stack allocation size etc **Fixes** diff --git a/c/tests/test_tables.c b/c/tests/test_tables.c index bb6445c9ab..1c89095f66 100644 --- a/c/tests/test_tables.c +++ b/c/tests/test_tables.c @@ -324,6 +324,117 @@ test_table_collection_simplify_errors(void) tsk_table_collection_free(&tables); } +static void +test_reference_sequence(void) +{ + int ret; + tsk_reference_sequence_t *r1 = NULL; + tsk_reference_sequence_t *r2 = NULL; + + char example_data[100] = "An example string with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_data_length = (tsk_size_t) strlen(example_data); + char example_url[100] = "An example url with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_url_length = (tsk_size_t) strlen(example_url); + char example_metadata[100] = "An example metadata with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_metadata_length = (tsk_size_t) strlen(example_metadata); + char example_schema[100] = "An example schema with unicode 🎄🌳🌴🌲🎋"; + tsk_size_t example_schema_length = (tsk_size_t) strlen(example_schema); + + // Test equality + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + r1 = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(r1, NULL); + tsk_reference_sequence_init(r1); + + ret = tsk_reference_sequence_set_data(r1, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_reference_sequence_equals(r1, r2, 0)); + + r2 = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(r2, NULL); + tsk_reference_sequence_init(r2); + + ret = tsk_reference_sequence_set_data(r1, "", 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_data(r1, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_data(r2, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_url(r1, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_reference_sequence_equals(r1, r2, 0)); + ret = tsk_reference_sequence_set_url(r2, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_metadata( + r1, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_reference_sequence_equals(r1, r2, 0)); + ret = tsk_reference_sequence_set_metadata( + r2, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_metadata_schema( + r1, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_FALSE(tsk_reference_sequence_equals(r1, r2, 0)); + ret = tsk_reference_sequence_set_metadata_schema( + r2, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + // Test copy + tsk_reference_sequence_free(r1); + tsk_safe_free(r1); + r1 = NULL; + tsk_reference_sequence_free(r2); + tsk_safe_free(r2); + r2 = NULL; + + r1 = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(r1, NULL); + tsk_reference_sequence_init(r1); + ret = tsk_reference_sequence_set_data(r1, example_data, example_data_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_copy(r1, &r2, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_url(r1, example_url, example_url_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_copy(r1, &r2, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_metadata( + r1, example_metadata, example_metadata_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_copy(r1, &r2, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + ret = tsk_reference_sequence_set_metadata_schema( + r1, example_schema, example_schema_length); + CU_ASSERT_EQUAL_FATAL(ret, 0); + ret = tsk_reference_sequence_copy(r1, &r2, 0); + CU_ASSERT_EQUAL_FATAL(ret, 0); + CU_ASSERT_TRUE(tsk_reference_sequence_equals(r1, r2, 0)); + + tsk_reference_sequence_free(r1); + tsk_safe_free(r1); + tsk_reference_sequence_free(r2); + tsk_safe_free(r2); +} + static void test_table_collection_reference_sequence(void) { @@ -346,39 +457,48 @@ test_table_collection_reference_sequence(void) CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); + tc1.reference_sequence = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(tc1.reference_sequence, NULL); + tsk_reference_sequence_init(tc1.reference_sequence); + ret = tsk_reference_sequence_set_data( - &tc1.reference_sequence, example_data, example_data_length); + tc1.reference_sequence, example_data, example_data_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); + + tc2.reference_sequence = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(tc2.reference_sequence, NULL); + tsk_reference_sequence_init(tc2.reference_sequence); + ret = tsk_reference_sequence_set_data( - &tc2.reference_sequence, example_data, example_data_length); + tc2.reference_sequence, example_data, example_data_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_url( - &tc1.reference_sequence, example_url, example_url_length); + tc1.reference_sequence, example_url, example_url_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_url( - &tc2.reference_sequence, example_url, example_url_length); + tc2.reference_sequence, example_url, example_url_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_metadata( - &tc1.reference_sequence, example_metadata, example_metadata_length); + tc1.reference_sequence, example_metadata, example_metadata_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_metadata( - &tc2.reference_sequence, example_metadata, example_metadata_length); + tc2.reference_sequence, example_metadata, example_metadata_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_metadata_schema( - &tc1.reference_sequence, example_schema, example_schema_length); + tc1.reference_sequence, example_schema, example_schema_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_FALSE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_metadata_schema( - &tc2.reference_sequence, example_schema, example_schema_length); + tc2.reference_sequence, example_schema, example_schema_length); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); @@ -388,29 +508,33 @@ test_table_collection_reference_sequence(void) ret = tsk_table_collection_init(&tc1, 0); CU_ASSERT_EQUAL_FATAL(ret, 0); + tc1.reference_sequence = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(tc1.reference_sequence, NULL); + tsk_reference_sequence_init(tc1.reference_sequence); + ret = tsk_reference_sequence_set_data( - &tc1.reference_sequence, example_data, example_data_length); + tc1.reference_sequence, example_data, example_data_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_table_collection_copy(&tc1, &tc2, 0); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_url( - &tc1.reference_sequence, example_url, example_url_length); + tc1.reference_sequence, example_url, example_url_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_table_collection_copy(&tc1, &tc2, TSK_NO_INIT); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_metadata( - &tc1.reference_sequence, example_metadata, example_metadata_length); + tc1.reference_sequence, example_metadata, example_metadata_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_table_collection_copy(&tc1, &tc2, TSK_NO_INIT); CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_TRUE(tsk_table_collection_equals(&tc1, &tc2, 0)); ret = tsk_reference_sequence_set_metadata_schema( - &tc1.reference_sequence, example_schema, example_schema_length); + tc1.reference_sequence, example_schema, example_schema_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_table_collection_copy(&tc1, &tc2, TSK_NO_INIT); CU_ASSERT_EQUAL_FATAL(ret, 0); @@ -422,17 +546,22 @@ test_table_collection_reference_sequence(void) ret = tsk_table_collection_init(&tc1, 0); CU_ASSERT_EQUAL_FATAL(ret, 0); tc1.sequence_length = 1.0; + + tc1.reference_sequence = tsk_malloc(sizeof(tsk_reference_sequence_t)); + CU_ASSERT_NOT_EQUAL_FATAL(tc1.reference_sequence, NULL); + tsk_reference_sequence_init(tc1.reference_sequence); + ret = tsk_reference_sequence_set_data( - &tc1.reference_sequence, example_data, example_data_length); + tc1.reference_sequence, example_data, example_data_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_reference_sequence_set_url( - &tc1.reference_sequence, example_url, example_url_length); + tc1.reference_sequence, example_url, example_url_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_reference_sequence_set_metadata( - &tc1.reference_sequence, example_metadata, example_metadata_length); + tc1.reference_sequence, example_metadata, example_metadata_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_reference_sequence_set_metadata_schema( - &tc1.reference_sequence, example_schema, example_schema_length); + tc1.reference_sequence, example_schema, example_schema_length); CU_ASSERT_EQUAL_FATAL(ret, 0); ret = tsk_table_collection_dump(&tc1, _tmp_file_name, 0); CU_ASSERT_EQUAL_FATAL(ret, 0); @@ -8916,6 +9045,8 @@ main(int argc, char **argv) { "test_table_collection_reference_sequence", test_table_collection_reference_sequence }, { "test_table_collection_metadata", test_table_collection_metadata }, + { "test_reference_sequence", test_reference_sequence }, + { "test_simplify_tables_drops_indexes", test_simplify_tables_drops_indexes }, { "test_simplify_empty_tables", test_simplify_empty_tables }, { "test_simplify_metadata", test_simplify_metadata }, diff --git a/c/tskit/tables.c b/c/tskit/tables.c index 9e0aecd3e6..8ce23d7823 100644 --- a/c/tskit/tables.c +++ b/c/tskit/tables.c @@ -626,7 +626,18 @@ write_metadata_schema_header( return fprintf(out, fmt, (int) metadata_schema_length, metadata_schema); } -static int +/************************* + * reference sequence + *************************/ + +int +tsk_reference_sequence_init(tsk_reference_sequence_t *self) +{ + tsk_memset(self, 0, sizeof(*self)); + return 0; +} + +int tsk_reference_sequence_free(tsk_reference_sequence_t *self) { tsk_safe_free(self->data); @@ -636,6 +647,112 @@ tsk_reference_sequence_free(tsk_reference_sequence_t *self) return 0; } +bool +tsk_reference_sequence_equals(const tsk_reference_sequence_t *self, + const tsk_reference_sequence_t *other, tsk_flags_t options) +{ + if (self == NULL && other == NULL) { + return true; + } + /* If one or the other is NULL they are not equal */ + if ((self == NULL) != (other == NULL)) { + return false; + } + return ( + (self->data_length == other->data_length && self->url_length == other->url_length + && ((options & TSK_CMP_IGNORE_TS_METADATA) + || self->metadata_length == other->metadata_length) + && ((options & TSK_CMP_IGNORE_TS_METADATA) + || self->metadata_schema_length == other->metadata_schema_length) + && tsk_memcmp(self->data, other->data, self->data_length * sizeof(char)) == 0 + && tsk_memcmp(self->url, other->url, self->url_length * sizeof(char)) == 0 + && ((options & TSK_CMP_IGNORE_TS_METADATA) + || tsk_memcmp(self->metadata, other->metadata, + self->metadata_length * sizeof(char)) + == 0) + && ((options & TSK_CMP_IGNORE_TS_METADATA) + || tsk_memcmp(self->metadata_schema, other->metadata_schema, + self->metadata_schema_length * sizeof(char)) + == 0))); +} + +int +tsk_reference_sequence_copy(const tsk_reference_sequence_t *self, + tsk_reference_sequence_t **dest, tsk_flags_t TSK_UNUSED(options)) +{ + int ret = 0; + + if (*dest != NULL) { + tsk_reference_sequence_free(*dest); + tsk_safe_free(*dest); + *dest = NULL; + } + + if (self != NULL) { + *dest = tsk_malloc(sizeof(tsk_reference_sequence_t)); + if (*dest == NULL) { + ret = TSK_ERR_NO_MEMORY; + goto out; + } + tsk_reference_sequence_init(*dest); + + ret = tsk_reference_sequence_set_data(*dest, self->data, self->data_length); + if (ret != 0) { + goto out; + } + ret = tsk_reference_sequence_set_url(*dest, self->url, self->url_length); + if (ret != 0) { + goto out; + } + ret = tsk_reference_sequence_set_metadata( + *dest, self->metadata, self->metadata_length); + if (ret != 0) { + goto out; + } + ret = tsk_reference_sequence_set_metadata_schema( + *dest, self->metadata_schema, self->metadata_schema_length); + if (ret != 0) { + goto out; + } + } +out: + return ret; +} + +int +tsk_reference_sequence_set_data(tsk_reference_sequence_t *self, + const char *reference_sequence, tsk_size_t reference_sequence_length) +{ + return replace_string( + &self->data, &self->data_length, reference_sequence, reference_sequence_length); +} + +int +tsk_reference_sequence_set_url(tsk_reference_sequence_t *self, + const char *reference_sequence_url, tsk_size_t reference_sequence_url_length) +{ + return replace_string(&self->url, &self->url_length, reference_sequence_url, + reference_sequence_url_length); +} + +int +tsk_reference_sequence_set_metadata(tsk_reference_sequence_t *self, + const char *reference_sequence_metadata, + tsk_size_t reference_sequence_metadata_length) +{ + return replace_string(&self->metadata, &self->metadata_length, + reference_sequence_metadata, reference_sequence_metadata_length); +} + +int +tsk_reference_sequence_set_metadata_schema(tsk_reference_sequence_t *self, + const char *reference_sequence_metadata_schema, + tsk_size_t reference_sequence_metadata_schema_length) +{ + return replace_string(&self->metadata_schema, &self->metadata_schema_length, + reference_sequence_metadata_schema, reference_sequence_metadata_schema_length); +} + /************************* * individual table *************************/ @@ -9837,7 +9954,10 @@ tsk_table_collection_free(tsk_table_collection_t *self) tsk_mutation_table_free(&self->mutations); tsk_population_table_free(&self->populations); tsk_provenance_table_free(&self->provenances); - tsk_reference_sequence_free(&self->reference_sequence); + if (self->reference_sequence != NULL) { + tsk_reference_sequence_free(self->reference_sequence); + } + tsk_safe_free(self->reference_sequence); tsk_safe_free(self->indexes.edge_insertion_order); tsk_safe_free(self->indexes.edge_removal_order); tsk_safe_free(self->file_uuid); @@ -9887,31 +10007,10 @@ tsk_table_collection_equals(const tsk_table_collection_t *self, && tsk_provenance_table_equals( &self->provenances, &other->provenances, options); } + ret = ret - && self->reference_sequence.url_length == other->reference_sequence.url_length - && tsk_memcmp(self->reference_sequence.url, other->reference_sequence.url, - self->reference_sequence.url_length * sizeof(char)) - == 0; - // TODO Ignore flags - ret = ret - && self->reference_sequence.data_length - == other->reference_sequence.data_length - && tsk_memcmp(self->reference_sequence.data, other->reference_sequence.data, - self->reference_sequence.data_length * sizeof(char)) - == 0; - ret = ret - && (self->reference_sequence.metadata_length - == other->reference_sequence.metadata_length - && self->reference_sequence.metadata_schema_length - == other->reference_sequence.metadata_schema_length - && tsk_memcmp(self->reference_sequence.metadata, - other->reference_sequence.metadata, - self->reference_sequence.metadata_length * sizeof(char)) - == 0 - && tsk_memcmp(self->reference_sequence.metadata_schema, - other->reference_sequence.metadata_schema, - self->reference_sequence.metadata_schema_length * sizeof(char)) - == 0); + && tsk_reference_sequence_equals( + self->reference_sequence, other->reference_sequence, options); return ret; } @@ -9939,40 +10038,6 @@ tsk_table_collection_set_metadata_schema(tsk_table_collection_t *self, metadata_schema, metadata_schema_length); } -int -tsk_reference_sequence_set_data(tsk_reference_sequence_t *self, - const char *reference_sequence, tsk_size_t reference_sequence_length) -{ - return replace_string( - &self->data, &self->data_length, reference_sequence, reference_sequence_length); -} - -int -tsk_reference_sequence_set_url(tsk_reference_sequence_t *self, - const char *reference_sequence_url, tsk_size_t reference_sequence_url_length) -{ - return replace_string(&self->url, &self->url_length, reference_sequence_url, - reference_sequence_url_length); -} - -int -tsk_reference_sequence_set_metadata(tsk_reference_sequence_t *self, - const char *reference_sequence_metadata, - tsk_size_t reference_sequence_metadata_length) -{ - return replace_string(&self->metadata, &self->metadata_length, - reference_sequence_metadata, reference_sequence_metadata_length); -} - -int -tsk_reference_sequence_set_metadata_schema(tsk_reference_sequence_t *self, - const char *reference_sequence_metadata_schema, - tsk_size_t reference_sequence_metadata_schema_length) -{ - return replace_string(&self->metadata_schema, &self->metadata_schema_length, - reference_sequence_metadata_schema, reference_sequence_metadata_schema_length); -} - int tsk_table_collection_set_indexes(tsk_table_collection_t *self, tsk_id_t *edge_insertion_order, tsk_id_t *edge_removal_order) @@ -10150,26 +10215,8 @@ tsk_table_collection_copy(const tsk_table_collection_t *self, if (ret != 0) { goto out; } - - // TODO separate func - ret = tsk_reference_sequence_set_data(&dest->reference_sequence, - self->reference_sequence.data, self->reference_sequence.data_length); - if (ret != 0) { - goto out; - } - ret = tsk_reference_sequence_set_url(&dest->reference_sequence, - self->reference_sequence.url, self->reference_sequence.url_length); - if (ret != 0) { - goto out; - } - ret = tsk_reference_sequence_set_metadata(&dest->reference_sequence, - self->reference_sequence.metadata, self->reference_sequence.metadata_length); - if (ret != 0) { - goto out; - } - ret = tsk_reference_sequence_set_metadata_schema(&dest->reference_sequence, - self->reference_sequence.metadata_schema, - self->reference_sequence.metadata_schema_length); + ret = tsk_reference_sequence_copy( + self->reference_sequence, &dest->reference_sequence, options); if (ret != 0) { goto out; } @@ -10389,89 +10436,76 @@ tsk_table_collection_load_indexes(tsk_table_collection_t *self, kastore_t *store } static int -tsk_reference_sequence_load(tsk_reference_sequence_t *self, kastore_t *store) +tsk_table_collection_load_reference_sequence( + tsk_table_collection_t *self, kastore_t *store) { int ret = 0; char *data = NULL; char *url = NULL; char *metadata = NULL; char *metadata_schema = NULL; - tsk_size_t data_length, url_length, metadata_length, metadata_schema_length; + tsk_size_t data_length = 0, url_length, metadata_length, metadata_schema_length; + bool reference_sequence_loaded; - // TODO - should be a loop - ret = kastore_containss(store, "reference_sequence/data"); - if (ret < 0) { - ret = tsk_set_kas_error(ret); + read_table_property_t properties[] = { + { "reference_sequence/data", (void **) &data, &data_length, KAS_UINT8, + TSK_COL_OPTIONAL }, + { "reference_sequence/url", (void **) &url, &url_length, KAS_UINT8, + TSK_COL_OPTIONAL }, + { "reference_sequence/metadata", (void **) &metadata, &metadata_length, + KAS_UINT8, TSK_COL_OPTIONAL }, + { "reference_sequence/metadata_schema", (void **) &metadata_schema, + &metadata_schema_length, KAS_UINT8, TSK_COL_OPTIONAL }, + { .name = NULL }, + }; + + ret = read_table_properties(store, properties, 0); + if (ret != 0) { goto out; } - if (ret == 1) { - ret = kastore_gets_int8( - store, "reference_sequence/data", (int8_t **) &data, &data_length); - if (ret != 0) { - ret = tsk_set_kas_error(ret); - goto out; - } - ret = tsk_reference_sequence_set_data(self, data, (tsk_size_t) data_length); - if (ret != 0) { + reference_sequence_loaded + = data != NULL || url != NULL || metadata != NULL || metadata_schema != NULL; + if (self->reference_sequence != NULL) { + tsk_reference_sequence_free(self->reference_sequence); + tsk_safe_free(self->reference_sequence); + } + if (reference_sequence_loaded) { + self->reference_sequence = tsk_malloc(sizeof(tsk_reference_sequence_t)); + if (self->reference_sequence == NULL) { + ret = TSK_ERR_NO_MEMORY; goto out; } + tsk_reference_sequence_init(self->reference_sequence); } - - ret = kastore_containss(store, "reference_sequence/metadata"); - if (ret < 0) { - ret = tsk_set_kas_error(ret); - goto out; - } - if (ret == 1) { - ret = kastore_gets_int8(store, "reference_sequence/metadata", - (int8_t **) &metadata, &metadata_length); + if (data != NULL) { + ret = tsk_reference_sequence_set_data( + self->reference_sequence, data, (tsk_size_t) data_length); if (ret != 0) { - ret = tsk_set_kas_error(ret); goto out; } + } + if (metadata != NULL) { ret = tsk_reference_sequence_set_metadata( - self, metadata, (tsk_size_t) metadata_length); + self->reference_sequence, metadata, (tsk_size_t) metadata_length); if (ret != 0) { goto out; } } - - ret = kastore_containss(store, "reference_sequence/metadata_schema"); - if (ret < 0) { - ret = tsk_set_kas_error(ret); - goto out; - } - if (ret == 1) { - ret = kastore_gets_int8(store, "reference_sequence/metadata_schema", - (int8_t **) &metadata_schema, &metadata_schema_length); - if (ret != 0) { - ret = tsk_set_kas_error(ret); - goto out; - } - ret = tsk_reference_sequence_set_metadata_schema( - self, metadata_schema, (tsk_size_t) metadata_schema_length); + if (metadata_schema != NULL) { + ret = tsk_reference_sequence_set_metadata_schema(self->reference_sequence, + metadata_schema, (tsk_size_t) metadata_schema_length); if (ret != 0) { goto out; } } - - ret = kastore_containss(store, "reference_sequence/url"); - if (ret < 0) { - ret = tsk_set_kas_error(ret); - goto out; - } - if (ret == 1) { - ret = kastore_gets_int8( - store, "reference_sequence/url", (int8_t **) &url, &url_length); - if (ret != 0) { - ret = tsk_set_kas_error(ret); - goto out; - } - ret = tsk_reference_sequence_set_url(self, url, (tsk_size_t) url_length); + if (url != NULL) { + ret = tsk_reference_sequence_set_url( + self->reference_sequence, url, (tsk_size_t) url_length); if (ret != 0) { goto out; } } + out: return ret; @@ -10536,7 +10570,7 @@ tsk_table_collection_loadf_inited(tsk_table_collection_t *self, FILE *file) if (ret != 0) { goto out; } - ret = tsk_reference_sequence_load(&self->reference_sequence, &store); + ret = tsk_table_collection_load_reference_sequence(self, &store); if (ret != 0) { goto out; } @@ -10641,16 +10675,17 @@ tsk_table_collection_write_format_data(const tsk_table_collection_t *self, } static int TSK_WARN_UNUSED -tsk_reference_sequence_dump(const tsk_reference_sequence_t *self, kastore_t *store, - tsk_flags_t TSK_UNUSED(options)) +tsk_table_collection_reference_sequence_dump(const tsk_table_collection_t *self, + kastore_t *store, tsk_flags_t TSK_UNUSED(options)) { + const tsk_reference_sequence_t *ref = self->reference_sequence; write_table_col_t write_cols[] = { - { "reference_sequence/data", (void *) self->data, self->data_length, KAS_INT8 }, - { "reference_sequence/url", (void *) self->url, self->url_length, KAS_INT8 }, - { "reference_sequence/metadata", (void *) self->metadata, self->metadata_length, - KAS_INT8 }, - { "reference_sequence/metadata_schema", (void *) self->metadata_schema, - self->metadata_schema_length, KAS_INT8 }, + { "reference_sequence/data", (void *) ref->data, ref->data_length, KAS_UINT8 }, + { "reference_sequence/url", (void *) ref->url, ref->url_length, KAS_UINT8 }, + { "reference_sequence/metadata", (void *) ref->metadata, ref->metadata_length, + KAS_UINT8 }, + { "reference_sequence/metadata_schema", (void *) ref->metadata_schema, + ref->metadata_schema_length, KAS_UINT8 }, { .name = NULL }, }; return write_table_cols(store, write_cols, 0); @@ -10744,9 +10779,11 @@ tsk_table_collection_dumpf( if (ret != 0) { goto out; } - ret = tsk_reference_sequence_dump(&self->reference_sequence, &store, options); - if (ret != 0) { - goto out; + if (self->reference_sequence != NULL) { + ret = tsk_table_collection_reference_sequence_dump(self, &store, options); + if (ret != 0) { + goto out; + } } ret = kastore_close(&store); diff --git a/c/tskit/tables.h b/c/tskit/tables.h index a9a1e0a0be..79ba0b0cff 100644 --- a/c/tskit/tables.h +++ b/c/tskit/tables.h @@ -565,7 +565,7 @@ typedef struct { /** @brief The metadata schema */ char *metadata_schema; tsk_size_t metadata_schema_length; - tsk_reference_sequence_t reference_sequence; + tsk_reference_sequence_t *reference_sequence; /** @brief The individual table */ tsk_individual_table_t individuals; /** @brief The node table */ @@ -4116,6 +4116,12 @@ int tsk_table_collection_compute_mutation_parents( int tsk_table_collection_compute_mutation_times( tsk_table_collection_t *self, double *random, tsk_flags_t TSK_UNUSED(options)); +int tsk_reference_sequence_init(tsk_reference_sequence_t *self); +int tsk_reference_sequence_free(tsk_reference_sequence_t *self); +bool tsk_reference_sequence_equals(const tsk_reference_sequence_t *self, + const tsk_reference_sequence_t *other, tsk_flags_t options); +int tsk_reference_sequence_copy(const tsk_reference_sequence_t *self, + tsk_reference_sequence_t **dest, tsk_flags_t options); int tsk_reference_sequence_set_data(tsk_reference_sequence_t *self, const char *reference_sequence, tsk_size_t reference_sequence_length); int tsk_reference_sequence_set_url(tsk_reference_sequence_t *self,