You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by to...@apache.org on 2017/08/03 19:02:54 UTC
[2/3] kudu git commit: Move clock-related classes to src/kudu/clock
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/master/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/master/CMakeLists.txt b/src/kudu/master/CMakeLists.txt
index ed72f58..1100807 100644
--- a/src/kudu/master/CMakeLists.txt
+++ b/src/kudu/master/CMakeLists.txt
@@ -47,6 +47,7 @@ set(MASTER_SRCS
add_library(master ${MASTER_SRCS})
target_link_libraries(master
+ clock
gutil
krpc
kserver
@@ -55,7 +56,6 @@ target_link_libraries(master
master_proto
rpc_header_proto
security
- server_common
server_process
tablet
token_proto
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/master/sys_catalog.cc
----------------------------------------------------------------------
diff --git a/src/kudu/master/sys_catalog.cc b/src/kudu/master/sys_catalog.cc
index 7ca586b..4b5e902 100644
--- a/src/kudu/master/sys_catalog.cc
+++ b/src/kudu/master/sys_catalog.cc
@@ -316,7 +316,7 @@ Status SysCatalogTable::SetupTablet(const scoped_refptr<tablet::TabletMetadata>&
tablet_replica_->SetBootstrapping();
RETURN_NOT_OK(BootstrapTablet(metadata,
cmeta_manager_,
- scoped_refptr<server::Clock>(master_->clock()),
+ scoped_refptr<clock::Clock>(master_->clock()),
master_->mem_tracker(),
scoped_refptr<rpc::ResultTracker>(),
metric_registry_,
@@ -331,7 +331,7 @@ Status SysCatalogTable::SetupTablet(const scoped_refptr<tablet::TabletMetadata>&
RETURN_NOT_OK_PREPEND(tablet_replica_->Start(consensus_info,
tablet,
- scoped_refptr<server::Clock>(master_->clock()),
+ scoped_refptr<clock::Clock>(master_->clock()),
master_->messenger(),
scoped_refptr<rpc::ResultTracker>(),
log,
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/server/CMakeLists.txt b/src/kudu/server/CMakeLists.txt
index 3c0158c..e1a0362 100644
--- a/src/kudu/server/CMakeLists.txt
+++ b/src/kudu/server/CMakeLists.txt
@@ -16,33 +16,6 @@
# under the License.
#########################################
-# server_common
-#########################################
-
-set(SERVER_COMMON_SRCS
- hybrid_clock.cc
- logical_clock.cc
-)
-
-add_library(server_common ${SERVER_COMMON_SRCS})
-target_link_libraries(server_common
- kudu_common
- codegen
- gutil
- kudu_fs
- kudu_util
- consensus_metadata_proto
- security)
-
-#########################################
-# server_common tests
-#########################################
-
-set(KUDU_TEST_LINK_LIBS server_common ${KUDU_MIN_TEST_LIBS})
-ADD_KUDU_TEST(hybrid_clock-test)
-ADD_KUDU_TEST(logical_clock-test)
-
-#########################################
# server_base_proto
#########################################
@@ -83,6 +56,8 @@ set(SERVER_PROCESS_SRCS
add_library(server_process ${SERVER_PROCESS_SRCS})
target_link_libraries(server_process
+ clock
+ codegen
gutil
krpc
kudu_common
@@ -90,7 +65,6 @@ target_link_libraries(server_process
kudu_util
mustache
server_base_proto
- server_common
squeasel)
# This module depends on tcmalloc and profiler directly, so need to make
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/clock.h
----------------------------------------------------------------------
diff --git a/src/kudu/server/clock.h b/src/kudu/server/clock.h
deleted file mode 100644
index 875b516..0000000
--- a/src/kudu/server/clock.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// 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.
-
-#ifndef KUDU_SERVER_CLOCK_H_
-#define KUDU_SERVER_CLOCK_H_
-
-#include <string>
-
-#include "kudu/common/common.pb.h"
-#include "kudu/common/timestamp.h"
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/util/monotime.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-class faststring;
-class MetricEntity;
-class Slice;
-class Status;
-namespace server {
-
-// An interface for a clock that can be used to assign timestamps to
-// operations.
-// Implementations must respect the following assumptions:
-// 1 - Now() must return monotonically increasing numbers
-// i.e. for any two calls, i.e. Now returns timestamp1 and timestamp2, it must
-// hold that timestamp1 < timestamp2.
-// 2 - Update() must never set the clock backwards (corollary of 1)
-class Clock : public RefCountedThreadSafe<Clock> {
- public:
-
- // Initializes the clock.
- virtual Status Init() = 0;
-
- // Obtains a new transaction timestamp corresponding to the current instant.
- virtual Timestamp Now() = 0;
-
- // Obtains a new transaction timestamp corresponding to the current instant
- // plus the max_error.
- virtual Timestamp NowLatest() = 0;
-
- // Obtain a timestamp which is guaranteed to be later than the current time
- // on any machine in the cluster.
- //
- // NOTE: this is not a very tight bound.
- virtual Status GetGlobalLatest(Timestamp* t) {
- return Status::NotSupported("clock does not support global properties");
- }
-
- // Indicates whether this clock supports the required external consistency mode.
- virtual bool SupportsExternalConsistencyMode(ExternalConsistencyMode mode) = 0;
-
- // Indicates whether the clock has a physical component to its timestamps
- // (wallclock time).
- virtual bool HasPhysicalComponent() const {
- return false;
- }
-
- // Get a MonoDelta representing the physical component difference between two timestamps,
- // specifically lhs - rhs.
- //
- // Requires that this clock's timestamps have a physical component, i.e.
- // that HasPhysicalComponent() return true, otherwise it will crash.
- virtual MonoDelta GetPhysicalComponentDifference(Timestamp /*lhs*/, Timestamp /*rhs*/) const {
- LOG(FATAL) << "Clock's timestamps don't have a physical component.";
- }
-
- // Update the clock with a transaction timestamp originating from
- // another server. For instance replicas can call this so that,
- // if elected leader, they are guaranteed to generate timestamps
- // higher than the timestamp of the last transaction accepted from the
- // leader.
- virtual Status Update(const Timestamp& to_update) = 0;
-
- // Waits until the clock on all machines has advanced past 'then'.
- // Can also be used to implement 'external consistency' in the same sense as
- // Google's Spanner.
- virtual Status WaitUntilAfter(const Timestamp& then,
- const MonoTime& deadline) = 0;
-
- // Waits until the clock on this machine advances past 'then'. Unlike
- // WaitUntilAfter(), this does not make any global guarantees.
- virtual Status WaitUntilAfterLocally(const Timestamp& then,
- const MonoTime& deadline) = 0;
-
- // Return true if the given time has definitely passed (i.e any future call
- // to Now() would return a higher value than t).
- virtual bool IsAfter(Timestamp t) = 0;
-
- // Register the clock metrics in the given entity.
- virtual void RegisterMetrics(const scoped_refptr<MetricEntity>& metric_entity) = 0;
-
- // Strigifies the provided timestamp according to this clock's internal format.
- virtual std::string Stringify(Timestamp timestamp) = 0;
-
- virtual ~Clock() {}
-};
-
-} // namespace server
-} // namespace kudu
-
-#endif /* KUDU_SERVER_CLOCK_H_ */
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/generic_service.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/generic_service.cc b/src/kudu/server/generic_service.cc
index 63dd4b2..422865f 100644
--- a/src/kudu/server/generic_service.cc
+++ b/src/kudu/server/generic_service.cc
@@ -21,11 +21,11 @@
#include <string>
#include <unordered_set>
+#include "kudu/clock/clock.h"
+#include "kudu/clock/hybrid_clock.h"
#include "kudu/gutil/map-util.h"
-#include "kudu/rpc/rpc_context.h"
#include "kudu/rpc/remote_user.h"
-#include "kudu/server/clock.h"
-#include "kudu/server/hybrid_clock.h"
+#include "kudu/rpc/rpc_context.h"
#include "kudu/server/server_base.h"
#include "kudu/util/debug-util.h"
#include "kudu/util/debug/leak_annotations.h"
@@ -175,7 +175,7 @@ void GenericServiceImpl::SetServerWallClockForTests(const SetServerWallClockForT
resp->set_success(false);
}
- server::HybridClock* clock = down_cast<server::HybridClock*>(server_->clock());
+ clock::HybridClock* clock = down_cast<clock::HybridClock*>(server_->clock());
if (req->has_now_usec()) {
clock->SetMockClockWallTimeForTests(req->now_usec());
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/hybrid_clock-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/hybrid_clock-test.cc b/src/kudu/server/hybrid_clock-test.cc
deleted file mode 100644
index b53fe0b..0000000
--- a/src/kudu/server/hybrid_clock-test.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-// 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 <algorithm>
-#include <glog/logging.h>
-#include <gtest/gtest.h>
-
-#include "kudu/server/hybrid_clock.h"
-#include "kudu/util/monotime.h"
-#include "kudu/util/random.h"
-#include "kudu/util/random_util.h"
-#include "kudu/util/test_util.h"
-
-DECLARE_bool(use_mock_wall_clock);
-
-namespace kudu {
-namespace server {
-
-class HybridClockTest : public KuduTest {
- public:
- HybridClockTest()
- : clock_(new HybridClock) {
- }
-
- virtual void SetUp() OVERRIDE {
- KuduTest::SetUp();
- ASSERT_OK(clock_->Init());
- }
-
- protected:
- scoped_refptr<HybridClock> clock_;
-};
-
-TEST(MockHybridClockTest, TestMockedSystemClock) {
- google::FlagSaver saver;
- FLAGS_use_mock_wall_clock = true;
- scoped_refptr<HybridClock> clock(new HybridClock());
- clock->Init();
- Timestamp timestamp;
- uint64_t max_error_usec;
- clock->NowWithError(×tamp, &max_error_usec);
- ASSERT_EQ(timestamp.ToUint64(), 0);
- ASSERT_EQ(max_error_usec, 0);
- // If we read the clock again we should see the logical component be incremented.
- clock->NowWithError(×tamp, &max_error_usec);
- ASSERT_EQ(timestamp.ToUint64(), 1);
- // Now set an arbitrary time and check that is the time returned by the clock.
- uint64_t time = 1234;
- uint64_t error = 100 * 1000;
- clock->SetMockClockWallTimeForTests(time);
- clock->SetMockMaxClockErrorForTests(error);
- clock->NowWithError(×tamp, &max_error_usec);
- ASSERT_EQ(timestamp.ToUint64(),
- HybridClock::TimestampFromMicrosecondsAndLogicalValue(time, 0).ToUint64());
- ASSERT_EQ(max_error_usec, error);
- // Perform another read, we should observe the logical component increment, again.
- clock->NowWithError(×tamp, &max_error_usec);
- ASSERT_EQ(timestamp.ToUint64(),
- HybridClock::TimestampFromMicrosecondsAndLogicalValue(time, 1).ToUint64());
-}
-
-// Test that, if the rate at which the clock is read is greater than the maximum
-// resolution of the logical counter (12 bits in our implementation), it properly
-// "overflows" into the physical portion of the clock, and maintains all ordering
-// guarantees even as the physical clock continues to increase.
-//
-// This is a regression test for KUDU-1345.
-TEST(MockHybridClockTest, TestClockDealsWithWrapping) {
- google::FlagSaver saver;
- FLAGS_use_mock_wall_clock = true;
- scoped_refptr<HybridClock> clock(new HybridClock());
- clock->SetMockClockWallTimeForTests(1000);
- clock->Init();
-
- Timestamp prev = clock->Now();
-
- // Update the clock from 10us in the future
- clock->Update(HybridClock::TimestampFromMicroseconds(1010));
-
- // Now read the clock value enough times so that the logical value wraps
- // over, and should increment the _physical_ portion of the clock.
- for (int i = 0; i < 10000; i++) {
- Timestamp now = clock->Now();
- ASSERT_GT(now.value(), prev.value());
- prev = now;
- }
- ASSERT_EQ(1012, HybridClock::GetPhysicalValueMicros(prev));
-
- // Advance the time microsecond by microsecond, and ensure the clock never
- // goes backwards.
- for (int time = 1001; time < 1020; time++) {
- clock->SetMockClockWallTimeForTests(time);
- Timestamp now = clock->Now();
-
- // Clock should run strictly forwards.
- ASSERT_GT(now.value(), prev.value());
-
- // Additionally, once the physical time surpasses the logical time, we should
- // be running on the physical clock. Otherwise, we should stick with the physical
- // time we had rolled forward to above.
- if (time > 1012) {
- ASSERT_EQ(time, HybridClock::GetPhysicalValueMicros(now));
- } else {
- ASSERT_EQ(1012, HybridClock::GetPhysicalValueMicros(now));
- }
-
- prev = now;
- }
-}
-
-// Test that two subsequent time reads are monotonically increasing.
-TEST_F(HybridClockTest, TestNow_ValuesIncreaseMonotonically) {
- const Timestamp now1 = clock_->Now();
- const Timestamp now2 = clock_->Now();
- ASSERT_LT(now1.value(), now2.value());
-}
-
-// Tests the clock updates with the incoming value if it is higher.
-TEST_F(HybridClockTest, TestUpdate_LogicalValueIncreasesByAmount) {
- Timestamp now = clock_->Now();
- uint64_t now_micros = HybridClock::GetPhysicalValueMicros(now);
-
- // increase the logical value
- uint64_t logical = HybridClock::GetLogicalValue(now);
- logical += 10;
-
- // increase the physical value so that we're sure the clock will take this
- // one, 200 msecs should be more than enough.
- now_micros += 200000;
-
- Timestamp now_increased = HybridClock::TimestampFromMicrosecondsAndLogicalValue(now_micros,
- logical);
-
- ASSERT_OK(clock_->Update(now_increased));
-
- Timestamp now2 = clock_->Now();
- ASSERT_EQ(logical + 1, HybridClock::GetLogicalValue(now2));
- ASSERT_EQ(HybridClock::GetPhysicalValueMicros(now) + 200000,
- HybridClock::GetPhysicalValueMicros(now2));
-}
-
-// Test that the incoming event is in the past, i.e. less than now - max_error
-TEST_F(HybridClockTest, TestWaitUntilAfter_TestCase1) {
- MonoTime no_deadline;
- MonoTime before = MonoTime::Now();
-
- Timestamp past_ts;
- uint64_t max_error;
- clock_->NowWithError(&past_ts, &max_error);
-
- // make the event 3 * the max. possible error in the past
- Timestamp past_ts_changed = HybridClock::AddPhysicalTimeToTimestamp(
- past_ts,
- MonoDelta::FromMicroseconds(-3 * max_error));
-
- Status s = clock_->WaitUntilAfter(past_ts_changed, no_deadline);
-
- ASSERT_OK(s);
-
- MonoTime after = MonoTime::Now();
- MonoDelta delta = after - before;
- // The delta should be close to 0, but it takes some time for the hybrid
- // logical clock to decide that it doesn't need to wait.
- ASSERT_LT(delta.ToMicroseconds(), 25000);
-}
-
-// The normal case for transactions. Obtain a timestamp and then wait until
-// we're sure that tx_latest < now_earliest.
-TEST_F(HybridClockTest, TestWaitUntilAfter_TestCase2) {
- MonoTime before = MonoTime::Now();
-
- // we do no time adjustment, this event should fall right within the possible
- // error interval
- Timestamp past_ts;
- uint64_t past_max_error;
- clock_->NowWithError(&past_ts, &past_max_error);
- // Make sure the error is at least a small number of microseconds, to ensure
- // that we always have to wait.
- past_max_error = std::max(past_max_error, static_cast<uint64_t>(20));
- Timestamp wait_until = HybridClock::AddPhysicalTimeToTimestamp(
- past_ts,
- MonoDelta::FromMicroseconds(past_max_error));
-
- Timestamp current_ts;
- uint64_t current_max_error;
- clock_->NowWithError(¤t_ts, ¤t_max_error);
-
- // Check waiting with a deadline which already expired.
- {
- MonoTime deadline = before;
- Status s = clock_->WaitUntilAfter(wait_until, deadline);
- ASSERT_TRUE(s.IsTimedOut());
- }
-
- // Wait with a deadline well in the future. This should succeed.
- {
- MonoTime deadline = before + MonoDelta::FromSeconds(60);
- ASSERT_OK(clock_->WaitUntilAfter(wait_until, deadline));
- }
-
- MonoTime after = MonoTime::Now();
- MonoDelta delta = after - before;
-
- // In the common case current_max_error >= past_max_error and we should have waited
- // 2 * past_max_error, but if the clock's error is reset between the two reads we might
- // have waited less time, but always more than 'past_max_error'.
- if (current_max_error >= past_max_error) {
- ASSERT_GE(delta.ToMicroseconds(), 2 * past_max_error);
- } else {
- ASSERT_GE(delta.ToMicroseconds(), past_max_error);
- }
-}
-
-TEST_F(HybridClockTest, TestIsAfter) {
- Timestamp ts1 = clock_->Now();
- ASSERT_TRUE(clock_->IsAfter(ts1));
-
- // Update the clock in the future, make sure it still
- // handles "IsAfter" properly even when it's running in
- // "logical" mode.
- Timestamp now_increased = HybridClock::TimestampFromMicroseconds(
- HybridClock::GetPhysicalValueMicros(ts1) + 1 * 1000 * 1000);
- ASSERT_OK(clock_->Update(now_increased));
- Timestamp ts2 = clock_->Now();
-
- ASSERT_TRUE(clock_->IsAfter(ts1));
- ASSERT_TRUE(clock_->IsAfter(ts2));
-}
-
-// Thread which loops polling the clock and updating it slightly
-// into the future.
-void StresserThread(HybridClock* clock, AtomicBool* stop) {
- Random rng(GetRandomSeed32());
- Timestamp prev(0);;
- while (!stop->Load()) {
- Timestamp t = clock->Now();
- CHECK_GT(t.value(), prev.value());
- prev = t;
-
- // Add a random bit of offset to the clock, and perform an update.
- Timestamp new_ts = HybridClock::AddPhysicalTimeToTimestamp(
- t, MonoDelta::FromMicroseconds(rng.Uniform(10000)));
- clock->Update(new_ts);
- }
-}
-
-// Regression test for KUDU-953: if threads are updating and polling the
-// clock concurrently, the clock should still never run backwards.
-TEST_F(HybridClockTest, TestClockDoesntGoBackwardsWithUpdates) {
- vector<scoped_refptr<kudu::Thread> > threads;
-
- AtomicBool stop(false);
- for (int i = 0; i < 4; i++) {
- scoped_refptr<Thread> thread;
- ASSERT_OK(Thread::Create("test", "stresser",
- &StresserThread, clock_.get(), &stop,
- &thread));
- threads.push_back(thread);
- }
-
- SleepFor(MonoDelta::FromSeconds(1));
- stop.Store(true);
- for (const scoped_refptr<Thread> t : threads) {
- t->Join();
- }
-}
-
-TEST_F(HybridClockTest, TestGetPhysicalComponentDifference) {
- Timestamp now1 = HybridClock::TimestampFromMicrosecondsAndLogicalValue(100, 100);
- SleepFor(MonoDelta::FromMilliseconds(1));
- Timestamp now2 = HybridClock::TimestampFromMicrosecondsAndLogicalValue(200, 0);
- MonoDelta delta = clock_->GetPhysicalComponentDifference(now2, now1);
- MonoDelta negative_delta = clock_->GetPhysicalComponentDifference(now1, now2);
- ASSERT_EQ(100, delta.ToMicroseconds());
- ASSERT_EQ(-100, negative_delta.ToMicroseconds());
-}
-
-} // namespace server
-} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/hybrid_clock.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/hybrid_clock.cc b/src/kudu/server/hybrid_clock.cc
deleted file mode 100644
index 976bdc0..0000000
--- a/src/kudu/server/hybrid_clock.cc
+++ /dev/null
@@ -1,495 +0,0 @@
-// 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/server/hybrid_clock.h"
-
-#include <algorithm>
-#include <glog/logging.h>
-#include <mutex>
-
-#include "kudu/gutil/bind.h"
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/gutil/walltime.h"
-#include "kudu/util/debug/trace_event.h"
-#include "kudu/util/errno.h"
-#include "kudu/util/flag_tags.h"
-#include "kudu/util/locks.h"
-#include "kudu/util/logging.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/status.h"
-
-#if !defined(__APPLE__)
-#include <sys/timex.h>
-#endif // !defined(__APPLE__)
-
-DEFINE_int32(max_clock_sync_error_usec, 10 * 1000 * 1000, // 10 secs
- "Maximum allowed clock synchronization error as reported by NTP "
- "before the server will abort.");
-TAG_FLAG(max_clock_sync_error_usec, advanced);
-TAG_FLAG(max_clock_sync_error_usec, runtime);
-
-DEFINE_bool(use_hybrid_clock, true,
- "Whether HybridClock should be used as the default clock"
- " implementation. This should be disabled for testing purposes only.");
-TAG_FLAG(use_hybrid_clock, hidden);
-
-DEFINE_bool(use_mock_wall_clock, false,
- "Whether HybridClock should use a mock wall clock which is updated manually"
- "instead of reading time from the system clock, for tests.");
-TAG_FLAG(use_mock_wall_clock, hidden);
-
-METRIC_DEFINE_gauge_uint64(server, hybrid_clock_timestamp,
- "Hybrid Clock Timestamp",
- kudu::MetricUnit::kMicroseconds,
- "Hybrid clock timestamp.");
-METRIC_DEFINE_gauge_uint64(server, hybrid_clock_error,
- "Hybrid Clock Error",
- kudu::MetricUnit::kMicroseconds,
- "Server clock maximum error.");
-
-using kudu::Status;
-using strings::Substitute;
-
-namespace kudu {
-namespace server {
-
-namespace {
-
-#if !defined(__APPLE__)
-// Returns the clock modes and checks if the clock is synchronized.
-Status GetClockModes(timex* timex) {
- // this makes ntp_adjtime a read-only call
- timex->modes = 0;
- int rc = ntp_adjtime(timex);
- if (PREDICT_FALSE(rc == TIME_ERROR)) {
- return Status::ServiceUnavailable(
- Substitute("Error reading clock. Clock considered unsynchronized. Return code: $0", rc));
- }
- // TODO what to do about leap seconds? see KUDU-146
- if (PREDICT_FALSE(rc != TIME_OK)) {
- LOG(ERROR) << Substitute("TODO Server undergoing leap second. Return code: $0", rc);
- }
- return Status::OK();
-}
-
-// Returns the current time/max error and checks if the clock is synchronized.
-kudu::Status GetClockTime(ntptimeval* timeval) {
- int rc = ntp_gettime(timeval);
- switch (rc) {
- case TIME_OK:
- return Status::OK();
- case -1: // generic error
- return Status::ServiceUnavailable("Error reading clock. ntp_gettime() failed",
- ErrnoToString(errno));
- case TIME_ERROR:
- return Status::ServiceUnavailable("Error reading clock. Clock considered unsynchronized");
- default:
- // TODO what to do about leap seconds? see KUDU-146
- KLOG_FIRST_N(ERROR, 1) << "Server undergoing leap second. This may cause consistency issues "
- << "(rc=" << rc << ")";
- return Status::OK();
- }
-}
-#endif // !defined(__APPLE__)
-
-Status CheckDeadlineNotWithinMicros(const MonoTime& deadline, int64_t wait_for_usec) {
- if (!deadline.Initialized()) {
- // No deadline.
- return Status::OK();
- }
- int64_t us_until_deadline = (deadline - MonoTime::Now()).ToMicroseconds();
- if (us_until_deadline <= wait_for_usec) {
- return Status::TimedOut(Substitute(
- "specified time is $0us in the future, but deadline expires in $1us",
- wait_for_usec, us_until_deadline));
- }
- return Status::OK();
-}
-
-} // anonymous namespace
-
-// Left shifting 12 bits gives us 12 bits for the logical value
-// and should still keep accurate microseconds time until 2100+
-const int HybridClock::kBitsToShift = 12;
-// This mask gives us back the logical bits.
-const uint64_t HybridClock::kLogicalBitMask = (1 << kBitsToShift) - 1;
-
-const uint64_t HybridClock::kNanosPerSec = 1000000;
-
-const double HybridClock::kAdjtimexScalingFactor = 65536;
-
-HybridClock::HybridClock()
- : mock_clock_time_usec_(0),
- mock_clock_max_error_usec_(0),
-#if !defined(__APPLE__)
- divisor_(1),
-#endif
- tolerance_adjustment_(1),
- next_timestamp_(0),
- state_(kNotInitialized) {
-}
-
-Status HybridClock::Init() {
- if (PREDICT_FALSE(FLAGS_use_mock_wall_clock)) {
- LOG(WARNING) << "HybridClock set to mock the wall clock.";
- state_ = kInitialized;
- return Status::OK();
- }
-#if defined(__APPLE__)
- LOG(WARNING) << "HybridClock initialized in local mode (OS X only). "
- << "Not suitable for distributed clusters.";
-#else
- // Read the current time. This will return an error if the clock is not synchronized.
- uint64_t now_usec;
- uint64_t error_usec;
- RETURN_NOT_OK(WalltimeWithError(&now_usec, &error_usec));
-
- timex timex;
- RETURN_NOT_OK(GetClockModes(&timex));
- // read whether the STA_NANO bit is set to know whether we'll get back nanos
- // or micros in timeval.time.tv_usec. See:
- // http://stackoverflow.com/questions/16063408/does-ntp-gettime-actually-return-nanosecond-precision
- // set the timeval.time.tv_usec divisor so that we always get micros
- if (timex.status & STA_NANO) {
- divisor_ = 1000;
- } else {
- divisor_ = 1;
- }
-
- // Calculate the sleep skew adjustment according to the max tolerance of the clock.
- // Tolerance comes in parts per million but needs to be applied a scaling factor.
- tolerance_adjustment_ = (1 + ((timex.tolerance / kAdjtimexScalingFactor) / 1000000.0));
-
- LOG(INFO) << "HybridClock initialized. Resolution in nanos?: " << (divisor_ == 1000)
- << " Wait times tolerance adjustment: " << tolerance_adjustment_
- << " Current error: " << error_usec;
-#endif // defined(__APPLE__)
-
- state_ = kInitialized;
-
- return Status::OK();
-}
-
-Timestamp HybridClock::Now() {
- Timestamp now;
- uint64_t error;
-
- std::lock_guard<simple_spinlock> lock(lock_);
- NowWithError(&now, &error);
- return now;
-}
-
-Timestamp HybridClock::NowLatest() {
- Timestamp now;
- uint64_t error;
-
- {
- std::lock_guard<simple_spinlock> lock(lock_);
- NowWithError(&now, &error);
- }
-
- uint64_t now_latest = GetPhysicalValueMicros(now) + error;
- uint64_t now_logical = GetLogicalValue(now);
-
- return TimestampFromMicrosecondsAndLogicalValue(now_latest, now_logical);
-}
-
-Status HybridClock::GetGlobalLatest(Timestamp* t) {
- Timestamp now = Now();
- uint64_t now_latest = GetPhysicalValueMicros(now) + FLAGS_max_clock_sync_error_usec;
- uint64_t now_logical = GetLogicalValue(now);
- *t = TimestampFromMicrosecondsAndLogicalValue(now_latest, now_logical);
- return Status::OK();
-}
-
-void HybridClock::NowWithError(Timestamp* timestamp, uint64_t* max_error_usec) {
-
- DCHECK_EQ(state_, kInitialized) << "Clock not initialized. Must call Init() first.";
-
- uint64_t now_usec;
- uint64_t error_usec;
- Status s = WalltimeWithError(&now_usec, &error_usec);
- if (PREDICT_FALSE(!s.ok())) {
- LOG(FATAL) << Substitute("Couldn't get the current time: Clock unsynchronized. "
- "Status: $0", s.ToString());
- }
-
- // If the physical time from the system clock is higher than our last-returned
- // time, we should use the physical timestamp.
- uint64_t candidate_phys_timestamp = now_usec << kBitsToShift;
- if (PREDICT_TRUE(candidate_phys_timestamp > next_timestamp_)) {
- next_timestamp_ = candidate_phys_timestamp;
- *timestamp = Timestamp(next_timestamp_++);
- *max_error_usec = error_usec;
- if (PREDICT_FALSE(VLOG_IS_ON(2))) {
- VLOG(2) << "Current clock is higher than the last one. Resetting logical values."
- << " Physical Value: " << now_usec << " usec Logical Value: 0 Error: "
- << error_usec;
- }
- return;
- }
-
- // We don't have the last time read max error since it might have originated
- // in another machine, but we can put a bound on the maximum error of the
- // timestamp we are providing.
- // In particular we know that the "true" time falls within the interval
- // now_usec +- now.maxerror so we get the following situations:
- //
- // 1)
- // --------|----------|----|---------|--------------------------> time
- // now - e now last now + e
- // 2)
- // --------|----------|--------------|------|-------------------> time
- // now - e now now + e last
- //
- // Assuming, in the worst case, that the "true" time is now - error we need to
- // always return: last - (now - e) as the new maximum error.
- // This broadens the error interval for both cases but always returns
- // a correct error interval.
-
- *max_error_usec = (next_timestamp_ >> kBitsToShift) - (now_usec - error_usec);
- *timestamp = Timestamp(next_timestamp_++);
- if (PREDICT_FALSE(VLOG_IS_ON(2))) {
- VLOG(2) << "Current clock is lower than the last one. Returning last read and incrementing"
- " logical values. Clock: " + Stringify(*timestamp) << " Error: " << *max_error_usec;
- }
-}
-
-Status HybridClock::Update(const Timestamp& to_update) {
- std::lock_guard<simple_spinlock> lock(lock_);
- Timestamp now;
- uint64_t error_ignored;
- NowWithError(&now, &error_ignored);
-
- // If the incoming message is in the past relative to our current
- // physical clock, there's nothing to do.
- if (PREDICT_TRUE(now > to_update)) {
- return Status::OK();
- }
-
- uint64_t to_update_physical = GetPhysicalValueMicros(to_update);
- uint64_t now_physical = GetPhysicalValueMicros(now);
-
- // we won't update our clock if to_update is more than 'max_clock_sync_error_usec'
- // into the future as it might have been corrupted or originated from an out-of-sync
- // server.
- if ((to_update_physical - now_physical) > FLAGS_max_clock_sync_error_usec) {
- return Status::InvalidArgument("Tried to update clock beyond the max. error.");
- }
-
- // Our next timestamp must be higher than the one that we are updating
- // from.
- next_timestamp_ = to_update.value() + 1;
- return Status::OK();
-}
-
-bool HybridClock::SupportsExternalConsistencyMode(ExternalConsistencyMode mode) {
- return true;
-}
-
-bool HybridClock::HasPhysicalComponent() const {
- return true;
-}
-
-MonoDelta HybridClock::GetPhysicalComponentDifference(Timestamp lhs, Timestamp rhs) const {
- return MonoDelta::FromMicroseconds(GetPhysicalValueMicros(lhs) - GetPhysicalValueMicros(rhs));
-}
-
-Status HybridClock::WaitUntilAfter(const Timestamp& then,
- const MonoTime& deadline) {
- TRACE_EVENT0("clock", "HybridClock::WaitUntilAfter");
- Timestamp now;
- uint64_t error;
- {
- std::lock_guard<simple_spinlock> lock(lock_);
- NowWithError(&now, &error);
- }
-
- // "unshift" the timestamps so that we can measure actual time
- uint64_t now_usec = GetPhysicalValueMicros(now);
- uint64_t then_latest_usec = GetPhysicalValueMicros(then);
-
- uint64_t now_earliest_usec = now_usec - error;
-
- // Case 1, event happened definitely in the past, return
- if (PREDICT_TRUE(then_latest_usec < now_earliest_usec)) {
- return Status::OK();
- }
-
- // Case 2 wait out until we are sure that then has passed
-
- // We'll sleep then_latest_usec - now_earliest_usec so that the new
- // nw.earliest is higher than then.latest.
- uint64_t wait_for_usec = (then_latest_usec - now_earliest_usec);
-
- // Additionally adjust the sleep time with the max tolerance adjustment
- // to account for the worst case clock skew while we're sleeping.
- wait_for_usec *= tolerance_adjustment_;
-
- // Check that sleeping wouldn't sleep longer than our deadline.
- RETURN_NOT_OK(CheckDeadlineNotWithinMicros(deadline, wait_for_usec));
-
- SleepFor(MonoDelta::FromMicroseconds(wait_for_usec));
-
-
- VLOG(1) << "WaitUntilAfter(): Incoming time(latest): " << then_latest_usec
- << " Now(earliest): " << now_earliest_usec << " error: " << error
- << " Waiting for: " << wait_for_usec;
-
- return Status::OK();
-}
-
-Status HybridClock::WaitUntilAfterLocally(const Timestamp& then,
- const MonoTime& deadline) {
- while (true) {
- Timestamp now;
- uint64_t error;
- {
- std::lock_guard<simple_spinlock> lock(lock_);
- NowWithError(&now, &error);
- }
- if (now > then) {
- return Status::OK();
- }
- uint64_t wait_for_usec = GetPhysicalValueMicros(then) - GetPhysicalValueMicros(now);
-
- // Check that sleeping wouldn't sleep longer than our deadline.
- RETURN_NOT_OK(CheckDeadlineNotWithinMicros(deadline, wait_for_usec));
- }
-}
-
-bool HybridClock::IsAfter(Timestamp t) {
- // Manually get the time, rather than using Now(), so we don't end up causing
- // a time update.
- uint64_t now_usec;
- uint64_t error_usec;
- CHECK_OK(WalltimeWithError(&now_usec, &error_usec));
-
- Timestamp now;
- {
- std::lock_guard<simple_spinlock> lock(lock_);
- now = Timestamp(std::max(next_timestamp_, now_usec << kBitsToShift));
- }
- return t.value() < now.value();
-}
-
-kudu::Status HybridClock::WalltimeWithError(uint64_t* now_usec, uint64_t* error_usec) {
- if (PREDICT_FALSE(FLAGS_use_mock_wall_clock)) {
- VLOG(1) << "Current clock time: " << mock_clock_time_usec_ << " error: "
- << mock_clock_max_error_usec_ << ". Updating to time: " << now_usec
- << " and error: " << error_usec;
- *now_usec = mock_clock_time_usec_;
- *error_usec = mock_clock_max_error_usec_;
- } else {
-#if defined(__APPLE__)
- *now_usec = GetCurrentTimeMicros();
- *error_usec = 0;
- }
-#else
- // Read the time. This will return an error if the clock is not synchronized.
- ntptimeval timeval;
- RETURN_NOT_OK(GetClockTime(&timeval));
- *now_usec = timeval.time.tv_sec * kNanosPerSec + timeval.time.tv_usec / divisor_;
- *error_usec = timeval.maxerror;
- }
-
- // If the clock is synchronized but has max_error beyond max_clock_sync_error_usec
- // we also return a non-ok status.
- if (*error_usec > FLAGS_max_clock_sync_error_usec) {
- return Status::ServiceUnavailable(Substitute("Error: Clock synchronized but error was"
- "too high ($0 us).", *error_usec));
- }
-#endif // defined(__APPLE__)
- return kudu::Status::OK();
-}
-
-void HybridClock::SetMockClockWallTimeForTests(uint64_t now_usec) {
- CHECK(FLAGS_use_mock_wall_clock);
- std::lock_guard<simple_spinlock> lock(lock_);
- CHECK_GE(now_usec, mock_clock_time_usec_);
- mock_clock_time_usec_ = now_usec;
-}
-
-void HybridClock::SetMockMaxClockErrorForTests(uint64_t max_error_usec) {
- CHECK(FLAGS_use_mock_wall_clock);
- std::lock_guard<simple_spinlock> lock(lock_);
- mock_clock_max_error_usec_ = max_error_usec;
-}
-
-// Used to get the timestamp for metrics.
-uint64_t HybridClock::NowForMetrics() {
- return Now().ToUint64();
-}
-
-// Used to get the current error, for metrics.
-uint64_t HybridClock::ErrorForMetrics() {
- Timestamp now;
- uint64_t error;
-
- std::lock_guard<simple_spinlock> lock(lock_);
- NowWithError(&now, &error);
- return error;
-}
-
-void HybridClock::RegisterMetrics(const scoped_refptr<MetricEntity>& metric_entity) {
- METRIC_hybrid_clock_timestamp.InstantiateFunctionGauge(
- metric_entity,
- Bind(&HybridClock::NowForMetrics, Unretained(this)))
- ->AutoDetachToLastValue(&metric_detacher_);
- METRIC_hybrid_clock_error.InstantiateFunctionGauge(
- metric_entity,
- Bind(&HybridClock::ErrorForMetrics, Unretained(this)))
- ->AutoDetachToLastValue(&metric_detacher_);
-}
-
-string HybridClock::Stringify(Timestamp timestamp) {
- return StringifyTimestamp(timestamp);
-}
-
-uint64_t HybridClock::GetLogicalValue(const Timestamp& timestamp) {
- return timestamp.value() & kLogicalBitMask;
-}
-
-uint64_t HybridClock::GetPhysicalValueMicros(const Timestamp& timestamp) {
- return timestamp.value() >> kBitsToShift;
-}
-
-Timestamp HybridClock::TimestampFromMicroseconds(uint64_t micros) {
- return Timestamp(micros << kBitsToShift);
-}
-
-Timestamp HybridClock::TimestampFromMicrosecondsAndLogicalValue(
- uint64_t micros,
- uint64_t logical_value) {
- return Timestamp((micros << kBitsToShift) + logical_value);
-}
-
-Timestamp HybridClock::AddPhysicalTimeToTimestamp(const Timestamp& original,
- const MonoDelta& to_add) {
- uint64_t new_physical = GetPhysicalValueMicros(original) + to_add.ToMicroseconds();
- uint64_t old_logical = GetLogicalValue(original);
- return TimestampFromMicrosecondsAndLogicalValue(new_physical, old_logical);
-}
-
-string HybridClock::StringifyTimestamp(const Timestamp& timestamp) {
- return Substitute("P: $0 usec, L: $1",
- GetPhysicalValueMicros(timestamp),
- GetLogicalValue(timestamp));
-}
-
-} // namespace server
-} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/hybrid_clock.h
----------------------------------------------------------------------
diff --git a/src/kudu/server/hybrid_clock.h b/src/kudu/server/hybrid_clock.h
deleted file mode 100644
index c2e1e62..0000000
--- a/src/kudu/server/hybrid_clock.h
+++ /dev/null
@@ -1,228 +0,0 @@
-// 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.
-
-#ifndef KUDU_SERVER_HYBRID_CLOCK_H_
-#define KUDU_SERVER_HYBRID_CLOCK_H_
-
-#include <string>
-
-#include "kudu/gutil/ref_counted.h"
-#include "kudu/server/clock.h"
-#include "kudu/util/locks.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-namespace server {
-
-// The HybridTime clock.
-//
-// HybridTime should not be used on a distributed cluster running on OS X hosts,
-// since NTP clock error is not available.
-class HybridClock : public Clock {
- public:
- HybridClock();
-
- virtual Status Init() OVERRIDE;
-
- // Obtains the timestamp corresponding to the current time.
- virtual Timestamp Now() OVERRIDE;
-
- // Obtains the timestamp corresponding to latest possible current
- // time.
- virtual Timestamp NowLatest() OVERRIDE;
-
- // Obtain a timestamp which is guaranteed to be later than the current time
- // on any machine in the cluster.
- //
- // NOTE: this is not a very tight bound.
- virtual Status GetGlobalLatest(Timestamp* t) OVERRIDE;
-
- // Updates the clock with a timestamp originating on another machine.
- virtual Status Update(const Timestamp& to_update) OVERRIDE;
-
- virtual void RegisterMetrics(const scoped_refptr<MetricEntity>& metric_entity) OVERRIDE;
-
- // HybridClock supports all external consistency modes.
- virtual bool SupportsExternalConsistencyMode(ExternalConsistencyMode mode) OVERRIDE;
-
- virtual bool HasPhysicalComponent() const OVERRIDE;
-
- MonoDelta GetPhysicalComponentDifference(Timestamp lhs, Timestamp rhs) const OVERRIDE;
-
- // Blocks the caller thread until the true time is after 'then'.
- // In other words, waits until the HybridClock::Now() on _all_ nodes
- // will return a value greater than 'then'.
- //
- // The incoming time 'then' is assumed to be the latest time possible
- // at the time the read was performed, i.e. 'then' = now + max_error.
- //
- // This method can be used to make Kudu behave like Spanner/TrueTime.
- // This is implemented by possibly making the caller thread wait for a
- // a certain period of time.
- //
- // As an example, the following cases might happen:
- //
- // 1 - 'then' is lower than now.earliest() -> Definitely in
- // the past, no wait necessary.
- //
- // 2 - 'then' is greater than > now.earliest(): need to wait until
- // 'then' <= now.earliest()
- //
- // Returns OK if it waited long enough or if no wait was necessary.
- //
- // Returns Status::ServiceUnavailable if the system clock was not
- // synchronized and therefore it couldn't wait out the error.
- //
- // Returns Status::TimedOut() if 'deadline' will pass before the specified
- // timestamp. NOTE: unlike most "wait" methods, this may return _immediately_
- // with a timeout, rather than actually waiting for the timeout to expire.
- // This is because, by looking at the current clock, we can know how long
- // we'll have to wait, in contrast to most Wait() methods which are waiting
- // on some external condition to become true.
- virtual Status WaitUntilAfter(const Timestamp& then,
- const MonoTime& deadline) OVERRIDE;
-
- // Blocks the caller thread until the local time is after 'then'.
- // This is in contrast to the above method, which waits until the time
- // on _all_ machines is past the given time.
- //
- // Returns Status::TimedOut() if 'deadline' will pass before the specified
- // timestamp. NOTE: unlike most "wait" methods, this may return _immediately_
- // with a timeout. See WaitUntilAfter() for details.
- virtual Status WaitUntilAfterLocally(const Timestamp& then,
- const MonoTime& deadline) OVERRIDE;
-
- // Return true if the given time has passed (i.e any future call
- // to Now() would return a higher value than t).
- //
- // NOTE: this only refers to the _local_ clock, and is not a guarantee
- // that other nodes' clocks have definitely passed this timestamp.
- // This is in contrast to WaitUntilAfter() above.
- virtual bool IsAfter(Timestamp t) OVERRIDE;
-
- // Obtains the timestamp corresponding to the current time and the associated
- // error in micros. This may fail if the clock is unsynchronized or synchronized
- // but the error is too high and, since we can't do anything about it,
- // LOG(FATAL)'s in that case.
- void NowWithError(Timestamp* timestamp, uint64_t* max_error_usec);
-
- virtual std::string Stringify(Timestamp timestamp) OVERRIDE;
-
- // Static encoding/decoding methods for timestamps. Public mostly
- // for testing/debugging purposes.
-
- // Returns the logical value embedded in 'timestamp'
- static uint64_t GetLogicalValue(const Timestamp& timestamp);
-
- // Returns the physical value embedded in 'timestamp', in microseconds.
- static uint64_t GetPhysicalValueMicros(const Timestamp& timestamp);
-
- // Obtains a new Timestamp with the logical value zeroed out.
- static Timestamp TimestampFromMicroseconds(uint64_t micros);
-
- // Obtains a new Timestamp that embeds both the physical and logical values.
- static Timestamp TimestampFromMicrosecondsAndLogicalValue(uint64_t micros,
- uint64_t logical_value);
-
- // Creates a new timestamp whose physical time is GetPhysicalValue(original) +
- // 'to_add' and which retains the same logical value.
- static Timestamp AddPhysicalTimeToTimestamp(const Timestamp& original,
- const MonoDelta& to_add);
-
- // Outputs a string containing the physical and logical values of the timestamp,
- // separated.
- static std::string StringifyTimestamp(const Timestamp& timestamp);
-
- // Sets the time to be returned by a mock call to the system clock, for tests.
- // Requires that 'FLAGS_use_mock_wall_clock' is set to true and that 'now_usec' is higher
- // than the previously set time.
- // NOTE: This refers to the time returned by the system clock, not the time returned
- // by HybridClock, i.e. 'now_usec' is not a HybridTime timestmap and shouldn't have
- // a logical component.
- void SetMockClockWallTimeForTests(uint64_t now_usec);
-
- // Sets the max. error to be returned by a mock call to the system clock, for tests.
- // Requires that 'FLAGS_use_mock_wall_clock' is set to true.
- // This can be used to make HybridClock report the wall clock as unsynchronized, by
- // setting error to be more than the configured tolerance.
- void SetMockMaxClockErrorForTests(uint64_t max_error_usec);
-
- private:
-
- // Obtains the current wallclock time and maximum error in microseconds,
- // and checks if the clock is synchronized.
- //
- // On OS X, the error will always be 0.
- kudu::Status WalltimeWithError(uint64_t* now_usec, uint64_t* error_usec);
-
- // Used to get the timestamp for metrics.
- uint64_t NowForMetrics();
-
- // Used to get the current error, for metrics.
- uint64_t ErrorForMetrics();
-
- // Set by calls to SetMockClockWallTimeForTests().
- // For testing purposes only.
- uint64_t mock_clock_time_usec_;
-
- // Set by calls to SetMockClockErrorForTests().
- // For testing purposes only.
- uint64_t mock_clock_max_error_usec_;
-
-#if !defined(__APPLE__)
- uint64_t divisor_;
-#endif
-
- double tolerance_adjustment_;
-
- mutable simple_spinlock lock_;
-
- // The next timestamp to be generated from this clock, assuming that
- // the physical clock hasn't advanced beyond the value stored here.
- uint64_t next_timestamp_;
-
- // How many bits to left shift a microseconds clock read. The remainder
- // of the timestamp will be reserved for logical values.
- static const int kBitsToShift;
-
- // Mask to extract the pure logical bits.
- static const uint64_t kLogicalBitMask;
-
- static const uint64_t kNanosPerSec;
-
- // The scaling factor used to obtain ppms. From the adjtimex source:
- // "scale factor used by adjtimex freq param. 1 ppm = 65536"
- static const double kAdjtimexScalingFactor;
-
- enum State {
- kNotInitialized,
- kInitialized
- };
-
- State state_;
-
- // Clock metrics are set to detach to their last value. This means
- // that, during our destructor, we'll need to access other class members
- // declared above this. Hence, this member must be declared last.
- FunctionGaugeDetacher metric_detacher_;
-};
-
-} // namespace server
-} // namespace kudu
-
-#endif /* KUDU_SERVER_HYBRID_CLOCK_H_ */
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/logical_clock-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/logical_clock-test.cc b/src/kudu/server/logical_clock-test.cc
deleted file mode 100644
index 2635c2f..0000000
--- a/src/kudu/server/logical_clock-test.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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 <glog/logging.h>
-#include <gtest/gtest.h>
-
-#include "kudu/server/logical_clock.h"
-#include "kudu/util/monotime.h"
-#include "kudu/util/test_util.h"
-
-namespace kudu {
-namespace server {
-
-class LogicalClockTest : public KuduTest {
- public:
- LogicalClockTest()
- : clock_(LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
- }
-
- protected:
- scoped_refptr<LogicalClock> clock_;
-};
-
-// Test that two subsequent time reads are monotonically increasing.
-TEST_F(LogicalClockTest, TestNow_ValuesIncreaseMonotonically) {
- const Timestamp now1 = clock_->Now();
- const Timestamp now2 = clock_->Now();
- ASSERT_EQ(now1.value() + 1, now2.value());
-}
-
-// Tests that the clock gets updated if the incoming value is higher.
-TEST_F(LogicalClockTest, TestUpdate_LogicalValueIncreasesByAmount) {
- Timestamp initial = clock_->Now();
- Timestamp future(initial.value() + 10);
- clock_->Update(future);
- Timestamp now = clock_->Now();
- // now should be 1 after future
- ASSERT_EQ(initial.value() + 11, now.value());
-}
-
-// Tests that the clock doesn't get updated if the incoming value is lower.
-TEST_F(LogicalClockTest, TestUpdate_LogicalValueDoesNotIncrease) {
- Timestamp ts(1);
- // update the clock to 1, the initial value, should do nothing
- clock_->Update(ts);
- Timestamp now = clock_->Now();
- ASSERT_EQ(now.value(), 2);
-}
-
-TEST_F(LogicalClockTest, TestWaitUntilAfterIsUnavailable) {
- Status status = clock_->WaitUntilAfter(
- Timestamp(10), MonoTime::Now());
- ASSERT_TRUE(status.IsServiceUnavailable());
-}
-
-TEST_F(LogicalClockTest, TestIsAfter) {
- Timestamp ts1 = clock_->Now();
- ASSERT_TRUE(clock_->IsAfter(ts1));
-
- // Update the clock in the future, make sure it still
- // handles "IsAfter" properly even when it's running in
- // "logical" mode.
- Timestamp now_increased = Timestamp(1000);
- ASSERT_OK(clock_->Update(now_increased));
- Timestamp ts2 = clock_->Now();
-
- ASSERT_TRUE(clock_->IsAfter(ts1));
- ASSERT_TRUE(clock_->IsAfter(ts2));
-}
-
-} // namespace server
-} // namespace kudu
-
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/logical_clock.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/logical_clock.cc b/src/kudu/server/logical_clock.cc
deleted file mode 100644
index ca3a30e..0000000
--- a/src/kudu/server/logical_clock.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// 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/server/logical_clock.h"
-
-#include "kudu/gutil/atomicops.h"
-#include "kudu/gutil/bind.h"
-#include "kudu/gutil/strings/substitute.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/monotime.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-namespace server {
-
-METRIC_DEFINE_gauge_uint64(server, logical_clock_timestamp,
- "Logical Clock Timestamp",
- kudu::MetricUnit::kUnits,
- "Logical clock timestamp.");
-
-using base::subtle::Atomic64;
-using base::subtle::Barrier_AtomicIncrement;
-using base::subtle::NoBarrier_CompareAndSwap;
-
-Timestamp LogicalClock::Now() {
- return Timestamp(Barrier_AtomicIncrement(&now_, 1));
-}
-
-Timestamp LogicalClock::NowLatest() {
- return Now();
-}
-
-Status LogicalClock::Update(const Timestamp& to_update) {
- DCHECK_NE(to_update.value(), Timestamp::kInvalidTimestamp.value())
- << "Updating the clock with an invalid timestamp";
- Atomic64 new_value = to_update.value();
-
- while (true) {
- Atomic64 current_value = NoBarrier_Load(&now_);
- // if the incoming value is less than the current one, or we've failed the
- // CAS because the current clock increased to higher than the incoming value,
- // we can stop the loop now.
- if (new_value <= current_value) return Status::OK();
- // otherwise try a CAS
- if (PREDICT_TRUE(NoBarrier_CompareAndSwap(&now_, current_value, new_value)
- == current_value))
- break;
- }
- return Status::OK();
-}
-
-Status LogicalClock::WaitUntilAfter(const Timestamp& then,
- const MonoTime& deadline) {
- return Status::ServiceUnavailable(
- "Logical clock does not support WaitUntilAfter()");
-}
-
-Status LogicalClock::WaitUntilAfterLocally(const Timestamp& then,
- const MonoTime& deadline) {
- if (IsAfter(then)) return Status::OK();
- return Status::ServiceUnavailable(
- "Logical clock does not support WaitUntilAfterLocally()");
-}
-
-bool LogicalClock::IsAfter(Timestamp t) {
- return base::subtle::Acquire_Load(&now_) >= t.value();
-}
-
-LogicalClock* LogicalClock::CreateStartingAt(const Timestamp& timestamp) {
- // initialize at 'timestamp' - 1 so that the first output value is 'timestamp'.
- return new LogicalClock(timestamp.value() - 1);
-}
-
-uint64_t LogicalClock::GetCurrentTime() {
- // We don't want reading metrics to change the clock.
- return NoBarrier_Load(&now_);
-}
-
-void LogicalClock::RegisterMetrics(const scoped_refptr<MetricEntity>& metric_entity) {
- METRIC_logical_clock_timestamp.InstantiateFunctionGauge(
- metric_entity,
- Bind(&LogicalClock::GetCurrentTime, Unretained(this)))
- ->AutoDetachToLastValue(&metric_detacher_);
-}
-
-string LogicalClock::Stringify(Timestamp timestamp) {
- return strings::Substitute("L: $0", timestamp.ToUint64());
-}
-
-} // namespace server
-} // namespace kudu
-
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/logical_clock.h
----------------------------------------------------------------------
diff --git a/src/kudu/server/logical_clock.h b/src/kudu/server/logical_clock.h
deleted file mode 100644
index 8f5ac33..0000000
--- a/src/kudu/server/logical_clock.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// 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.
-
-#ifndef KUDU_SERVER_LOGICAL_CLOCK_H_
-#define KUDU_SERVER_LOGICAL_CLOCK_H_
-
-#include <string>
-
-#include "kudu/server/clock.h"
-#include "kudu/util/metrics.h"
-#include "kudu/util/status.h"
-
-namespace kudu {
-class MonoDelta;
-class MonoTime;
-namespace server {
-
-// An implementation of Clock that behaves as a plain Lamport Clock.
-// In a single node, single tablet, setting this generates exactly the
-// same Timestamp sequence as the original MvccManager did, but it can be
-// updated to make sure replicas generate new timestamps on becoming leader.
-// This can be used as a deterministic timestamp generator that has the same
-// consistency properties as a HybridTime clock.
-//
-// The Wait* methods are unavailable in this implementation and will
-// return Status::ServiceUnavailable().
-//
-// NOTE: this class is thread safe.
-class LogicalClock : public Clock {
- public:
-
- virtual Status Init() OVERRIDE { return Status::OK(); }
-
- virtual Timestamp Now() OVERRIDE;
-
- // In the logical clock this call is equivalent to Now();
- virtual Timestamp NowLatest() OVERRIDE;
-
- virtual Status Update(const Timestamp& to_update) OVERRIDE;
-
- // The Wait*() functions are not available for this clock.
- virtual Status WaitUntilAfter(const Timestamp& then,
- const MonoTime& deadline) OVERRIDE;
- virtual Status WaitUntilAfterLocally(const Timestamp& then,
- const MonoTime& deadline) OVERRIDE;
-
- virtual bool IsAfter(Timestamp t) OVERRIDE;
-
- virtual void RegisterMetrics(const scoped_refptr<MetricEntity>& metric_entity) OVERRIDE;
-
- virtual std::string Stringify(Timestamp timestamp) OVERRIDE;
-
- // Used to get the timestamp without incrementing the logical component.
- // Mostly used for tests/metrics.
- uint64_t GetCurrentTime();
-
- // Logical clock doesn't support COMMIT_WAIT.
- virtual bool SupportsExternalConsistencyMode(ExternalConsistencyMode mode) OVERRIDE {
- return mode != COMMIT_WAIT;
- }
-
- // Creates a logical clock whose first output value on a Now() call is 'timestamp'.
- static LogicalClock* CreateStartingAt(const Timestamp& timestamp);
-
- private:
- // Should use LogicalClock::CreatingStartingAt()
- explicit LogicalClock(Timestamp::val_type initial_time) : now_(initial_time) {}
-
- base::subtle::Atomic64 now_;
-
- FunctionGaugeDetacher metric_detacher_;
-};
-
-} // namespace server
-} // namespace kudu
-
-#endif /* KUDU_SERVER_LOGICAL_CLOCK_H_ */
-
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/server_base.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/server_base.cc b/src/kudu/server/server_base.cc
index 7ffbf46..47c9777 100644
--- a/src/kudu/server/server_base.cc
+++ b/src/kudu/server/server_base.cc
@@ -24,6 +24,8 @@
#include <boost/optional.hpp>
#include <gflags/gflags.h>
+#include "kudu/clock/hybrid_clock.h"
+#include "kudu/clock/logical_clock.h"
#include "kudu/codegen/compilation_manager.h"
#include "kudu/common/wire_protocol.h"
#include "kudu/common/wire_protocol.pb.h"
@@ -36,13 +38,11 @@
#include "kudu/rpc/messenger.h"
#include "kudu/rpc/remote_user.h"
#include "kudu/rpc/rpc_context.h"
-#include "kudu/security/kerberos_util.h"
#include "kudu/security/init.h"
+#include "kudu/security/kerberos_util.h"
#include "kudu/server/default-path-handlers.h"
#include "kudu/server/generic_service.h"
#include "kudu/server/glog_metrics.h"
-#include "kudu/server/hybrid_clock.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/server/rpc_server.h"
#include "kudu/server/rpcz-path-handler.h"
#include "kudu/server/server_base.pb.h"
@@ -148,9 +148,9 @@ ServerBase::ServerBase(string name, const ServerBaseOptions& options,
fs_manager_.reset(new FsManager(options.env, fs_opts));
if (FLAGS_use_hybrid_clock) {
- clock_ = new HybridClock();
+ clock_ = new clock::HybridClock();
} else {
- clock_ = LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp);
+ clock_ = clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp);
}
if (FLAGS_webserver_enabled) {
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/server/server_base.h
----------------------------------------------------------------------
diff --git a/src/kudu/server/server_base.h b/src/kudu/server/server_base.h
index b0095db..7e81c12 100644
--- a/src/kudu/server/server_base.h
+++ b/src/kudu/server/server_base.h
@@ -44,6 +44,10 @@ class Sockaddr;
class Thread;
class Webserver;
+namespace clock {
+class Clock;
+} // namespace clock
+
namespace rpc {
class RpcContext;
} // namespace rpc
@@ -54,8 +58,6 @@ class TokenVerifier;
} // namespace security
namespace server {
-class Clock;
-
struct ServerBaseOptions;
class ServerStatusPB;
@@ -97,7 +99,7 @@ class ServerBase {
const scoped_refptr<rpc::ResultTracker>& result_tracker() const { return result_tracker_; }
// Returns this server's clock.
- Clock* clock() { return clock_.get(); }
+ clock::Clock* clock() { return clock_.get(); }
// Return a PB describing the status of the server (version info, bound ports, etc)
void GetStatusPB(ServerStatusPB* status) const;
@@ -169,7 +171,7 @@ class ServerBase {
scoped_refptr<rpc::ResultTracker> result_tracker_;
bool is_first_run_;
- scoped_refptr<Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
// The instance identifier of this server.
gscoped_ptr<NodeInstancePB> instance_pb_;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/CMakeLists.txt b/src/kudu/tablet/CMakeLists.txt
index c54ba43..3d1062d 100644
--- a/src/kudu/tablet/CMakeLists.txt
+++ b/src/kudu/tablet/CMakeLists.txt
@@ -74,12 +74,12 @@ ADD_EXPORTABLE_LIBRARY(tablet_proto
add_library(tablet ${TABLET_SRCS})
target_link_libraries(tablet
+ clock
tablet_proto
codegen
kudu_common
cfile
gutil
- server_common
kudu_fs
kudu_util
consensus)
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/compaction-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/compaction-test.cc b/src/kudu/tablet/compaction-test.cc
index 52649f9..e2d389c 100644
--- a/src/kudu/tablet/compaction-test.cc
+++ b/src/kudu/tablet/compaction-test.cc
@@ -22,6 +22,7 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/partial_row.h"
#include "kudu/consensus/log_anchor_registry.h"
#include "kudu/consensus/opid_util.h"
@@ -29,7 +30,6 @@
#include "kudu/fs/log_block_manager.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/gutil/strings/util.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/tablet/compaction.h"
#include "kudu/tablet/local_tablet_writer.h"
#include "kudu/tablet/tablet-test-util.h"
@@ -70,7 +70,7 @@ class TestCompaction : public KuduRowSetTest {
op_id_(consensus::MaximumOpId()),
row_builder_(schema_),
arena_(32*1024, 128*1024),
- clock_(server::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)),
+ clock_(clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)),
log_anchor_registry_(new log::LogAnchorRegistry()) {
}
@@ -434,7 +434,7 @@ class TestCompaction : public KuduRowSetTest {
RowBuilder row_builder_;
char key_buf_[256];
Arena arena_;
- scoped_refptr<server::LogicalClock> clock_;
+ scoped_refptr<clock::LogicalClock> clock_;
MvccManager mvcc_;
scoped_refptr<LogAnchorRegistry> log_anchor_registry_;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/compaction.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/compaction.cc b/src/kudu/tablet/compaction.cc
index 4621b6c..a39e17c 100644
--- a/src/kudu/tablet/compaction.cc
+++ b/src/kudu/tablet/compaction.cc
@@ -24,13 +24,13 @@
#include <unordered_set>
#include <vector>
+#include "kudu/clock/hybrid_clock.h"
#include "kudu/common/wire_protocol.h"
#include "kudu/consensus/opid_util.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/stl_util.h"
#include "kudu/gutil/strings/substitute.h"
-#include "kudu/server/hybrid_clock.h"
#include "kudu/tablet/cfile_set.h"
#include "kudu/tablet/delta_store.h"
#include "kudu/tablet/delta_tracker.h"
@@ -39,7 +39,7 @@
#include "kudu/tablet/transactions/write_transaction.h"
#include "kudu/util/debug/trace_event.h"
-using kudu::server::HybridClock;
+using kudu::clock::HybridClock;
using std::shared_ptr;
using std::unique_ptr;
using std::unordered_set;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/deltamemstore-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/deltamemstore-test.cc b/src/kudu/tablet/deltamemstore-test.cc
index b61e1a1..1471359 100644
--- a/src/kudu/tablet/deltamemstore-test.cc
+++ b/src/kudu/tablet/deltamemstore-test.cc
@@ -20,14 +20,14 @@
#include <stdlib.h>
#include <unordered_set>
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/schema.h"
#include "kudu/consensus/consensus.pb.h"
#include "kudu/consensus/opid_util.h"
#include "kudu/gutil/casts.h"
#include "kudu/gutil/gscoped_ptr.h"
-#include "kudu/server/logical_clock.h"
-#include "kudu/tablet/deltamemstore.h"
#include "kudu/tablet/deltafile.h"
+#include "kudu/tablet/deltamemstore.h"
#include "kudu/tablet/mutation.h"
#include "kudu/util/mem_tracker.h"
#include "kudu/util/stopwatch.h"
@@ -50,7 +50,7 @@ class TestDeltaMemStore : public KuduTest {
TestDeltaMemStore()
: op_id_(consensus::MaximumOpId()),
schema_(CreateSchema()),
- clock_(server::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
+ clock_(clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
CHECK_OK(DeltaMemStore::Create(0, 0,
new log::LogAnchorRegistry(),
MemTracker::GetRootTracker(), &dms_));
@@ -122,7 +122,7 @@ class TestDeltaMemStore : public KuduTest {
const Schema schema_;
shared_ptr<DeltaMemStore> dms_;
- scoped_refptr<server::Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
MvccManager mvcc_;
gscoped_ptr<FsManager> fs_manager_;
};
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/diskrowset-test-base.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/diskrowset-test-base.h b/src/kudu/tablet/diskrowset-test-base.h
index 6d2b7eb..927cd7c 100644
--- a/src/kudu/tablet/diskrowset-test-base.h
+++ b/src/kudu/tablet/diskrowset-test-base.h
@@ -27,6 +27,8 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/clock/clock.h"
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/iterator.h"
#include "kudu/common/rowblock.h"
#include "kudu/common/scan_spec.h"
@@ -34,8 +36,6 @@
#include "kudu/consensus/log_util.h"
#include "kudu/consensus/opid_util.h"
#include "kudu/gutil/stringprintf.h"
-#include "kudu/server/clock.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/tablet/diskrowset.h"
#include "kudu/tablet/tablet-test-util.h"
#include "kudu/tablet/tablet_mem_trackers.h"
@@ -61,7 +61,7 @@ class TestRowSet : public KuduRowSetTest {
: KuduRowSetTest(CreateTestSchema()),
n_rows_(FLAGS_roundtrip_num_rows),
op_id_(consensus::MaximumOpId()),
- clock_(server::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
+ clock_(clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
CHECK_GT(n_rows_, 0);
}
@@ -335,7 +335,7 @@ class TestRowSet : public KuduRowSetTest {
size_t n_rows_;
consensus::OpId op_id_; // Generally a "fake" OpId for these tests.
- scoped_refptr<server::Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
MvccManager mvcc_;
};
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/major_delta_compaction-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/major_delta_compaction-test.cc b/src/kudu/tablet/major_delta_compaction-test.cc
index e5e3b15..c170537 100644
--- a/src/kudu/tablet/major_delta_compaction-test.cc
+++ b/src/kudu/tablet/major_delta_compaction-test.cc
@@ -21,16 +21,16 @@
#include <memory>
#include <unordered_set>
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/generic_iterators.h"
#include "kudu/common/partial_row.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/gutil/strings/util.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/tablet/cfile_set.h"
#include "kudu/tablet/delta_compaction.h"
+#include "kudu/tablet/diskrowset-test-base.h"
#include "kudu/tablet/local_tablet_writer.h"
#include "kudu/tablet/tablet-test-util.h"
-#include "kudu/tablet/diskrowset-test-base.h"
#include "kudu/util/test_util.h"
using std::shared_ptr;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/memrowset-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/memrowset-test.cc b/src/kudu/tablet/memrowset-test.cc
index c8dab7e..8ebb5fa 100644
--- a/src/kudu/tablet/memrowset-test.cc
+++ b/src/kudu/tablet/memrowset-test.cc
@@ -19,11 +19,11 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/row.h"
#include "kudu/common/scan_spec.h"
#include "kudu/consensus/log_anchor_registry.h"
#include "kudu/consensus/opid_util.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/tablet/memrowset.h"
#include "kudu/tablet/tablet-test-util.h"
#include "kudu/util/stopwatch.h"
@@ -48,7 +48,7 @@ class TestMemRowSet : public KuduTest {
log_anchor_registry_(new LogAnchorRegistry()),
schema_(CreateSchema()),
key_schema_(schema_.CreateKeyProjection()),
- clock_(server::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
+ clock_(clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
}
static Schema CreateSchema() {
@@ -181,7 +181,7 @@ class TestMemRowSet : public KuduTest {
faststring mutation_buf_;
const Schema schema_;
const Schema key_schema_;
- scoped_refptr<server::Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
MvccManager mvcc_;
};
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/mvcc-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/mvcc-test.cc b/src/kudu/tablet/mvcc-test.cc
index 21ccc4a..705a336 100644
--- a/src/kudu/tablet/mvcc-test.cc
+++ b/src/kudu/tablet/mvcc-test.cc
@@ -20,8 +20,8 @@
#include <mutex>
#include <thread>
-#include "kudu/server/hybrid_clock.h"
-#include "kudu/server/logical_clock.h"
+#include "kudu/clock/hybrid_clock.h"
+#include "kudu/clock/logical_clock.h"
#include "kudu/tablet/mvcc.h"
#include "kudu/util/monotime.h"
#include "kudu/util/test_util.h"
@@ -31,14 +31,14 @@ using std::thread;
namespace kudu {
namespace tablet {
-using server::Clock;
-using server::HybridClock;
+using clock::Clock;
+using clock::HybridClock;
class MvccTest : public KuduTest {
public:
MvccTest()
: clock_(
- server::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
+ clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp)) {
}
void WaitForSnapshotAtTSThread(MvccManager* mgr, Timestamp ts) {
@@ -55,7 +55,7 @@ class MvccTest : public KuduTest {
}
protected:
- scoped_refptr<server::Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
mutable simple_spinlock lock_;
gscoped_ptr<MvccSnapshot> result_snapshot_;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/mvcc.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/mvcc.cc b/src/kudu/tablet/mvcc.cc
index e0c1e32..e683a4e 100644
--- a/src/kudu/tablet/mvcc.cc
+++ b/src/kudu/tablet/mvcc.cc
@@ -21,13 +21,13 @@
#include <glog/logging.h>
#include <mutex>
+#include "kudu/clock/logical_clock.h"
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/mathlimits.h"
#include "kudu/gutil/port.h"
#include "kudu/gutil/stringprintf.h"
#include "kudu/gutil/strings/strcat.h"
#include "kudu/gutil/strings/substitute.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/util/countdown_latch.h"
#include "kudu/util/debug/trace_event.h"
#include "kudu/util/stopwatch.h"
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/mvcc.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/mvcc.h b/src/kudu/tablet/mvcc.h
index 948a4ce..df3a9e9 100644
--- a/src/kudu/tablet/mvcc.h
+++ b/src/kudu/tablet/mvcc.h
@@ -23,8 +23,8 @@
#include <unordered_map>
#include <vector>
+#include "kudu/clock/clock.h"
#include "kudu/gutil/gscoped_ptr.h"
-#include "kudu/server/clock.h"
#include "kudu/util/locks.h"
namespace kudu {
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet-harness.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet-harness.h b/src/kudu/tablet/tablet-harness.h
index 44159d5..648adc0 100644
--- a/src/kudu/tablet/tablet-harness.h
+++ b/src/kudu/tablet/tablet-harness.h
@@ -22,11 +22,11 @@
#include <utility>
#include <vector>
+#include "kudu/clock/hybrid_clock.h"
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/schema.h"
#include "kudu/consensus/log_anchor_registry.h"
#include "kudu/consensus/metadata.pb.h"
-#include "kudu/server/hybrid_clock.h"
-#include "kudu/server/logical_clock.h"
#include "kudu/tablet/tablet.h"
#include "kudu/util/env.h"
#include "kudu/util/mem_tracker.h"
@@ -107,9 +107,9 @@ class TabletHarness {
}
if (options_.clock_type == Options::LOGICAL_CLOCK) {
- clock_.reset(server::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp));
+ clock_.reset(clock::LogicalClock::CreateStartingAt(Timestamp::kInitialTimestamp));
} else {
- clock_.reset(new server::HybridClock());
+ clock_.reset(new clock::HybridClock());
RETURN_NOT_OK(clock_->Init());
}
tablet_.reset(new Tablet(metadata,
@@ -126,7 +126,7 @@ class TabletHarness {
return Status::OK();
}
- server::Clock* clock() const {
+ clock::Clock* clock() const {
return clock_.get();
}
@@ -147,7 +147,7 @@ class TabletHarness {
gscoped_ptr<MetricRegistry> metrics_registry_;
- scoped_refptr<server::Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
Schema schema_;
gscoped_ptr<FsManager> fs_manager_;
std::shared_ptr<Tablet> tablet_;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet-test-util.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet-test-util.h b/src/kudu/tablet/tablet-test-util.h
index 8adc3ad..2a5ee2a 100644
--- a/src/kudu/tablet/tablet-test-util.h
+++ b/src/kudu/tablet/tablet-test-util.h
@@ -83,7 +83,7 @@ class KuduTabletTest : public KuduTest {
return client_schema_;
}
- server::Clock* clock() {
+ clock::Clock* clock() {
return harness_->clock();
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet.cc b/src/kudu/tablet/tablet.cc
index fb6043b..4304262 100644
--- a/src/kudu/tablet/tablet.cc
+++ b/src/kudu/tablet/tablet.cc
@@ -28,6 +28,7 @@
#include <vector>
#include "kudu/cfile/cfile_writer.h"
+#include "kudu/clock/hybrid_clock.h"
#include "kudu/common/iterator.h"
#include "kudu/common/row_changelist.h"
#include "kudu/common/row_operations.h"
@@ -42,7 +43,6 @@
#include "kudu/gutil/strings/human_readable.h"
#include "kudu/gutil/strings/numbers.h"
#include "kudu/gutil/strings/substitute.h"
-#include "kudu/server/hybrid_clock.h"
#include "kudu/tablet/compaction.h"
#include "kudu/tablet/compaction_policy.h"
#include "kudu/tablet/delta_compaction.h"
@@ -149,11 +149,10 @@ METRIC_DEFINE_gauge_size(tablet, on_disk_size, "Tablet Size On Disk",
"Space used by this tablet's data blocks.");
using kudu::MaintenanceManager;
+using kudu::clock::HybridClock;
using kudu::log::LogAnchorRegistry;
-using kudu::server::HybridClock;
using std::shared_ptr;
using std::string;
-using std::unique_ptr;
using std::unordered_set;
using std::vector;
using strings::Substitute;
@@ -178,7 +177,7 @@ TabletComponents::TabletComponents(shared_ptr<MemRowSet> mrs,
////////////////////////////////////////////////////////////
Tablet::Tablet(const scoped_refptr<TabletMetadata>& metadata,
- const scoped_refptr<server::Clock>& clock,
+ const scoped_refptr<clock::Clock>& clock,
const shared_ptr<MemTracker>& parent_mem_tracker,
MetricRegistry* metric_registry,
const scoped_refptr<LogAnchorRegistry>& log_anchor_registry)
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet.h b/src/kudu/tablet/tablet.h
index 0c18bdf..a81fd03 100644
--- a/src/kudu/tablet/tablet.h
+++ b/src/kudu/tablet/tablet.h
@@ -45,22 +45,21 @@
namespace kudu {
+class MaintenanceManager;
+class MaintenanceOp;
+class MaintenanceOpStats;
class MemTracker;
class MetricEntity;
class RowChangeList;
class UnionIterator;
-namespace log {
-class LogAnchorRegistry;
-}
-
-namespace server {
+namespace clock {
class Clock;
}
-class MaintenanceManager;
-class MaintenanceOp;
-class MaintenanceOpStats;
+namespace log {
+class LogAnchorRegistry;
+}
namespace tablet {
@@ -92,7 +91,7 @@ class Tablet {
// If 'metric_registry' is non-NULL, then this tablet will create a 'tablet' entity
// within the provided registry. Otherwise, no metrics are collected.
Tablet(const scoped_refptr<TabletMetadata>& metadata,
- const scoped_refptr<server::Clock>& clock,
+ const scoped_refptr<clock::Clock>& clock,
const std::shared_ptr<MemTracker>& parent_mem_tracker,
MetricRegistry* metric_registry,
const scoped_refptr<log::LogAnchorRegistry>& log_anchor_registry);
@@ -390,7 +389,7 @@ class Tablet {
// Return true if this RPC is allowed.
bool ShouldThrottleAllow(int64_t bytes);
- scoped_refptr<server::Clock> clock() const { return clock_; }
+ scoped_refptr<clock::Clock> clock() const { return clock_; }
std::string LogPrefix() const;
@@ -587,7 +586,7 @@ class Tablet {
int64_t next_mrs_id_;
// A pointer to the server's clock.
- scoped_refptr<server::Clock> clock_;
+ scoped_refptr<clock::Clock> clock_;
MvccManager mvcc_;
LockManager lock_manager_;
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet_bootstrap-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_bootstrap-test.cc b/src/kudu/tablet/tablet_bootstrap-test.cc
index f0e30eb..433ae2b 100644
--- a/src/kudu/tablet/tablet_bootstrap-test.cc
+++ b/src/kudu/tablet/tablet_bootstrap-test.cc
@@ -20,6 +20,7 @@
#include <memory>
#include <vector>
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/iterator.h"
#include "kudu/consensus/consensus-test-util.h"
#include "kudu/consensus/consensus_meta.h"
@@ -29,11 +30,10 @@
#include "kudu/consensus/metadata.pb.h"
#include "kudu/consensus/opid_util.h"
#include "kudu/fs/data_dirs.h"
-#include "kudu/server/logical_clock.h"
-#include "kudu/util/logging_test_util.h"
-#include "kudu/tablet/tablet_bootstrap.h"
#include "kudu/tablet/tablet-test-util.h"
+#include "kudu/tablet/tablet_bootstrap.h"
#include "kudu/tablet/tablet_metadata.h"
+#include "kudu/util/logging_test_util.h"
using std::shared_ptr;
using std::string;
@@ -43,21 +43,20 @@ using std::vector;
namespace kudu {
namespace tablet {
+using clock::Clock;
+using clock::LogicalClock;
using consensus::ConsensusBootstrapInfo;
using consensus::ConsensusMetadata;
using consensus::ConsensusMetadataManager;
-using consensus::kMinimumTerm;
using consensus::MakeOpId;
using consensus::OpId;
using consensus::ReplicateMsg;
using consensus::ReplicateRefPtr;
+using consensus::kMinimumTerm;
using consensus::make_scoped_refptr_replicate;
using log::Log;
using log::LogAnchorRegistry;
using log::LogTestBase;
-using log::ReadableLogSegment;
-using server::Clock;
-using server::LogicalClock;
using tserver::WriteRequestPB;
class BootstrapTest : public LogTestBase {
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet_bootstrap.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_bootstrap.cc b/src/kudu/tablet/tablet_bootstrap.cc
index 2bd6364..21e93fb 100644
--- a/src/kudu/tablet/tablet_bootstrap.cc
+++ b/src/kudu/tablet/tablet_bootstrap.cc
@@ -24,6 +24,8 @@
#include <utility>
#include <vector>
+#include "kudu/clock/clock.h"
+#include "kudu/clock/hybrid_clock.h"
#include "kudu/common/partial_row.h"
#include "kudu/common/row_operations.h"
#include "kudu/common/wire_protocol.h"
@@ -43,8 +45,6 @@
#include "kudu/gutil/strings/util.h"
#include "kudu/gutil/walltime.h"
#include "kudu/rpc/result_tracker.h"
-#include "kudu/server/clock.h"
-#include "kudu/server/hybrid_clock.h"
#include "kudu/tablet/lock_manager.h"
#include "kudu/tablet/row_op.h"
#include "kudu/tablet/tablet.h"
@@ -77,6 +77,7 @@ DECLARE_int32(max_clock_sync_error_usec);
namespace kudu {
namespace tablet {
+using clock::Clock;
using consensus::ALTER_SCHEMA_OP;
using consensus::CHANGE_CONFIG_OP;
using consensus::ChangeConfigRecordPB;
@@ -86,13 +87,13 @@ using consensus::ConsensusMetadata;
using consensus::ConsensusMetadataManager;
using consensus::MinimumOpId;
using consensus::NO_OP;
-using consensus::OperationType;
-using consensus::OperationType_Name;
using consensus::OpId;
using consensus::OpIdEquals;
using consensus::OpIdEqualsFunctor;
using consensus::OpIdHashFunctor;
using consensus::OpIdToString;
+using consensus::OperationType;
+using consensus::OperationType_Name;
using consensus::RaftConfigPB;
using consensus::ReplicateMsg;
using consensus::WRITE_OP;
@@ -103,7 +104,6 @@ using log::LogOptions;
using log::LogReader;
using log::ReadableLogSegment;
using rpc::ResultTracker;
-using server::Clock;
using std::map;
using std::shared_ptr;
using std::string;
@@ -1082,7 +1082,7 @@ Status TabletBootstrap::HandleEntryPair(LogEntryPB* replicate_entry, LogEntryPB*
} else {
DCHECK(clock_->SupportsExternalConsistencyMode(COMMIT_WAIT)) << "The provided clock does not"
"support COMMIT_WAIT external consistency mode.";
- safe_time = server::HybridClock::AddPhysicalTimeToTimestamp(
+ safe_time = clock::HybridClock::AddPhysicalTimeToTimestamp(
Timestamp(replicate->timestamp()),
MonoDelta::FromMicroseconds(-FLAGS_max_clock_sync_error_usec));
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet_bootstrap.h
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_bootstrap.h b/src/kudu/tablet/tablet_bootstrap.h
index d8091d8..65cd1df 100644
--- a/src/kudu/tablet/tablet_bootstrap.h
+++ b/src/kudu/tablet/tablet_bootstrap.h
@@ -49,7 +49,7 @@ namespace rpc {
class ResultTracker;
} // namespace rpc
-namespace server {
+namespace clock {
class Clock;
}
@@ -67,7 +67,7 @@ extern const char* kLogRecoveryDir;
// TSTabletManager.
Status BootstrapTablet(const scoped_refptr<TabletMetadata>& tablet_meta,
const scoped_refptr<consensus::ConsensusMetadataManager>& cmeta_manager,
- const scoped_refptr<server::Clock>& clock,
+ const scoped_refptr<clock::Clock>& clock,
const std::shared_ptr<MemTracker>& mem_tracker,
const scoped_refptr<rpc::ResultTracker>& result_tracker,
MetricRegistry* metric_registry,
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet_history_gc-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_history_gc-test.cc b/src/kudu/tablet/tablet_history_gc-test.cc
index da751f8..7c75fa7 100644
--- a/src/kudu/tablet/tablet_history_gc-test.cc
+++ b/src/kudu/tablet/tablet_history_gc-test.cc
@@ -18,18 +18,18 @@
#include <atomic>
#include <gflags/gflags.h>
-#include "kudu/server/hybrid_clock.h"
+#include "kudu/clock/hybrid_clock.h"
#include "kudu/tablet/compaction.h"
#include "kudu/tablet/mvcc.h"
+#include "kudu/tablet/tablet-test-base.h"
#include "kudu/tablet/tablet.h"
#include "kudu/tablet/tablet_metrics.h"
-#include "kudu/tablet/tablet-test-base.h"
DECLARE_bool(enable_maintenance_manager);
DECLARE_int32(tablet_history_max_age_sec);
DECLARE_bool(use_mock_wall_clock);
-using kudu::server::HybridClock;
+using kudu::clock::HybridClock;
// Specify row regex to match on. Empty string means don't match anything.
#define ASSERT_DEBUG_DUMP_ROWS_MATCH(pattern) do { \
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet_replica-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_replica-test.cc b/src/kudu/tablet/tablet_replica-test.cc
index 55f71dc..c8f248b 100644
--- a/src/kudu/tablet/tablet_replica-test.cc
+++ b/src/kudu/tablet/tablet_replica-test.cc
@@ -18,6 +18,8 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include "kudu/clock/clock.h"
+#include "kudu/clock/logical_clock.h"
#include "kudu/common/partial_row.h"
#include "kudu/common/timestamp.h"
#include "kudu/common/wire_protocol-test-util.h"
@@ -31,14 +33,12 @@
#include "kudu/gutil/gscoped_ptr.h"
#include "kudu/gutil/macros.h"
#include "kudu/rpc/messenger.h"
-#include "kudu/server/clock.h"
-#include "kudu/server/logical_clock.h"
+#include "kudu/tablet/tablet-test-util.h"
+#include "kudu/tablet/tablet_replica.h"
+#include "kudu/tablet/tablet_replica_mm_ops.h"
#include "kudu/tablet/transactions/transaction.h"
#include "kudu/tablet/transactions/transaction_driver.h"
#include "kudu/tablet/transactions/write_transaction.h"
-#include "kudu/tablet/tablet_replica.h"
-#include "kudu/tablet/tablet_replica_mm_ops.h"
-#include "kudu/tablet/tablet-test-util.h"
#include "kudu/tserver/tserver.pb.h"
#include "kudu/util/maintenance_manager.h"
#include "kudu/util/metrics.h"
http://git-wip-us.apache.org/repos/asf/kudu/blob/7ff27dcf/src/kudu/tablet/tablet_replica.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_replica.cc b/src/kudu/tablet/tablet_replica.cc
index 2a87fa0..4a67b10 100644
--- a/src/kudu/tablet/tablet_replica.cc
+++ b/src/kudu/tablet/tablet_replica.cc
@@ -130,7 +130,7 @@ TabletReplica::~TabletReplica() {
Status TabletReplica::Start(const ConsensusBootstrapInfo& bootstrap_info,
shared_ptr<Tablet> tablet,
- scoped_refptr<server::Clock> clock,
+ scoped_refptr<clock::Clock> clock,
shared_ptr<Messenger> messenger,
scoped_refptr<ResultTracker> result_tracker,
scoped_refptr<Log> log,