Skip to content
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
38 changes: 30 additions & 8 deletions libtiledbvcf/src/dataset/tiledbvcfdataset.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <cstdlib>
#include <future>
#include <map>
#include <optional>
#include <string>
#include <vector>

Expand Down Expand Up @@ -571,12 +572,12 @@ void TileDBVCFDataset::open(
// 'vcf.end_timestamp' in tiledb_config. If either timestamp is provided,
// reopen the arrays.
bool reopen = false;
std::optional<uint64_t> start_timestamp;
std::optional<uint64_t> end_timestamp;

try {
auto start_timestamp = std::stoull(cfg_.get("vcf.start_timestamp"));
data_array_->set_open_timestamp_start(start_timestamp);
vcf_header_array_->set_open_timestamp_start(start_timestamp);
LOG_INFO("Using vcf.start_timestamp from config: {}", start_timestamp);
start_timestamp = std::stoull(cfg_.get("vcf.start_timestamp"));
LOG_INFO("Using vcf.start_timestamp from config: {}", *start_timestamp);
reopen = true;
} catch (const tiledb::TileDBError& ex) {
LOG_TRACE("'vcf.start_timestamp' not specified in config, using default");
Expand All @@ -587,10 +588,8 @@ void TileDBVCFDataset::open(
}

try {
auto end_timestamp = std::stoull(cfg_.get("vcf.end_timestamp"));
data_array_->set_open_timestamp_end(end_timestamp);
vcf_header_array_->set_open_timestamp_end(end_timestamp);
LOG_INFO("Using vcf.end_timestamp from config: {}", end_timestamp);
end_timestamp = std::stoull(cfg_.get("vcf.end_timestamp"));
LOG_INFO("Using vcf.end_timestamp from config: {}", *end_timestamp);
reopen = true;
} catch (const tiledb::TileDBError& ex) {
LOG_TRACE("'vcf.end_timestamp' not specified in config, using default");
Expand All @@ -600,6 +599,29 @@ void TileDBVCFDataset::open(
cfg_.get("vcf.end_timestamp"));
}

// If the user supplied an inverted range (start > end), short-circuit:
// mark the dataset as having an empty time range and skip the reopen.
// Calling reopen() with start > end would surface as an uncaught
// "Range is empty" exception in some TileDB versions and abort the process.
if (start_timestamp && end_timestamp && *start_timestamp > *end_timestamp) {
LOG_INFO(
"vcf.start_timestamp ({}) > vcf.end_timestamp ({}); treating as "
"empty time range",
*start_timestamp,
*end_timestamp);
empty_time_range_ = true;
reopen = false;
} else {
if (start_timestamp) {
data_array_->set_open_timestamp_start(*start_timestamp);
vcf_header_array_->set_open_timestamp_start(*start_timestamp);
}
if (end_timestamp) {
data_array_->set_open_timestamp_end(*end_timestamp);
vcf_header_array_->set_open_timestamp_end(*end_timestamp);
}
}

if (reopen) {
data_array_->reopen();
vcf_header_array_->reopen();
Expand Down
15 changes: 15 additions & 0 deletions libtiledbvcf/src/dataset/tiledbvcfdataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,16 @@ class TileDBVCFDataset {
/** Returns true if the dataset is tiledb cloud URI. */
bool tiledb_cloud_dataset() const;

/**
* Returns true if the user requested an inverted time-travel range
* (vcf.start_timestamp > vcf.end_timestamp). In that case the arrays were
* never reopened with the inverted range, and callers should treat reads
* as producing zero results.
*/
bool empty_time_range() const {
return empty_time_range_;
}

/**
* Gets the datatype of a particular exportable attribute that is not fmt or
* info
Expand Down Expand Up @@ -881,6 +891,11 @@ class TileDBVCFDataset {
/** Set to true when the dataset is opened. */
bool open_;

/** Set to true when open() was called with an inverted time-travel range
* (start_timestamp > end_timestamp). When true, reads should short-circuit
* to zero results without consulting the underlying arrays. */
bool empty_time_range_ = false;

/** The dataset's general metadata (does not contain sample header data). */
Metadata metadata_;

Expand Down
10 changes: 10 additions & 0 deletions libtiledbvcf/src/read/reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ void Reader::read() {
throw std::runtime_error(
"Error exporting records; reader has not been initialized.");

if (dataset_->empty_time_range()) {
read_state_.status = ReadStatus::COMPLETED;
buffers_a.reset(nullptr);
return;
}

bool pending_work = true;
switch (read_state_.status) {
case ReadStatus::COMPLETED:
Expand Down Expand Up @@ -2587,6 +2593,10 @@ void Reader::info_attribute_count(int32_t* count) {
void Reader::sample_count(int32_t* count) {
if (count == nullptr)
throw std::runtime_error("Error getting sample count");
if (dataset_->empty_time_range()) {
*count = 0;
return;
}
*count = dataset_->sample_names().size();
}

Expand Down
Loading