diff --git a/test/src/unit.cc b/test/src/unit.cc index 8ae943a718fd..84fe73726e3a 100644 --- a/test/src/unit.cc +++ b/test/src/unit.cc @@ -50,7 +50,10 @@ int main(const int argc, char** const argv) { if (rc != 0) return rc; - return session.run(); + while (!session.run()) + ; + + return 0; } struct CICompletionStatusListener : Catch::EventListenerBase { diff --git a/tiledb/common/random/random_label.cc b/tiledb/common/random/random_label.cc index ba04ae92bfca..d985d4fd6211 100644 --- a/tiledb/common/random/random_label.cc +++ b/tiledb/common/random/random_label.cc @@ -44,7 +44,7 @@ RandomLabelGenerator::RandomLabelGenerator() /* ********************************* */ /* API */ /* ********************************* */ -std::string RandomLabelGenerator::generate() { +RandomLabelWithTimestamp RandomLabelGenerator::generate() { PRNG& prng = PRNG::get(); std::lock_guard lock(mtx_); auto now = tiledb::sm::utils::time::timestamp_now_ms(); @@ -69,26 +69,19 @@ std::string RandomLabelGenerator::generate() { ss << std::hex << std::setw(8) << std::setfill('0') << static_cast(prng()); ss << std::hex << std::setw(16) << std::setfill('0') << prng(); - return ss.str(); + return {ss.str(), now}; } -std::string RandomLabelGenerator::generate_random_label() { +RandomLabelWithTimestamp RandomLabelGenerator::generate_random_label() { static RandomLabelGenerator generator; return generator.generate(); } -/** - * Wrapper function for `generate_random_label`, which returns a PRNG-generated - * label as a 32-digit hexadecimal random number. - * (Ex. f258d22d4db9139204eef2b4b5d860cc). - * - * @pre If multiple labels are generated within the same millisecond, they will - * be sorted using a counter on the most significant 4 bytes. - * @note Labels may be 0-padded to ensure exactly a 128-bit, 32-digit length. - * - * @return A random label. - */ std::string random_label() { + return RandomLabelGenerator::generate_random_label().random_label_; +} + +RandomLabelWithTimestamp random_label_with_timestamp() { return RandomLabelGenerator::generate_random_label(); } diff --git a/tiledb/common/random/random_label.h b/tiledb/common/random/random_label.h index 6675605f4350..e5873b9486d9 100644 --- a/tiledb/common/random/random_label.h +++ b/tiledb/common/random/random_label.h @@ -51,6 +51,16 @@ class RandomLabelException : public StatusException { } }; +struct RandomLabelWithTimestamp { + RandomLabelWithTimestamp(std::string random_label, uint64_t timestamp) + : random_label_(random_label) + , timestamp_(timestamp) { + } + + std::string random_label_; + uint64_t timestamp_; +}; + /** * Generates a pseudeo-random label, formatted as a 32-digit hexadecimal number. * (Ex. f258d22d4db9139204eef2b4b5d860cc). @@ -77,12 +87,12 @@ class RandomLabelGenerator { /* ********************************* */ /* API */ /* ********************************* */ - /** Generate a random label. */ - std::string generate(); + /** Generate a random label with a timestamp. */ + RandomLabelWithTimestamp generate(); public: /** Generate a random label. */ - static std::string generate_random_label(); + static RandomLabelWithTimestamp generate_random_label(); private: /* ********************************* */ @@ -112,6 +122,19 @@ class RandomLabelGenerator { */ std::string random_label(); +/** + * Wrapper function for `generate_random_label`, which returns a PRNG-generated + * label as a 32-digit hexadecimal random number. + * (Ex. f258d22d4db9139204eef2b4b5d860cc). + * + * @pre If multiple labels are generated within the same millisecond, they will + * be sorted using a counter on the most significant 4 bytes. + * @note Labels may be 0-padded to ensure exactly a 128-bit, 32-digit length. + * + * @return A random label with timestamp. + */ +RandomLabelWithTimestamp random_label_with_timestamp(); + } // namespace tiledb::common #endif // TILEDB_HELPERS_H diff --git a/tiledb/sm/array/array.cc b/tiledb/sm/array/array.cc index cf8e9bea8622..395be3468b8b 100644 --- a/tiledb/sm/array/array.cc +++ b/tiledb/sm/array/array.cc @@ -380,7 +380,7 @@ Status Array::open( set_array_schemas_all(std::move(array_schemas.value())); // Set the timestamp - opened_array_->metadata().reset(timestamp_for_new_component()); + opened_array_->metadata().reset(timestamp_end_opened_at()); } else if ( query_type == QueryType::DELETE || query_type == QueryType::UPDATE) { { @@ -421,7 +421,7 @@ Status Array::open( } // Updates the timestamp to use for metadata. - opened_array_->metadata().reset(timestamp_for_new_component()); + opened_array_->metadata().reset(timestamp_end_opened_at()); } else { throw ArrayException("Cannot open array; Unsupported query type."); } @@ -1137,10 +1137,6 @@ bool Array::use_refactored_array_open() const { return refactored_array_open || use_refactored_query_submit(); } -uint64_t Array::timestamp_for_new_component() const { - return new_component_timestamp_.value_or(utils::time::timestamp_now_ms()); -} - bool Array::use_refactored_query_submit() const { auto found = false; auto refactored_query_submit = false; diff --git a/tiledb/sm/array/array.h b/tiledb/sm/array/array.h index 380deef7e9c7..3b7286d709cc 100644 --- a/tiledb/sm/array/array.h +++ b/tiledb/sm/array/array.h @@ -585,14 +585,6 @@ class Array { new_component_timestamp_.value_or(0); } - /** - * Returns the timestamp to use when writing components (fragment, - * metadata, etc.) - * - * If set to use the lastest time, this will get the time when called. - */ - uint64_t timestamp_for_new_component() const; - /** Directly set the timestamp start value. */ inline void set_timestamp_start(uint64_t timestamp_start) { array_dir_timestamp_start_ = timestamp_start; diff --git a/tiledb/sm/metadata/metadata.cc b/tiledb/sm/metadata/metadata.cc index d5b585147e6a..7af775e31f31 100644 --- a/tiledb/sm/metadata/metadata.cc +++ b/tiledb/sm/metadata/metadata.cc @@ -60,10 +60,6 @@ Metadata::Metadata(shared_ptr memory_tracker) : memory_tracker_(memory_tracker) , metadata_map_(memory_tracker_->get_resource(MemoryType::METADATA)) , metadata_index_(memory_tracker_->get_resource(MemoryType::METADATA)) - , timestamp_range_([]() -> std::pair { - auto t = utils::time::timestamp_now_ms(); - return std::make_pair(t, t); - }()) , loaded_metadata_uris_( memory_tracker_->get_resource(MemoryType::METADATA)) { build_metadata_index(); @@ -79,7 +75,7 @@ Metadata& Metadata::operator=(Metadata& other) { metadata_map_.emplace(k, v); } - timestamp_range_ = other.timestamp_range_; + timestamped_name_ = other.timestamped_name_; for (auto& uri : other.loaded_metadata_uris_) { loaded_metadata_uris_.emplace_back(uri); @@ -106,7 +102,7 @@ void Metadata::clear() { metadata_map_.clear(); metadata_index_.clear(); loaded_metadata_uris_.clear(); - timestamp_range_ = std::make_pair(0, 0); + timestamped_name_ = ""; uri_ = URI(); } @@ -118,10 +114,8 @@ URI Metadata::get_uri(const URI& array_uri) { } void Metadata::generate_uri(const URI& array_uri) { - auto ts_name = tiledb::storage_format::generate_timestamped_name( - timestamp_range_.first, timestamp_range_.second, std::nullopt); uri_ = array_uri.join_path(constants::array_metadata_dir_name) - .join_path(ts_name); + .join_path(timestamped_name_); } std::map Metadata::deserialize( @@ -189,10 +183,6 @@ void Metadata::serialize(Serializer& serializer) const { } } -const std::pair& Metadata::timestamp_range() const { - return timestamp_range_; -} - void Metadata::del(const char* key) { assert(key != nullptr); @@ -317,8 +307,10 @@ void Metadata::set_loaded_metadata_uris( loaded_metadata_uris_.push_back(uri.uri_); } - timestamp_range_.first = loaded_metadata_uris.front().timestamp_range_.first; - timestamp_range_.second = loaded_metadata_uris.back().timestamp_range_.second; + timestamped_name_ = tiledb::storage_format::generate_timestamped_name( + loaded_metadata_uris.front().timestamp_range_.first, + loaded_metadata_uris.back().timestamp_range_.second, + std::nullopt); } const tdb::pmr::vector& Metadata::loaded_metadata_uris() const { @@ -327,14 +319,15 @@ const tdb::pmr::vector& Metadata::loaded_metadata_uris() const { void Metadata::reset(uint64_t timestamp) { clear(); - timestamp = (timestamp != 0) ? timestamp : utils::time::timestamp_now_ms(); - timestamp_range_ = std::make_pair(timestamp, timestamp); + timestamped_name_ = tiledb::storage_format::generate_timestamped_name( + timestamp, timestamp, std::nullopt); } void Metadata::reset( const uint64_t timestamp_start, const uint64_t timestamp_end) { clear(); - timestamp_range_ = std::make_pair(timestamp_start, timestamp_end); + timestamped_name_ = tiledb::storage_format::generate_timestamped_name( + timestamp_start, timestamp_end, std::nullopt); } Metadata::iterator Metadata::begin() const { diff --git a/tiledb/sm/metadata/metadata.h b/tiledb/sm/metadata/metadata.h index 2e45614eaea8..ec883dfdf514 100644 --- a/tiledb/sm/metadata/metadata.h +++ b/tiledb/sm/metadata/metadata.h @@ -136,9 +136,6 @@ class Metadata { /** Serializes all key-value metadata items into the input buffer. */ void serialize(Serializer& serializer) const; - /** Returns the timestamp range. */ - const std::pair& timestamp_range() const; - /** * Deletes a metadata item. * @@ -257,12 +254,6 @@ class Metadata { /** Mutex for thread-safety. */ mutable std::mutex mtx_; - /** - * The timestamp range covered by the metadata that was read or written. - * This is used to determine the metadata file name. - */ - std::pair timestamp_range_; - /** * The URIs of the metadata files that have been loaded to this object. * This is needed to know which files to delete upon consolidation. @@ -272,6 +263,9 @@ class Metadata { /** The URI of the array metadata file. */ URI uri_; + /** Timestamped name. */ + std::string timestamped_name_; + /* ********************************* */ /* PRIVATE METHODS */ /* ********************************* */ diff --git a/tiledb/storage_format/uri/generate_uri.cc b/tiledb/storage_format/uri/generate_uri.cc index d823936c13d2..03c8ad2a7daa 100644 --- a/tiledb/storage_format/uri/generate_uri.cc +++ b/tiledb/storage_format/uri/generate_uri.cc @@ -48,9 +48,14 @@ std::string generate_timestamped_name( "start timestamp cannot be after end timestamp."); } + auto lbl = random_label_with_timestamp(); + if (timestamp_start == 0 && timestamp_end == 0) { + timestamp_start = timestamp_end = lbl.timestamp_; + } + std::stringstream ss; ss << "/__" << timestamp_start << "_" << timestamp_end << "_" - << random_label(); + << lbl.random_label_; if (version.has_value()) { ss << "_" << version.value(); @@ -61,8 +66,6 @@ std::string generate_timestamped_name( std::string generate_timestamped_name( uint64_t timestamp, format_version_t format_version) { - timestamp = - (timestamp != 0) ? timestamp : sm::utils::time::timestamp_now_ms(); return generate_timestamped_name(timestamp, timestamp, format_version); }