This is an automated email from the ASF dual-hosted git repository. alexey pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/kudu.git
commit 185d2c9faa403a6214520ea2d98d8833ab7d36ea Author: Alexey Serbin <[email protected]> AuthorDate: Tue Oct 20 16:50:22 2020 -0700 [common] introduce TxnId wrapper TxnId is a wrapper around int64_t with transaction-related specifics. It's an alternative to boost::optional<int64_t> since it lightweight and it's possible to use it as an atomic (i.e. std::atomic<TxnId> works as expected). This patch also contains appropriate test coverage for the newly introduced functionality. Change-Id: I0511637702e946f140dc617ee6bf7e1c3d5289e3 Reviewed-on: http://gerrit.cloudera.org:8080/16624 Tested-by: Kudu Jenkins Reviewed-by: Andrew Wong <[email protected]> --- src/kudu/common/CMakeLists.txt | 2 + src/kudu/common/txn_id-test.cc | 89 ++++++++++++++++++++++++++++++++++++++++++ src/kudu/common/txn_id.cc | 48 +++++++++++++++++++++++ src/kudu/common/txn_id.h | 80 +++++++++++++++++++++++++++++++++++++ 4 files changed, 219 insertions(+) diff --git a/src/kudu/common/CMakeLists.txt b/src/kudu/common/CMakeLists.txt index b9aa87f..e25d07e 100644 --- a/src/kudu/common/CMakeLists.txt +++ b/src/kudu/common/CMakeLists.txt @@ -61,6 +61,7 @@ set(COMMON_SRCS schema.cc table_util.cc timestamp.cc + txn_id.cc types.cc wire_protocol.cc zp7.cc) @@ -99,5 +100,6 @@ ADD_KUDU_TEST(row_operations-test) ADD_KUDU_TEST(scan_spec-test) ADD_KUDU_TEST(schema-test) ADD_KUDU_TEST(table_util-test) +ADD_KUDU_TEST(txn_id-test) ADD_KUDU_TEST(types-test) ADD_KUDU_TEST(wire_protocol-test NUM_SHARDS 10) diff --git a/src/kudu/common/txn_id-test.cc b/src/kudu/common/txn_id-test.cc new file mode 100644 index 0000000..92e6859 --- /dev/null +++ b/src/kudu/common/txn_id-test.cc @@ -0,0 +1,89 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "kudu/common/txn_id.h" + +#include <cstdint> + +#include <glog/logging.h> +#include <gtest/gtest.h> + +namespace kudu { + +// Basic unit test scenario for TxnId. +TEST(TxnIdTest, Basic) { + TxnId id(0); + ASSERT_TRUE(id.IsValid()); + ASSERT_EQ(0, id.value()); + + // Implicit convesion: operator int64_t(). + int64_t id_value = id; + ASSERT_EQ(0, id_value); + + // operator!() + ASSERT_FALSE(!id); + + ASSERT_EQ("0", id.ToString()); + + TxnId invalid_id; + ASSERT_GT(id, invalid_id); + + TxnId id_0(0); + ASSERT_EQ(id, id_0); + ASSERT_TRUE(id == id_0); + ASSERT_TRUE(id_0 >= id); + ASSERT_TRUE(id_0 <= id); + + TxnId id_1(1); + ASSERT_GT(id_1, id); + ASSERT_TRUE(id_1 > id); + ASSERT_TRUE(id_1 >= id); + ASSERT_TRUE(id < id_1); + ASSERT_TRUE(id <= id_1); +} + +// Test scenarios specific to invalid transaction identifiers. +TEST(TxnIdTest, InvalidTxnIdValue) { + // Non-initialized txn id has invalid value. + TxnId invalid_id; + + // operator!() + ASSERT_TRUE(!invalid_id); + +#if DCHECK_IS_ON() + ASSERT_DEATH({ + auto v = invalid_id.value(); + TxnId(v).ToString(); // unreachable + }, + "TxnId contains an invalid value"); +#endif // #if DCHECK_IS_ON() ... + + ASSERT_EQ("InvalidTxnId", invalid_id.ToString()); + +#if DCHECK_IS_ON() + ASSERT_DEATH({ + TxnId id(-1); + }, + "negative value is not allowed for TxnId"); + ASSERT_DEATH({ + TxnId id(-2); + }, + "negative value is not allowed for TxnId"); +#endif // #if DCHECK_IS_ON() ... +} + +} // namespace kudu diff --git a/src/kudu/common/txn_id.cc b/src/kudu/common/txn_id.cc new file mode 100644 index 0000000..29abf60 --- /dev/null +++ b/src/kudu/common/txn_id.cc @@ -0,0 +1,48 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "kudu/common/txn_id.h" + +#include <ostream> // IWYU pragma: keep + +#include <glog/logging.h> + +#include "kudu/gutil/strings/substitute.h" + +namespace kudu { + +const TxnId TxnId::kInvalidTxnId; + +TxnId::TxnId(int64_t id) noexcept + : id_(id) { + DCHECK_GE(id, 0) << "negative value is not allowed for TxnId"; +} + +int64_t TxnId::value() const { + DCHECK(IsValid()) << "TxnId contains an invalid value"; + return id_; +} + +std::string TxnId::ToString() const { + return IsValid() ? strings::Substitute("$0", id_) : "InvalidTxnId"; +} + +std::ostream& operator<<(std::ostream& o, const TxnId& id) { + return o << id.ToString(); +} + +} // namespace kudu diff --git a/src/kudu/common/txn_id.h b/src/kudu/common/txn_id.h new file mode 100644 index 0000000..c7cd50e --- /dev/null +++ b/src/kudu/common/txn_id.h @@ -0,0 +1,80 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +#pragma once + +#include <cstdint> +#include <iosfwd> +#include <string> + +namespace kudu { + +// A representation of transaction identifier. +class TxnId { + public: + // An invalid transaction identifier: the default constructed instances are + // initialized to this value. + static const TxnId kInvalidTxnId; + + TxnId() noexcept : id_(-1) {} + explicit TxnId(int64_t id) noexcept; + + int64_t value() const; + bool IsValid() const { return id_ >= 0; } + std::string ToString() const; + + // Cast operator: returns TxnId's int64_t value. + operator int64_t () const { return value(); } + bool operator!() const { return !IsValid(); } + + private: + friend bool operator==(const TxnId& lhs, const TxnId& rhs); + friend bool operator!=(const TxnId& lhs, const TxnId& rhs); + friend bool operator<(const TxnId& lhs, const TxnId& rhs); + friend bool operator<=(const TxnId& lhs, const TxnId& rhs); + friend bool operator>(const TxnId& lhs, const TxnId& rhs); + friend bool operator>=(const TxnId& lhs, const TxnId& rhs); + + const int64_t id_; +}; + +std::ostream& operator<<(std::ostream& o, const TxnId& txn_id); + +inline bool operator==(const TxnId& lhs, const TxnId& rhs) { + return lhs.id_ == rhs.id_; +} + +inline bool operator!=(const TxnId& lhs, const TxnId& rhs) { + return !(lhs.id_ == rhs.id_); +} + +inline bool operator<(const TxnId& lhs, const TxnId& rhs) { + return lhs.id_ < rhs.id_; +} + +inline bool operator>(const TxnId& lhs, const TxnId& rhs) { + return rhs < lhs; +} + +inline bool operator<=(const TxnId& lhs, const TxnId& rhs) { + return !(lhs > rhs); +} + +inline bool operator>=(const TxnId& lhs, const TxnId& rhs) { + return !(lhs < rhs); +} + +} // namespace kudu
