Skip to content

Update to C API 0.99.14 #165

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions subprojects/tskit/tskit/convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
* pointless. */

typedef struct {
size_t precision;
unsigned int precision;
tsk_flags_t options;
char *newick;
tsk_id_t *traversal_stack;
Expand Down Expand Up @@ -98,7 +98,7 @@ tsk_newick_converter_run(
}
/* We do this for ms-compatability. This should be a configurable option
* via the flags attribute */
label = v + 1;
label = (int) v + 1;
r = snprintf(buffer + s, buffer_size - s, "%d", label);
if (r < 0) {
ret = TSK_ERR_IO;
Expand Down Expand Up @@ -145,16 +145,17 @@ tsk_newick_converter_run(

static int
tsk_newick_converter_init(tsk_newick_converter_t *self, const tsk_tree_t *tree,
size_t precision, tsk_flags_t options)
unsigned int precision, tsk_flags_t options)
{
int ret = 0;

memset(self, 0, sizeof(tsk_newick_converter_t));
tsk_memset(self, 0, sizeof(tsk_newick_converter_t));
self->precision = precision;
self->options = options;
self->tree = tree;
self->traversal_stack = malloc(tsk_treeseq_get_num_nodes(self->tree->tree_sequence)
* sizeof(*self->traversal_stack));
self->traversal_stack
= tsk_malloc(tsk_treeseq_get_num_nodes(self->tree->tree_sequence)
* sizeof(*self->traversal_stack));
if (self->traversal_stack == NULL) {
ret = TSK_ERR_NO_MEMORY;
goto out;
Expand All @@ -171,7 +172,7 @@ tsk_newick_converter_free(tsk_newick_converter_t *self)
}

int
tsk_convert_newick(const tsk_tree_t *tree, tsk_id_t root, size_t precision,
tsk_convert_newick(const tsk_tree_t *tree, tsk_id_t root, unsigned int precision,
tsk_flags_t options, size_t buffer_size, char *buffer)
{
int ret = 0;
Expand Down
2 changes: 1 addition & 1 deletion subprojects/tskit/tskit/convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ extern "C" {

#include <tskit/trees.h>

int tsk_convert_newick(const tsk_tree_t *tree, tsk_id_t root, size_t precision,
int tsk_convert_newick(const tsk_tree_t *tree, tsk_id_t root, unsigned int precision,
tsk_flags_t options, size_t buffer_size, char *buffer);

#ifdef __cplusplus
Expand Down
93 changes: 83 additions & 10 deletions subprojects/tskit/tskit/core.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2019 Tskit Developers
* Copyright (c) 2019-2021 Tskit Developers
* Copyright (c) 2015-2018 University of Oxford
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down Expand Up @@ -175,6 +175,9 @@ tsk_strerror_internal(int err)
case TSK_ERR_BOTH_COLUMNS_REQUIRED:
ret = "Both columns in a related pair must be provided";
break;
case TSK_ERR_BAD_COLUMN_TYPE:
ret = "An incompatible type for a column was found in the file";
break;

/* Out of bounds errors */
case TSK_ERR_BAD_OFFSET:
Expand Down Expand Up @@ -400,6 +403,9 @@ tsk_strerror_internal(int err)
case TSK_ERR_BAD_GENOTYPE:
ret = "Bad genotype value provided";
break;
case TSK_ERR_BAD_ANCESTRAL_STATE:
ret = "Bad ancestral state specified";
break;

/* Genotype decoding errors */
case TSK_ERR_TOO_MANY_ALLELES:
Expand Down Expand Up @@ -541,11 +547,11 @@ void
tsk_blkalloc_print_state(tsk_blkalloc_t *self, FILE *out)
{
fprintf(out, "Block allocator%p::\n", (void *) self);
fprintf(out, "\ttop = %d\n", (int) self->top);
fprintf(out, "\tchunk_size = %d\n", (int) self->chunk_size);
fprintf(out, "\tnum_chunks = %d\n", (int) self->num_chunks);
fprintf(out, "\ttotal_allocated = %d\n", (int) self->total_allocated);
fprintf(out, "\ttotal_size = %d\n", (int) self->total_size);
fprintf(out, "\ttop = %lld\n", (long long) self->top);
fprintf(out, "\tchunk_size = %lld\n", (long long) self->chunk_size);
fprintf(out, "\tnum_chunks = %lld\n", (long long) self->num_chunks);
fprintf(out, "\ttotal_allocated = %lld\n", (long long) self->total_allocated);
fprintf(out, "\ttotal_size = %lld\n", (long long) self->total_size);
}

int TSK_WARN_UNUSED
Expand All @@ -564,7 +570,7 @@ tsk_blkalloc_init(tsk_blkalloc_t *self, size_t chunk_size)
{
int ret = 0;

memset(self, 0, sizeof(tsk_blkalloc_t));
tsk_memset(self, 0, sizeof(tsk_blkalloc_t));
if (chunk_size < 1) {
ret = TSK_ERR_BAD_PARAM_VALUE;
goto out;
Expand Down Expand Up @@ -642,8 +648,8 @@ tsk_blkalloc_free(tsk_blkalloc_t *self)

/* Mirrors the semantics of numpy's searchsorted function. Uses binary
* search to find the index of the closest value in the array. */
size_t
tsk_search_sorted(const double *restrict array, size_t size, double value)
tsk_size_t
tsk_search_sorted(const double *restrict array, tsk_size_t size, double value)
{
int64_t upper = (int64_t) size;
int64_t lower = 0;
Expand All @@ -663,7 +669,7 @@ tsk_search_sorted(const double *restrict array, size_t size, double value)
}
}
offset = (int64_t)(array[lower] < value);
return (size_t)(lower + offset);
return (tsk_size_t)(lower + offset);
}

/* Rounds the specified double to the closest multiple of 10**-num_digits. If
Expand Down Expand Up @@ -703,3 +709,70 @@ tsk_is_unknown_time(double val)
nan_union.f = val;
return nan_union.i == TSK_UNKNOWN_TIME_HEX;
}

void *
tsk_malloc(tsk_size_t size)
{
/* Avoid malloc(0) as it's not portable */
if (size == 0) {
size = 1;
}
#if TSK_MAX_SIZE > SIZE_MAX
if (size > SIZE_MAX) {
return NULL;
}
#endif
return malloc((size_t) size);
}

void *
tsk_realloc(void *ptr, tsk_size_t size)
{
/* We shouldn't ever realloc to a zero size in tskit */
tsk_bug_assert(size > 0);
return realloc(ptr, (size_t) size);
}

/* We keep the size argument here as a size_t because we'd have to
* cast the outputs of sizeof() otherwise, which would lead to
* less readable code. We need to be careful to use calloc within
* the library accordingly, so that size can't overflow on 32 bit.
*/
void *
tsk_calloc(tsk_size_t n, size_t size)
{
/* Avoid calloc(0) as it's not portable */
if (n == 0) {
n = 1;
}
#if TSK_MAX_SIZE > SIZE_MAX
if (n > SIZE_MAX) {
return NULL;
}
#endif
return calloc((size_t) n, size);
}

void *
tsk_memset(void *ptr, int fill, tsk_size_t size)
{
return memset(ptr, fill, (size_t) size);
}

void *
tsk_memcpy(void *dest, const void *src, tsk_size_t size)
{
return memcpy(dest, src, (size_t) size);
}

void *
tsk_memmove(void *dest, const void *src, tsk_size_t size)
{
return memmove(dest, src, (size_t) size);
}

int
tsk_memcmp(const void *s1, const void *s2, tsk_size_t size)
{
return memcmp(s1, s2, (size_t) size);
}
76 changes: 73 additions & 3 deletions subprojects/tskit/tskit/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,59 @@ __tsk_nan_f(void)
}
#define TSK_UNKNOWN_TIME __tsk_nan_f()

/**
@brief Tskit Object IDs.

@rst
All objects in tskit are referred to by integer IDs corresponding to the
row they occupy in the relevant table. The ``tsk_id_t`` type should be used
when manipulating these ID values. The reserved value ``TSK_NULL`` (-1) defines
missing data.
@endrst
*/
#ifdef _TSK_BIG_TABLES
/* Allow tables to have more than 2^31 rows. This is an EXPERIMENTAL feature
* and is not supported in any way. This typedef is only included for
* future-proofing purposes, so that we can be sure that we don't make any
* design decisions that are incompatible with big tables by building the
* library in 64 bit mode in CI. See the discussion here for more background:

* https://github.com/tskit-dev/tskit/issues/343
*
* If you need big tables, please open an issue on GitHub to discuss, or comment
* on the thread above.
*/
typedef int64_t tsk_id_t;
#define TSK_MAX_ID INT64_MAX
#define TSK_ID_STORAGE_TYPE KAS_INT64
#else
typedef int32_t tsk_id_t;
#define TSK_MAX_ID INT32_MAX
#define TSK_ID_STORAGE_TYPE KAS_INT32
#endif

/**
@brief Tskit sizes.

@rst
The ``tsk_size_t`` type is an unsigned integer used for any size or count value.
@endrst
*/
typedef uint64_t tsk_size_t;
#define TSK_MAX_SIZE UINT64_MAX
#define TSK_SIZE_STORAGE_TYPE KAS_UINT64

/**
@brief Container for bitwise flags.

@rst
Bitwise flags are used in tskit as a column type and also as a way to
specify options to API functions.
@endrst
*/
typedef uint32_t tsk_flags_t;
#define TSK_FLAGS_STORAGE_TYPE KAS_UINT32

// clang-format off
/**
@defgroup API_VERSION_GROUP API version macros.
Expand All @@ -129,7 +182,7 @@ to the API or ABI are introduced, i.e., the addition of a new function.
The library patch version. Incremented when any changes not relevant to the
to the API or ABI are introduced, i.e., internal refactors of bugfixes.
*/
#define TSK_VERSION_PATCH 12
#define TSK_VERSION_PATCH 14
/** @} */

/* Node flags */
Expand All @@ -144,7 +197,7 @@ to the API or ABI are introduced, i.e., internal refactors of bugfixes.
#define TSK_FILE_FORMAT_NAME "tskit.trees"
#define TSK_FILE_FORMAT_NAME_LENGTH 11
#define TSK_FILE_FORMAT_VERSION_MAJOR 12
#define TSK_FILE_FORMAT_VERSION_MINOR 4
#define TSK_FILE_FORMAT_VERSION_MINOR 5

/**
@defgroup GENERAL_ERROR_GROUP General errors.
Expand Down Expand Up @@ -208,6 +261,12 @@ not found in the file.
*/
#define TSK_ERR_BOTH_COLUMNS_REQUIRED -104

/**
An unsupported type was provided for a column in the file.
*/
#define TSK_ERR_BAD_COLUMN_TYPE -105


/* Out of bounds errors */
#define TSK_ERR_BAD_OFFSET -200
#define TSK_ERR_OUT_OF_BOUNDS -201
Expand Down Expand Up @@ -291,6 +350,7 @@ not found in the file.
/* Mutation mapping errors */
#define TSK_ERR_GENOTYPES_ALL_MISSING -1000
#define TSK_ERR_BAD_GENOTYPE -1001
#define TSK_ERR_BAD_ANCESTRAL_STATE -1002

/* Genotype decoding errors */
#define TSK_ERR_MUST_IMPUTE_NON_SAMPLES -1100
Expand Down Expand Up @@ -402,14 +462,24 @@ extern int tsk_blkalloc_init(tsk_blkalloc_t *self, size_t chunk_size);
extern void *tsk_blkalloc_get(tsk_blkalloc_t *self, size_t size);
extern void tsk_blkalloc_free(tsk_blkalloc_t *self);

size_t tsk_search_sorted(const double *array, size_t size, double value);
tsk_size_t tsk_search_sorted(const double *array, tsk_size_t size, double value);
double tsk_round(double x, unsigned int ndigits);

bool tsk_is_unknown_time(double val);

#define TSK_UUID_SIZE 36
int tsk_generate_uuid(char *dest, int flags);

/* TODO most of these can probably be macros so they compile out as no-ops.
* Lets do the 64 bit tsk_size_t switch first though. */
void *tsk_malloc(tsk_size_t size);
void *tsk_realloc(void *ptr, tsk_size_t size);
void *tsk_calloc(tsk_size_t n, size_t size);
void *tsk_memset(void *ptr, int fill, tsk_size_t size);
void *tsk_memcpy(void *dest, const void *src, tsk_size_t size);
void *tsk_memmove(void *dest, const void *src, tsk_size_t size);
int tsk_memcmp(const void *s1, const void *s2, tsk_size_t size);

#ifdef __cplusplus
}
#endif
Expand Down
Loading