Skip to content

Commit 5524ccc

Browse files
committed
Simplify the pointer code #37
1 parent 878d539 commit 5524ccc

5 files changed

Lines changed: 38 additions & 42 deletions

File tree

tskitr/notes_pkg_dev.Rmd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* TODO: Rename ts_load() to ts_load_ptr() and create ts_load() returning S3/S4/R6 object #22
66
https://github.com/HighlanderLab/tskitr/issues/22
77

8+
I guess we should create a minimal S4 class and a minimal R6 class
9+
and then try to load a tree sequence and grow it further and
10+
time the performance with each class.
11+
812
## Setup
913

1014
```

tskitr/src/Makevars.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ PKG_CPPFLAGS = \
4141

4242
# Compiler flags
4343
PKG_CFLAGS = -DNDEBUG # to remove calls to assert() as per the R extensions manual
44-
# PKG_CFLAGS = -DNDEBUG -DTSK_TRACE_ERRORS
44+
# PKG_CFLAGS = -DNDEBUG -DTSK_TRACE_ERRORS # to also enable error tracing in tskit C
4545
# TODO: Should we port any flags from extern/tskit/c/meson.build to R build system? #6
4646
# https://github.com/HighlanderLab/tskitr/issues/6
4747
# See default flags used by clang (see below output from devtools::install())
4848
# clang -arch arm64 -I../inst/include -I../inst/include/tskit -I../inst/include/tskit/tskit -I/opt/homebrew/opt/gettext/include -falign-functions=64 -Wall -g -O2 -c tskit/convert.c -o tskit/convert.o
4949
# PKG_CFLAGS = -O2 -Wall
5050
# PKG_CXXFLAGS = -O2 -Wall
51-
# PKG_CXXFLAGS = -DTSK_TRACE_ERRORS
51+
# PKG_CXXFLAGS = -DTSK_TRACE_ERRORS # to also enable error tracing in tskit C as called from Rcpp
5252

5353
# Explicit compile rule for tskit C files
5454
tskit/%.o: tskit/%.c

tskitr/src/test_tsk_abort_stderr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ extern "C" void tskitr_trace_error_c(void);
1515
void test_tsk_trace_error_c() { tskitr_trace_error_c(); }
1616

1717
// [[Rcpp::export]]
18-
void test_tsk_trace_error_cpp() { tsk_trace_error(-1); }
18+
void test_tsk_trace_error_cpp() { (void)tsk_trace_error(-1); }

tskitr/src/test_tsk_abort_stderr_c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
void tskitr_bug_assert_c(void) { tsk_bug_assert(0); }
44

5-
void tskitr_trace_error_c(void) { tsk_trace_error(-1); }
5+
void tskitr_trace_error_c(void) { (void)tsk_trace_error(-1); }

tskitr/src/tskitr.cpp

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44
// using namespace Rcpp; // to omit Rcpp:: prefix for whole Rcpp API
55
// using Rcpp::IntegerVector; // to omit Rcpp:: prefix for IntegerVector
66

7+
// Finaliser to free tsk_treeseq_t when it is garbage collected
8+
// See \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_free}
9+
// for more details.
10+
static void tskitr_treeseq_xptr_delete(tsk_treeseq_t *ptr) {
11+
if (ptr != NULL) {
12+
tsk_treeseq_free(ptr);
13+
delete ptr;
14+
}
15+
}
16+
// Define the external pointer type for tsk_treeseq_t with the finaliser
17+
using tskitr_treeseq_xptr = Rcpp::XPtr<tsk_treeseq_t, Rcpp::PreserveStorage,
18+
tskitr_treeseq_xptr_delete, true>;
19+
720
//' Report the version of installed kastore C API
821
//'
922
//' @details The version is stored in the installed header \code{kastore.h}.
@@ -51,22 +64,6 @@ int table_collection_num_nodes_zero_check() {
5164
}
5265
// # nocov end
5366

54-
// Finaliser function to free tsk_treeseq_t when it is garbage collected
55-
//
56-
// @param xptr_sexp tree sequence as an external pointer to a
57-
// \code{tsk_treeseq_t} object.
58-
// @details Frees memory allocated to a \code{tsk_treeseq_t} object and deletes
59-
// its pointer by calling \code{tsk_treeseq_free()} from the tskit C API.
60-
// See \url{https://tskit.dev/tskit/docs/stable/c-api.html#c.tsk_treeseq_free}
61-
// for more details.
62-
void treeseq_xptr_finalize(SEXP xptr_sexp) {
63-
Rcpp::XPtr<tsk_treeseq_t> xptr(xptr_sexp);
64-
if (xptr.get() != NULL) {
65-
tsk_treeseq_free(xptr.get());
66-
delete xptr.get();
67-
}
68-
}
69-
7067
// TODO: Rename ts_load() to ts_load_ptr() and create ts_load() returning
7168
// S3/S4/R6/... object #22
7269
// https://github.com/HighlanderLab/tskitr/issues/22
@@ -98,12 +95,7 @@ SEXP ts_load(std::string file, int options = 0) {
9895
delete ts_ptr;
9996
Rcpp::stop(tsk_strerror(ret));
10097
}
101-
// Rcpp::XPtr<tsk_treeseq_t> xptr(ts_ptr, true);
102-
// true => delete ts_ptr on garbage collection (GC),
103-
// but note that GC will not call tsk_treeseq_free(),
104-
// which is why we need R_RegisterCFinalizerEx() below
105-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts_ptr, false);
106-
R_RegisterCFinalizerEx(xptr, treeseq_xptr_finalize, TRUE);
98+
tskitr_treeseq_xptr xptr(ts_ptr, true);
10799
return xptr;
108100
}
109101

@@ -126,7 +118,7 @@ SEXP ts_load(std::string file, int options = 0) {
126118
//' @export
127119
// [[Rcpp::export]]
128120
void ts_dump(SEXP ts, std::string file, int options = 0) {
129-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
121+
tskitr_treeseq_xptr xptr(ts);
130122
int ret =
131123
tsk_treeseq_dump(xptr, file.c_str(), static_cast<tsk_flags_t>(options));
132124
if (ret != 0) {
@@ -189,7 +181,7 @@ void ts_dump(SEXP ts, std::string file, int options = 0) {
189181
//' @export
190182
// [[Rcpp::export]]
191183
Rcpp::List ts_summary(SEXP ts) {
192-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
184+
tskitr_treeseq_xptr xptr(ts);
193185
return Rcpp::List::create(
194186
Rcpp::_["num_provenances"] = tsk_treeseq_get_num_provenances(xptr),
195187
Rcpp::_["num_populations"] = tsk_treeseq_get_num_populations(xptr),
@@ -209,31 +201,31 @@ Rcpp::List ts_summary(SEXP ts) {
209201
//' @export
210202
// [[Rcpp::export]]
211203
int ts_num_provenances(SEXP ts) {
212-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
204+
tskitr_treeseq_xptr xptr(ts);
213205
return static_cast<int>(tsk_treeseq_get_num_provenances(xptr));
214206
}
215207

216208
//' @describeIn ts_summary Get the number of populations in a tree sequence
217209
//' @export
218210
// [[Rcpp::export]]
219211
int ts_num_populations(SEXP ts) {
220-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
212+
tskitr_treeseq_xptr xptr(ts);
221213
return static_cast<int>(tsk_treeseq_get_num_populations(xptr));
222214
}
223215

224216
//' @describeIn ts_summary Get the number of migrations in a tree sequence
225217
//' @export
226218
// [[Rcpp::export]]
227219
int ts_num_migrations(SEXP ts) {
228-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
220+
tskitr_treeseq_xptr xptr(ts);
229221
return static_cast<int>(tsk_treeseq_get_num_migrations(xptr));
230222
}
231223

232224
//' @describeIn ts_summary Get the number of individuals in a tree sequence
233225
//' @export
234226
// [[Rcpp::export]]
235227
int ts_num_individuals(SEXP ts) {
236-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
228+
tskitr_treeseq_xptr xptr(ts);
237229
return static_cast<int>(tsk_treeseq_get_num_individuals(xptr));
238230
}
239231

@@ -242,63 +234,63 @@ int ts_num_individuals(SEXP ts) {
242234
//' @export
243235
// [[Rcpp::export]]
244236
int ts_num_samples(SEXP ts) {
245-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
237+
tskitr_treeseq_xptr xptr(ts);
246238
return static_cast<int>(tsk_treeseq_get_num_samples(xptr));
247239
}
248240

249241
//' @describeIn ts_summary Get the number of nodes in a tree sequence
250242
//' @export
251243
// [[Rcpp::export]]
252244
int ts_num_nodes(SEXP ts) {
253-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
245+
tskitr_treeseq_xptr xptr(ts);
254246
return static_cast<int>(tsk_treeseq_get_num_nodes(xptr));
255247
}
256248

257249
//' @describeIn ts_summary Get the number of edges in a tree sequence
258250
//' @export
259251
// [[Rcpp::export]]
260252
int ts_num_edges(SEXP ts) {
261-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
253+
tskitr_treeseq_xptr xptr(ts);
262254
return static_cast<int>(tsk_treeseq_get_num_edges(xptr));
263255
}
264256

265257
//' @describeIn ts_summary Get the number of trees in a tree sequence
266258
//' @export
267259
// [[Rcpp::export]]
268260
int ts_num_trees(SEXP ts) {
269-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
261+
tskitr_treeseq_xptr xptr(ts);
270262
return static_cast<int>(tsk_treeseq_get_num_trees(xptr));
271263
}
272264

273265
//' @describeIn ts_summary Get the number of sites in a tree sequence
274266
//' @export
275267
// [[Rcpp::export]]
276268
int ts_num_sites(SEXP ts) {
277-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
269+
tskitr_treeseq_xptr xptr(ts);
278270
return static_cast<int>(tsk_treeseq_get_num_sites(xptr));
279271
}
280272

281273
//' @describeIn ts_summary Get the number of mutations in a tree sequence
282274
//' @export
283275
// [[Rcpp::export]]
284276
int ts_num_mutations(SEXP ts) {
285-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
277+
tskitr_treeseq_xptr xptr(ts);
286278
return static_cast<int>(tsk_treeseq_get_num_mutations(xptr));
287279
}
288280

289281
//' @describeIn ts_summary Get the sequence length
290282
//' @export
291283
// [[Rcpp::export]]
292284
double ts_sequence_length(SEXP ts) {
293-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
285+
tskitr_treeseq_xptr xptr(ts);
294286
return tsk_treeseq_get_sequence_length(xptr);
295287
}
296288

297289
//' @describeIn ts_summary Get the time units string
298290
//' @export
299291
// [[Rcpp::export]]
300292
Rcpp::String ts_time_units(SEXP ts) {
301-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
293+
tskitr_treeseq_xptr xptr(ts);
302294
const char *p = tsk_treeseq_get_time_units(xptr);
303295
tsk_size_t n = tsk_treeseq_get_time_units_length(xptr);
304296
return Rcpp::String(std::string(p, p + n));
@@ -313,7 +305,7 @@ Rcpp::String ts_time_units(SEXP ts) {
313305
// ts_metadata(ts)
314306
// slendr::ts_metadata(slim_ts)
315307
Rcpp::String ts_metadata(SEXP ts) {
316-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
308+
tskitr_treeseq_xptr xptr(ts);
317309
const char *p = tsk_treeseq_get_metadata(xptr);
318310
tsk_size_t n = tsk_treeseq_get_metadata_length(xptr);
319311
return Rcpp::String(std::string(p, p + n));
@@ -340,7 +332,7 @@ Rcpp::String ts_metadata(SEXP ts) {
340332
//' @export
341333
// [[Rcpp::export]]
342334
Rcpp::List ts_metadata_length(SEXP ts) {
343-
Rcpp::XPtr<tsk_treeseq_t> xptr(ts);
335+
tskitr_treeseq_xptr xptr(ts);
344336
const tsk_table_collection_t *tables = xptr->tables;
345337
return Rcpp::List::create(
346338
Rcpp::_["ts"] = static_cast<int>(tsk_treeseq_get_metadata_length(xptr)),

0 commit comments

Comments
 (0)