blob: b30c76f7fbb146d1a61b1f3b6e75437b2ebb4c6d [file] [log] [blame]
// 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 <optional>
#include <glog/logging.h>
#include "kudu/common/timestamp.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/tablet/metadata.pb.h"
#include "kudu/util/locks.h"
#include "kudu/util/mutex.h"
namespace kudu {
namespace tablet {
// Encapsulates the persistent state associated with a transaction.
class TxnMetadata : public RefCountedThreadSafe<TxnMetadata> {
public:
explicit TxnMetadata(bool aborted = false,
std::optional<Timestamp> commit_mvcc_op_timestamp = std::nullopt,
std::optional<Timestamp> commit_ts = std::nullopt,
bool flushed_committed_mrs = false)
: aborted_(aborted),
commit_mvcc_op_timestamp_(std::move(commit_mvcc_op_timestamp)),
commit_timestamp_(std::move(commit_ts)),
flushed_committed_mrs_(flushed_committed_mrs) {}
void set_flushed_committed_mrs() {
std::lock_guard<simple_spinlock> l(lock_);
flushed_committed_mrs_ = true;
}
bool flushed_committed_mrs() const {
std::lock_guard<simple_spinlock> l(lock_);
return flushed_committed_mrs_;
}
void set_aborted() {
std::lock_guard<simple_spinlock> l(lock_);
CHECK(std::nullopt == commit_timestamp_);
aborted_ = true;
}
void set_commit_timestamp(Timestamp commit_ts) {
std::lock_guard<simple_spinlock> l(lock_);
CHECK(std::nullopt == commit_timestamp_);
CHECK(!aborted_);
CHECK(std::nullopt != commit_mvcc_op_timestamp_);
commit_timestamp_ = commit_ts;
}
void set_commit_mvcc_op_timestamp(Timestamp op_ts) {
std::lock_guard<simple_spinlock> l(lock_);
CHECK(std::nullopt == commit_timestamp_);
commit_mvcc_op_timestamp_ = op_ts;
}
bool aborted() const {
std::lock_guard<simple_spinlock> l(lock_);
return aborted_;
}
std::optional<Timestamp> commit_timestamp() const {
std::lock_guard<simple_spinlock> l(lock_);
return commit_timestamp_;
}
std::optional<Timestamp> commit_mvcc_op_timestamp() const {
std::lock_guard<simple_spinlock> l(lock_);
return commit_mvcc_op_timestamp_;
}
void GetTimestamps(std::optional<Timestamp>* op_ts,
std::optional<Timestamp>* commit_ts) const {
std::lock_guard<simple_spinlock> l(lock_);
*op_ts = commit_mvcc_op_timestamp_;
*commit_ts = commit_timestamp_;
}
TxnMetadataPB ToPB() {
TxnMetadataPB pb;
std::lock_guard<simple_spinlock> l(lock_);
if (commit_timestamp_) {
pb.set_commit_timestamp(commit_timestamp_->value());
}
if (commit_mvcc_op_timestamp_) {
pb.set_commit_mvcc_op_timestamp(commit_mvcc_op_timestamp_->value());
}
if (aborted_) {
pb.set_aborted(true);
}
if (flushed_committed_mrs_) {
pb.set_flushed_committed_mrs(true);
}
return pb;
}
private:
friend class RefCountedThreadSafe<TxnMetadata>;
~TxnMetadata() = default;
// Protects access to all members below.
mutable simple_spinlock lock_;
bool aborted_;
// If the MVCC op with this timestamp is considered applied, either
// 'aborted_' is set to true, or 'commit_timestamp_' is set.
std::optional<Timestamp> commit_mvcc_op_timestamp_;
std::optional<Timestamp> commit_timestamp_;
bool flushed_committed_mrs_;
};
} // namespace tablet
} // namespace kudu