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 2016/08/17 19:12:30 UTC

[2/3] kudu git commit: [util/monotime] added handy operators for MonoTime

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/server/pprof-path-handlers.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/pprof-path-handlers.cc b/src/kudu/server/pprof-path-handlers.cc
index c1850ee..1537a31 100644
--- a/src/kudu/server/pprof-path-handlers.cc
+++ b/src/kudu/server/pprof-path-handlers.cc
@@ -149,10 +149,9 @@ static void PprofContentionHandler(const Webserver::WebRequest& req, stringstrea
   *output << "sampling period = 1" << endl;
   *output << "cycles/second = " << base::CyclesPerSecond() << endl;
 
-  MonoTime end = MonoTime::Now();
-  end.AddDelta(MonoDelta::FromSeconds(seconds));
+  MonoTime end = MonoTime::Now() + MonoDelta::FromSeconds(seconds);
   StartSynchronizationProfiling();
-  while (MonoTime::Now().ComesBefore(end)) {
+  while (MonoTime::Now() < end) {
     SleepFor(MonoDelta::FromMilliseconds(500));
     FlushSynchronizationProfile(output, &discarded_samples);
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/server/server_base.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/server_base.cc b/src/kudu/server/server_base.cc
index 6d84393..aa7d111 100644
--- a/src/kudu/server/server_base.cc
+++ b/src/kudu/server/server_base.cc
@@ -262,8 +262,8 @@ void ServerBase::MetricsLoggingThread() {
 
   MonoTime next_log = MonoTime::Now();
   while (!stop_metrics_logging_latch_.WaitUntil(next_log)) {
-    next_log = MonoTime::Now();
-    next_log.AddDelta(MonoDelta::FromMilliseconds(options_.metrics_log_interval_ms));
+    next_log = MonoTime::Now() +
+        MonoDelta::FromMilliseconds(options_.metrics_log_interval_ms);
 
     std::stringstream buf;
     buf << "metrics " << GetCurrentTimeMicros() << " ";
@@ -278,7 +278,7 @@ void ServerBase::MetricsLoggingThread() {
     Status s = metric_registry_->WriteAsJson(&writer, metrics, opts);
     if (!s.ok()) {
       WARN_NOT_OK(s, "Unable to collect metrics to log");
-      next_log.AddDelta(kWaitBetweenFailures);
+      next_log += kWaitBetweenFailures;
       continue;
     }
 
@@ -287,7 +287,7 @@ void ServerBase::MetricsLoggingThread() {
     s = log.Append(buf.str());
     if (!s.ok()) {
       WARN_NOT_OK(s, "Unable to write metrics to log");
-      next_log.AddDelta(kWaitBetweenFailures);
+      next_log += kWaitBetweenFailures;
       continue;
     }
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/server/webui_util.cc
----------------------------------------------------------------------
diff --git a/src/kudu/server/webui_util.cc b/src/kudu/server/webui_util.cc
index ebdc353..1b90700 100644
--- a/src/kudu/server/webui_util.cc
+++ b/src/kudu/server/webui_util.cc
@@ -167,11 +167,10 @@ void HtmlOutputTaskList(const std::vector<scoped_refptr<MonitoredTask> >& tasks,
 
     double running_secs = 0;
     if (task->completion_timestamp().Initialized()) {
-      running_secs = task->completion_timestamp().GetDeltaSince(
-        task->start_timestamp()).ToSeconds();
+      running_secs =
+          (task->completion_timestamp() - task->start_timestamp()).ToSeconds();
     } else if (task->start_timestamp().Initialized()) {
-      running_secs = MonoTime::Now().GetDeltaSince(
-        task->start_timestamp()).ToSeconds();
+      running_secs = (MonoTime::Now() - task->start_timestamp()).ToSeconds();
     }
 
     *output << Substitute(

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/compaction-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/compaction-test.cc b/src/kudu/tablet/compaction-test.cc
index 45bb343..738c8ce 100644
--- a/src/kudu/tablet/compaction-test.cc
+++ b/src/kudu/tablet/compaction-test.cc
@@ -749,8 +749,7 @@ TEST_F(TestCompaction, TestCompactionFreesDiskSpace) {
 
   // Block deletion may happen asynchronously, so let's loop for a bit until
   // the space becomes free.
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(MonoDelta::FromSeconds(30));
+  MonoTime deadline = MonoTime::Now() + MonoDelta::FromSeconds(30);
   while (true) {
     uint64_t bytes_after;
     ASSERT_OK(env_->GetFileSizeOnDiskRecursively(
@@ -759,7 +758,7 @@ TEST_F(TestCompaction, TestCompactionFreesDiskSpace) {
                             bytes_before, bytes_after);
     if (bytes_after < bytes_before) {
       break;
-    } else if (deadline.ComesBefore(MonoTime::Now())) {
+    } else if (MonoTime::Now() > deadline) {
       FAIL() << "Timed out waiting for compaction to reduce data block disk "
              << "space usage";
     }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/mvcc-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/mvcc-test.cc b/src/kudu/tablet/mvcc-test.cc
index 48782f0..7d4ef77 100644
--- a/src/kudu/tablet/mvcc-test.cc
+++ b/src/kudu/tablet/mvcc-test.cc
@@ -607,8 +607,7 @@ TEST_F(MvccTest, TestWaitUntilCleanDeadline) {
 
   // Wait until the 'tx1' timestamp is clean -- this won't happen because the
   // transaction isn't committed yet.
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(MonoDelta::FromMilliseconds(10));
+  MonoTime deadline = MonoTime::Now() + MonoDelta::FromMilliseconds(10);
   MvccSnapshot snap;
   Status s = mgr.WaitForCleanSnapshotAtTimestamp(tx1, &snap, deadline);
   ASSERT_TRUE(s.IsTimedOut()) << s.ToString();

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/tablet_mm_ops-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_mm_ops-test.cc b/src/kudu/tablet/tablet_mm_ops-test.cc
index 5f9514a..7422230 100644
--- a/src/kudu/tablet/tablet_mm_ops-test.cc
+++ b/src/kudu/tablet/tablet_mm_ops-test.cc
@@ -48,7 +48,7 @@ class KuduTabletMmOpsTest : public TabletTestBase<IntKeyTestSetup<INT64>> {
   void StatsShouldChange(MaintenanceOp* op) {
     SleepFor(MonoDelta::FromMilliseconds(1));
     op->UpdateStats(&stats_);
-    ASSERT_TRUE(next_time_.ComesBefore(stats_.last_modified()));
+    ASSERT_TRUE(next_time_ < stats_.last_modified());
     next_time_ = stats_.last_modified();
   }
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/tablet_peer.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/tablet_peer.cc b/src/kudu/tablet/tablet_peer.cc
index eb9366b..93301c2 100644
--- a/src/kudu/tablet/tablet_peer.cc
+++ b/src/kudu/tablet/tablet_peer.cc
@@ -313,8 +313,8 @@ Status TabletPeer::WaitUntilConsensusRunning(const MonoDelta& timeout) {
       break;
     }
     MonoTime now(MonoTime::Now());
-    MonoDelta elapsed(now.GetDeltaSince(start));
-    if (elapsed.MoreThan(timeout)) {
+    MonoDelta elapsed(now - start);
+    if (elapsed > timeout) {
       return Status::TimedOut(Substitute("Consensus is not running after waiting for $0. State; $1",
                                          elapsed.ToString(), TabletStatePB_Name(cached_state)));
     }
@@ -419,7 +419,7 @@ void TabletPeer::GetInFlightTransactions(Transaction::TraceType trace_type,
       }
       status_pb.set_description(driver->ToString());
       int64_t running_for_micros =
-          MonoTime::Now().GetDeltaSince(driver->start_time()).ToMicroseconds();
+          (MonoTime::Now() - driver->start_time()).ToMicroseconds();
       status_pb.set_running_for_micros(running_for_micros);
       if (trace_type == Transaction::TRACE_TXNS) {
         status_pb.set_trace_buffer(driver->trace()->DumpToString());

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/transactions/transaction_driver.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/transactions/transaction_driver.cc b/src/kudu/tablet/transactions/transaction_driver.cc
index c97d71b..60af908 100644
--- a/src/kudu/tablet/transactions/transaction_driver.cc
+++ b/src/kudu/tablet/transactions/transaction_driver.cc
@@ -382,7 +382,7 @@ void TransactionDriver::ReplicationFinished(const Status& status) {
       transaction_status_ = status;
     }
     prepare_state_copy = prepare_state_;
-    replication_duration = replication_finished_time.GetDeltaSince(replication_start_time_);
+    replication_duration = replication_finished_time - replication_start_time_;
   }
 
 
@@ -511,7 +511,7 @@ Status TransactionDriver::CommitWait() {
       mutable_state()->tablet_peer()->clock()->WaitUntilAfter(mutable_state()->timestamp(),
                                                               MonoTime::Max()));
   mutable_state()->mutable_metrics()->commit_wait_duration_usec =
-      MonoTime::Now().GetDeltaSince(before).ToMicroseconds();
+      (MonoTime::Now() - before).ToMicroseconds();
   return Status::OK();
 }
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/transactions/transaction_tracker.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/transactions/transaction_tracker.cc b/src/kudu/tablet/transactions/transaction_tracker.cc
index 4e0033e..fbdb5a6 100644
--- a/src/kudu/tablet/transactions/transaction_tracker.cc
+++ b/src/kudu/tablet/transactions/transaction_tracker.cc
@@ -213,8 +213,8 @@ Status TransactionTracker::WaitForAllToFinish(const MonoDelta& timeout) const {
       break;
     }
 
-    MonoDelta diff = MonoTime::Now().GetDeltaSince(start_time);
-    if (diff.MoreThan(timeout)) {
+    MonoDelta diff = MonoTime::Now() - start_time;
+    if (diff > timeout) {
       return Status::TimedOut(Substitute("Timed out waiting for all transactions to finish. "
                                          "$0 transactions pending. Waited for $1",
                                          txns.size(), diff.ToString()));

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tablet/transactions/write_transaction.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/transactions/write_transaction.cc b/src/kudu/tablet/transactions/write_transaction.cc
index 44d3fa3..6387fb1 100644
--- a/src/kudu/tablet/transactions/write_transaction.cc
+++ b/src/kudu/tablet/transactions/write_transaction.cc
@@ -177,7 +177,7 @@ void WriteTransaction::Finish(TransactionResult result) {
         metrics->commit_wait_duration->Increment(state_->metrics().commit_wait_duration_usec);
       }
       uint64_t op_duration_usec =
-          MonoTime::Now().GetDeltaSince(start_time_).ToMicroseconds();
+          (MonoTime::Now() - start_time_).ToMicroseconds();
       switch (state()->external_consistency_mode()) {
         case CLIENT_PROPAGATED:
           metrics->write_op_duration_client_propagated_consistency->Increment(op_duration_usec);
@@ -194,7 +194,7 @@ void WriteTransaction::Finish(TransactionResult result) {
 
 string WriteTransaction::ToString() const {
   MonoTime now(MonoTime::Now());
-  MonoDelta d = now.GetDeltaSince(start_time_);
+  MonoDelta d = now - start_time_;
   WallTime abs_time = WallTime_Now() - d.ToSeconds();
   string abs_time_formatted;
   StringAppendStrftime(&abs_time_formatted, "%Y-%m-%d %H:%M:%S", (time_t)abs_time, true);

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tools/ksck.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck.cc b/src/kudu/tools/ksck.cc
index 20e28af..8d7e4f5 100644
--- a/src/kudu/tools/ksck.cc
+++ b/src/kudu/tools/ksck.cc
@@ -278,19 +278,17 @@ class ChecksumResultReporter : public RefCountedThreadSafe<ChecksumResultReporte
   // Otherwise, returns true.
   bool WaitFor(const MonoDelta& timeout) const {
     MonoTime start = MonoTime::Now();
-
-    MonoTime deadline = start;
-    deadline.AddDelta(timeout);
+    MonoTime deadline = start + timeout;
 
     bool done = false;
     while (!done) {
       MonoTime now = MonoTime::Now();
-      int rem_ms = deadline.GetDeltaSince(now).ToMilliseconds();
+      int rem_ms = (deadline - now).ToMilliseconds();
       if (rem_ms <= 0) return false;
 
       done = responses_.WaitFor(MonoDelta::FromMilliseconds(std::min(rem_ms, 5000)));
       string status = done ? "finished in " : "running for ";
-      int run_time_sec = MonoTime::Now().GetDeltaSince(start).ToSeconds();
+      int run_time_sec = (MonoTime::Now() - start).ToSeconds();
       Info() << "Checksum " << status << run_time_sec << "s: "
              << responses_.count() << "/" << expected_count_ << " replicas remaining ("
              << HumanReadableNumBytes::ToString(disk_bytes_summed_.Load()) << " from disk, "

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tools/ksck_remote-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck_remote-test.cc b/src/kudu/tools/ksck_remote-test.cc
index 5f87c15..7c8c303 100644
--- a/src/kudu/tools/ksck_remote-test.cc
+++ b/src/kudu/tools/ksck_remote-test.cc
@@ -207,10 +207,9 @@ TEST_F(RemoteKsckTest, TestTabletServersOk) {
 }
 
 TEST_F(RemoteKsckTest, TestTableConsistency) {
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(MonoDelta::FromSeconds(30));
+  MonoTime deadline = MonoTime::Now() + MonoDelta::FromSeconds(30);
   Status s;
-  while (MonoTime::Now().ComesBefore(deadline)) {
+  while (MonoTime::Now() < deadline) {
     ASSERT_OK(ksck_->CheckMasterRunning());
     ASSERT_OK(ksck_->FetchTableAndTabletInfo());
     ASSERT_OK(ksck_->FetchInfoFromTabletServers());
@@ -228,10 +227,9 @@ TEST_F(RemoteKsckTest, TestChecksum) {
   LOG(INFO) << "Generating row writes...";
   ASSERT_OK(GenerateRowWrites(num_writes));
 
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(MonoDelta::FromSeconds(30));
+  MonoTime deadline = MonoTime::Now() + MonoDelta::FromSeconds(30);
   Status s;
-  while (MonoTime::Now().ComesBefore(deadline)) {
+  while (MonoTime::Now() < deadline) {
     ASSERT_OK(ksck_->FetchTableAndTabletInfo());
 
     err_stream_.str("");
@@ -275,8 +273,7 @@ TEST_F(RemoteKsckTest, TestChecksumSnapshot) {
 
   uint64_t ts = client_->GetLatestObservedTimestamp();
   MonoTime start(MonoTime::Now());
-  MonoTime deadline = start;
-  deadline.AddDelta(MonoDelta::FromSeconds(30));
+  MonoTime deadline = start + MonoDelta::FromSeconds(30);
   Status s;
   // TODO: We need to loop here because safe time is not yet implemented.
   // Remove this loop when that is done. See KUDU-1056.
@@ -284,13 +281,13 @@ TEST_F(RemoteKsckTest, TestChecksumSnapshot) {
     ASSERT_OK(ksck_->FetchTableAndTabletInfo());
     Status s = ksck_->ChecksumData(ChecksumOptions(MonoDelta::FromSeconds(10), 16, true, ts));
     if (s.ok()) break;
-    if (deadline.ComesBefore(MonoTime::Now())) break;
+    if (MonoTime::Now() > deadline) break;
     SleepFor(MonoDelta::FromMilliseconds(10));
   }
   if (!s.ok()) {
     LOG(WARNING) << Substitute("Timed out after $0 waiting for ksck to become consistent on TS $1. "
                                "Status: $2",
-                               MonoTime::Now().GetDeltaSince(start).ToString(),
+                               (MonoTime::Now() - start).ToString(),
                                ts, s.ToString());
     EXPECT_OK(s); // To avoid ASAN complaints due to thread reading the CountDownLatch.
   }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/heartbeater.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/heartbeater.cc b/src/kudu/tserver/heartbeater.cc
index 19027bb..d56a8ca 100644
--- a/src/kudu/tserver/heartbeater.cc
+++ b/src/kudu/tserver/heartbeater.cc
@@ -424,15 +424,15 @@ void Heartbeater::Thread::RunThread() {
   last_hb_response_.set_needs_full_tablet_report(true);
 
   while (true) {
-    MonoTime next_heartbeat = MonoTime::Now();
-    next_heartbeat.AddDelta(MonoDelta::FromMilliseconds(GetMillisUntilNextHeartbeat()));
+    MonoTime next_heartbeat =
+        MonoTime::Now() + MonoDelta::FromMilliseconds(GetMillisUntilNextHeartbeat());
 
     // Wait for either the heartbeat interval to elapse, or for an "ASAP" heartbeat,
     // or for the signal to shut down.
     {
       MutexLock l(mutex_);
       while (true) {
-        MonoDelta remaining = next_heartbeat.GetDeltaSince(MonoTime::Now());
+        MonoDelta remaining = next_heartbeat - MonoTime::Now();
         if (remaining.ToMilliseconds() <= 0 ||
             heartbeat_asap_ ||
             !should_run_) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/scanner_metrics.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/scanner_metrics.cc b/src/kudu/tserver/scanner_metrics.cc
index 2527b98..80f189d 100644
--- a/src/kudu/tserver/scanner_metrics.cc
+++ b/src/kudu/tserver/scanner_metrics.cc
@@ -42,7 +42,7 @@ ScannerMetrics::ScannerMetrics(const scoped_refptr<MetricEntity>& metric_entity)
 
 void ScannerMetrics::SubmitScannerDuration(const MonoTime& time_started) {
   scanner_duration->Increment(
-      MonoTime::Now().GetDeltaSince(time_started).ToMicroseconds());
+      (MonoTime::Now() - time_started).ToMicroseconds());
 }
 
 } // namespace tserver

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/scanners.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/scanners.cc b/src/kudu/tserver/scanners.cc
index ab23b4c..e698b61 100644
--- a/src/kudu/tserver/scanners.cc
+++ b/src/kudu/tserver/scanners.cc
@@ -159,7 +159,7 @@ void ScannerManager::RemoveExpiredScanners() {
       SharedScanner& scanner = it->second;
       MonoDelta time_live =
           scanner->TimeSinceLastAccess(MonoTime::Now());
-      if (time_live.MoreThan(scanner_ttl)) {
+      if (time_live > scanner_ttl) {
         // TODO: once we have a metric for the number of scanners expired, make this a
         // VLOG(1).
         LOG(INFO) << "Expiring scanner id: " << it->first << ", of tablet " << scanner->tablet_id()

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/scanners.h
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/scanners.h b/src/kudu/tserver/scanners.h
index d9264e2..3e28d69 100644
--- a/src/kudu/tserver/scanners.h
+++ b/src/kudu/tserver/scanners.h
@@ -238,7 +238,7 @@ class Scanner {
   // Return the delta from the last time this scan was updated to 'now'.
   MonoDelta TimeSinceLastAccess(const MonoTime& now) const {
     std::lock_guard<simple_spinlock> l(lock_);
-    return now.GetDeltaSince(last_access_time_);
+    return now - last_access_time_;
   }
 
   // Returns the time this scan was started.

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/tablet_server-stress-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tablet_server-stress-test.cc b/src/kudu/tserver/tablet_server-stress-test.cc
index 95af005..cfe24b1 100644
--- a/src/kudu/tserver/tablet_server-stress-test.cc
+++ b/src/kudu/tserver/tablet_server-stress-test.cc
@@ -91,7 +91,7 @@ void TSStressTest::InserterThread(int thread_idx) {
     MonoTime before = MonoTime::Now();
     InsertTestRowsRemote(thread_idx, i, 1);
     MonoTime after = MonoTime::Now();
-    MonoDelta delta = after.GetDeltaSince(before);
+    MonoDelta delta = after - before;
     histogram_->Increment(delta.ToMicroseconds());
   }
   LOG(INFO) << "Inserter thread " << thread_idx << " complete";

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/tablet_server-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tablet_server-test.cc b/src/kudu/tserver/tablet_server-test.cc
index 3ba0b11..9e036ff 100644
--- a/src/kudu/tserver/tablet_server-test.cc
+++ b/src/kudu/tserver/tablet_server-test.cc
@@ -2033,12 +2033,12 @@ TEST_F(TabletServerTest, TestInsertLatencyMicroBenchmark) {
     MonoTime before = MonoTime::Now();
     InsertTestRowsRemote(0, i, 1);
     MonoTime after = MonoTime::Now();
-    MonoDelta delta = after.GetDeltaSince(before);
+    MonoDelta delta = after - before;
     histogram->Increment(delta.ToMicroseconds());
   }
 
   MonoTime end = MonoTime::Now();
-  double throughput = ((max_rows - warmup) * 1.0) / end.GetDeltaSince(start).ToSeconds();
+  double throughput = ((max_rows - warmup) * 1.0) / (end - start).ToSeconds();
 
   // Generate the JSON.
   std::stringstream out;

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/tablet_service.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tablet_service.cc b/src/kudu/tserver/tablet_service.cc
index d5bc836..8b9d770 100644
--- a/src/kudu/tserver/tablet_service.cc
+++ b/src/kudu/tserver/tablet_service.cc
@@ -1590,8 +1590,7 @@ Status TabletServiceImpl::HandleContinueScanRequest(const ScanRequestPB* req,
   // TODO: in the future, use the client timeout to set a budget. For now,
   // just use a half second, which should be plenty to amortize call overhead.
   int budget_ms = 500;
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(MonoDelta::FromMilliseconds(budget_ms));
+  MonoTime deadline = MonoTime::Now() + MonoDelta::FromMilliseconds(budget_ms);
 
   int64_t rows_scanned = 0;
   while (iter->HasNext()) {
@@ -1622,8 +1621,7 @@ Status TabletServiceImpl::HandleContinueScanRequest(const ScanRequestPB* req,
     }
 
     // TODO: should check if RPC got cancelled, once we implement RPC cancellation.
-    MonoTime now = MonoTime::Now();
-    if (PREDICT_FALSE(!now.ComesBefore(deadline))) {
+    if (PREDICT_FALSE(MonoTime::Now() >= deadline)) {
       TRACE("Deadline expired - responding early");
       break;
     }
@@ -1732,14 +1730,13 @@ Status TabletServiceImpl::HandleScanAtSnapshot(const NewScanRequestPB& scan_pb,
   // has been since the MVCC manager was able to advance its safe time. If it has been
   // a long time, it's likely that the majority of voters for this tablet are down
   // and some writes are "stuck" and therefore won't be committed.
-  MonoTime client_deadline = rpc_context->GetClientDeadline();
   // Subtract a little bit from the client deadline so that it's more likely we actually
   // have time to send our response sent back before it times out.
-  client_deadline.AddDelta(MonoDelta::FromMilliseconds(-10));
+  MonoTime client_deadline =
+      rpc_context->GetClientDeadline() - MonoDelta::FromMilliseconds(10);
 
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(MonoDelta::FromSeconds(5));
-  if (client_deadline.ComesBefore(deadline)) {
+  MonoTime deadline = MonoTime::Now() + MonoDelta::FromSeconds(5);
+  if (client_deadline < deadline) {
     deadline = client_deadline;
   }
 
@@ -1750,7 +1747,7 @@ Status TabletServiceImpl::HandleScanAtSnapshot(const NewScanRequestPB& scan_pb,
           tmp_snap_timestamp, &snap, deadline),
       "could not wait for desired snapshot timestamp to be consistent");
 
-  uint64_t duration_usec = MonoTime::Now().GetDeltaSince(before).ToMicroseconds();
+  uint64_t duration_usec = (MonoTime::Now() - before).ToMicroseconds();
   tablet->metrics()->snapshot_read_inflight_wait_duration->Increment(duration_usec);
   TRACE("All operations in snapshot committed. Waited for $0 microseconds", duration_usec);
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/ts_tablet_manager-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/ts_tablet_manager-test.cc b/src/kudu/tserver/ts_tablet_manager-test.cc
index dfbb7f1..2d01868 100644
--- a/src/kudu/tserver/ts_tablet_manager-test.cc
+++ b/src/kudu/tserver/ts_tablet_manager-test.cc
@@ -241,10 +241,11 @@ TEST_F(TsTabletManagerTest, TestTabletReports) {
       }
     }
     if (found_tablet_2) break;
-    MonoDelta elapsed(MonoTime::Now().GetDeltaSince(start));
-    ASSERT_TRUE(elapsed.LessThan(timeout)) << "Waited too long for tablet-2 to be marked dirty: "
-                                           << elapsed.ToString() << ". "
-                                           << "Latest report: " << report.ShortDebugString();
+    MonoDelta elapsed(MonoTime::Now() - start);
+    ASSERT_TRUE(elapsed < timeout)
+        << "Waited too long for tablet-2 to be marked dirty: "
+        << elapsed.ToString() << ". "
+        << "Latest report: " << report.ShortDebugString();
     SleepFor(MonoDelta::FromMilliseconds(10));
   }
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/ts_tablet_manager.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/ts_tablet_manager.cc b/src/kudu/tserver/ts_tablet_manager.cc
index 481f569..bdc65dd 100644
--- a/src/kudu/tserver/ts_tablet_manager.cc
+++ b/src/kudu/tserver/ts_tablet_manager.cc
@@ -687,7 +687,7 @@ void TSTabletManager::OpenTablet(const scoped_refptr<TabletMetadata>& meta,
     tablet_peer->RegisterMaintenanceOps(server_->maintenance_manager());
   }
 
-  int elapsed_ms = MonoTime::Now().GetDeltaSince(start).ToMilliseconds();
+  int elapsed_ms = (MonoTime::Now() - start).ToMilliseconds();
   if (elapsed_ms > FLAGS_tablet_start_warn_threshold_ms) {
     LOG(WARNING) << LogPrefix(tablet_id) << "Tablet startup took " << elapsed_ms << "ms";
     if (Trace::CurrentTrace()) {

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/tserver/tserver-path-handlers.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/tserver-path-handlers.cc b/src/kudu/tserver/tserver-path-handlers.cc
index 18e95a5..aedf41a 100644
--- a/src/kudu/tserver/tserver-path-handlers.cc
+++ b/src/kudu/tserver/tserver-path-handlers.cc
@@ -417,7 +417,7 @@ void TabletServerPathHandlers::HandleScansPage(const Webserver::WebRequest& req,
 string TabletServerPathHandlers::ScannerToHtml(const Scanner& scanner) const {
   std::stringstream html;
   uint64_t time_in_flight_us =
-      MonoTime::Now().GetDeltaSince(scanner.start_time()).ToMicroseconds();
+      (MonoTime::Now() - scanner.start_time()).ToMicroseconds();
   uint64_t time_since_last_access_us =
       scanner.TimeSinceLastAccess(MonoTime::Now()).ToMicroseconds();
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/countdown_latch.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/countdown_latch.h b/src/kudu/util/countdown_latch.h
index 1816f4c..7024c1c 100644
--- a/src/kudu/util/countdown_latch.h
+++ b/src/kudu/util/countdown_latch.h
@@ -79,8 +79,7 @@ class CountDownLatch {
   // Returns true if the count became zero, false otherwise.
   bool WaitUntil(const MonoTime& when) const {
     ThreadRestrictions::AssertWaitAllowed();
-    MonoDelta relative = when.GetDeltaSince(MonoTime::Now());
-    return WaitFor(relative);
+    return WaitFor(when - MonoTime::Now());
   }
 
   // Waits for the count on the latch to reach zero, or until 'delta' time elapses.

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/debug/trace_event_synthetic_delay.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/debug/trace_event_synthetic_delay.cc b/src/kudu/util/debug/trace_event_synthetic_delay.cc
index ecbe383..0fff9fb 100644
--- a/src/kudu/util/debug/trace_event_synthetic_delay.cc
+++ b/src/kudu/util/debug/trace_event_synthetic_delay.cc
@@ -135,14 +135,12 @@ MonoTime TraceEventSyntheticDelay::CalculateEndTimeLocked(
     return MonoTime();
   else if (mode_ == ALTERNATING && trigger_count_++ % 2)
     return MonoTime();
-  MonoTime end = start_time;
-  end.AddDelta(target_duration_);
-  return end;
+  return start_time + target_duration_;
 }
 
 void TraceEventSyntheticDelay::ApplyDelay(const MonoTime& end_time) {
   TRACE_EVENT0("synthetic_delay", name_.c_str());
-  while (clock_->Now().ComesBefore(end_time)) {
+  while (clock_->Now() < end_time) {
     // Busy loop.
   }
 }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/failure_detector.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/failure_detector.cc b/src/kudu/util/failure_detector.cc
index 696abc2..510cbca 100644
--- a/src/kudu/util/failure_detector.cc
+++ b/src/kudu/util/failure_detector.cc
@@ -91,7 +91,7 @@ Status TimedFailureDetector::MessageFrom(const std::string& name, const MonoTime
 FailureDetector::NodeStatus TimedFailureDetector::GetNodeStatusUnlocked(const std::string& name,
                                                                         const MonoTime& now) {
   Node* node = FindOrDie(nodes_, name);
-  if (now.GetDeltaSince(node->last_heard_of).MoreThan(failure_period_)) {
+  if ((now - node->last_heard_of) > failure_period_) {
     node->status = DEAD;
   }
   return node->status;

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/metrics.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/metrics.cc b/src/kudu/util/metrics.cc
index 27766ac..50ccdcf 100644
--- a/src/kudu/util/metrics.cc
+++ b/src/kudu/util/metrics.cc
@@ -275,16 +275,15 @@ void MetricEntity::RetireOldMetrics() {
       VLOG(3) << "Metric " << it->first << " has become un-referenced. Will retire after "
               << "the retention interval";
       // This is the first time we've seen this metric as retirable.
-      metric->retire_time_ = now;
-      metric->retire_time_.AddDelta(MonoDelta::FromMilliseconds(
-                                      FLAGS_metrics_retirement_age_ms));
+      metric->retire_time_ =
+          now + MonoDelta::FromMilliseconds(FLAGS_metrics_retirement_age_ms);
       ++it;
       continue;
     }
 
     // If we've already seen this metric in a previous scan, check if it's
     // time to retire it yet.
-    if (now.ComesBefore(metric->retire_time_)) {
+    if (now < metric->retire_time_) {
       VLOG(3) << "Metric " << it->first << " is un-referenced, but still within "
               << "the retention interval";
       ++it;
@@ -676,7 +675,7 @@ ScopedLatencyMetric::ScopedLatencyMetric(Histogram* latency_hist)
 ScopedLatencyMetric::~ScopedLatencyMetric() {
   if (latency_hist_ != nullptr) {
     MonoTime time_now = MonoTime::Now();
-    latency_hist_->Increment(time_now.GetDeltaSince(time_started_).ToMicroseconds());
+    latency_hist_->Increment((time_now - time_started_).ToMicroseconds());
   }
 }
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/monotime-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/monotime-test.cc b/src/kudu/util/monotime-test.cc
index 2852768..f193ecd 100644
--- a/src/kudu/util/monotime-test.cc
+++ b/src/kudu/util/monotime-test.cc
@@ -45,9 +45,9 @@ TEST(TestMonoTime, TestComparison) {
   MonoTime future(now);
   future.AddDelta(MonoDelta::FromNanoseconds(1L));
 
-  ASSERT_GT(future.GetDeltaSince(now).ToNanoseconds(), 0);
-  ASSERT_LT(now.GetDeltaSince(future).ToNanoseconds(), 0);
-  ASSERT_EQ(now.GetDeltaSince(now).ToNanoseconds(), 0);
+  ASSERT_GT((future - now).ToNanoseconds(), 0);
+  ASSERT_LT((now - future).ToNanoseconds(), 0);
+  ASSERT_EQ((now - now).ToNanoseconds(), 0);
 
   MonoDelta nano(MonoDelta::FromNanoseconds(1L));
   MonoDelta mil(MonoDelta::FromMilliseconds(1L));
@@ -185,6 +185,231 @@ TEST(TestMonoTime, TestSleepForOverflow) {
   ASSERT_GE(actualSleep.ToNanoseconds(), sleep.ToNanoseconds());
 }
 
+// Test functionality of the handy operators for MonoTime/MonoDelta objects.
+// The test assumes that the core functionality provided by the
+// MonoTime/MonoDelta objects are in place, and it tests that the operators
+// have the expected behavior expressed in terms of already existing,
+// semantically equivalent methods.
+TEST(TestMonoTime, TestOperators) {
+  // MonoTime& MonoTime::operator+=(const MonoDelta& delta);
+  {
+    MonoTime tmp = MonoTime::Now();
+    MonoTime start = tmp;
+    MonoDelta delta = MonoDelta::FromMilliseconds(100);
+    MonoTime o_end = start;
+    o_end += delta;
+    tmp.AddDelta(delta);
+    MonoTime m_end = tmp;
+    EXPECT_TRUE(m_end.Equals(o_end));
+  }
+
+  // MonoTime& MonoTime::operator-=(const MonoDelta& delta);
+  {
+    MonoTime tmp = MonoTime::Now();
+    MonoTime start = tmp;
+    MonoDelta delta = MonoDelta::FromMilliseconds(100);
+    MonoTime o_end = start;
+    o_end -= delta;
+    tmp.AddDelta(MonoDelta::FromNanoseconds(-delta.ToNanoseconds()));
+    MonoTime m_end = tmp;
+    EXPECT_TRUE(m_end.Equals(o_end));
+  }
+
+  // bool operator==(const MonoDelta& lhs, const MonoDelta& rhs);
+  {
+    MonoDelta dn = MonoDelta::FromNanoseconds(0);
+    MonoDelta dm = MonoDelta::FromMicroseconds(0);
+    ASSERT_TRUE(dn.Equals(dm));
+    EXPECT_TRUE(dn == dm);
+    EXPECT_TRUE(dm == dn);
+  }
+
+  // bool operator!=(const MonoDelta& lhs, const MonoDelta& rhs);
+  {
+    MonoDelta dn = MonoDelta::FromNanoseconds(1);
+    MonoDelta dm = MonoDelta::FromMicroseconds(1);
+    ASSERT_FALSE(dn.Equals(dm));
+    EXPECT_TRUE(dn != dm);
+    EXPECT_TRUE(dm != dn);
+  }
+
+  // bool operator<(const MonoDelta& lhs, const MonoDelta& rhs);
+  {
+    MonoDelta d0 = MonoDelta::FromNanoseconds(0);
+    MonoDelta d1 = MonoDelta::FromNanoseconds(1);
+    ASSERT_TRUE(d0.LessThan(d1));
+    EXPECT_TRUE(d0 < d1);
+  }
+
+  // bool operator<=(const MonoDelta& lhs, const MonoDelta& rhs);
+  {
+    MonoDelta d0 = MonoDelta::FromNanoseconds(0);
+    MonoDelta d1 = MonoDelta::FromNanoseconds(1);
+    ASSERT_TRUE(d0.LessThan(d1));
+    EXPECT_TRUE(d0 <= d1);
+
+    MonoDelta d20 = MonoDelta::FromNanoseconds(2);
+    MonoDelta d21 = MonoDelta::FromNanoseconds(2);
+    ASSERT_TRUE(d20.Equals(d21));
+    EXPECT_TRUE(d20 <= d21);
+  }
+
+  // bool operator>(const MonoDelta& lhs, const MonoDelta& rhs);
+  {
+    MonoDelta d0 = MonoDelta::FromNanoseconds(0);
+    MonoDelta d1 = MonoDelta::FromNanoseconds(1);
+    ASSERT_TRUE(d1.MoreThan(d0));
+    EXPECT_TRUE(d1 > d0);
+  }
+
+  // bool operator>=(const MonoDelta& lhs, const MonoDelta& rhs);
+  {
+    MonoDelta d0 = MonoDelta::FromNanoseconds(0);
+    MonoDelta d1 = MonoDelta::FromNanoseconds(1);
+    ASSERT_TRUE(d1.MoreThan(d0));
+    EXPECT_TRUE(d1 >= d1);
+
+    MonoDelta d20 = MonoDelta::FromNanoseconds(2);
+    MonoDelta d21 = MonoDelta::FromNanoseconds(2);
+    ASSERT_TRUE(d20.Equals(d21));
+    EXPECT_TRUE(d21 >= d20);
+  }
+
+  // bool operator==(const MonoTime& lhs, const MonoTime& rhs);
+  {
+    MonoTime t0 = MonoTime::Now();
+    MonoTime t1(t0);
+    ASSERT_TRUE(t0.Equals(t1));
+    ASSERT_TRUE(t1.Equals(t0));
+    EXPECT_TRUE(t0 == t1);
+    EXPECT_TRUE(t1 == t0);
+  }
+
+  // bool operator!=(const MonoTime& lhs, const MonoTime& rhs);
+  {
+    MonoTime t0 = MonoTime::Now();
+    MonoTime t1(t0 + MonoDelta::FromMilliseconds(100));
+    ASSERT_TRUE(!t0.Equals(t1));
+    ASSERT_TRUE(!t1.Equals(t0));
+    EXPECT_TRUE(t0 != t1);
+    EXPECT_TRUE(t1 != t0);
+  }
+
+  // bool operator<(const MonoTime& lhs, const MonoTime& rhs);
+  {
+    MonoTime t0 = MonoTime::Now();
+    MonoTime t1(t0 + MonoDelta::FromMilliseconds(100));
+    ASSERT_TRUE(t0.ComesBefore(t1));
+    ASSERT_FALSE(t1.ComesBefore(t0));
+    EXPECT_TRUE(t0 < t1);
+    EXPECT_FALSE(t1 < t0);
+  }
+
+  // bool operator<=(const MonoTime& lhs, const MonoTime& rhs);
+  {
+    MonoTime t00 = MonoTime::Now();
+    MonoTime t01(t00);
+    ASSERT_TRUE(t00.Equals(t00));
+    ASSERT_TRUE(t00.Equals(t01));
+    ASSERT_TRUE(t01.Equals(t00));
+    ASSERT_TRUE(t01.Equals(t01));
+    EXPECT_TRUE(t00 <= t00);
+    EXPECT_TRUE(t00 <= t01);
+    EXPECT_TRUE(t01 <= t00);
+    EXPECT_TRUE(t01 <= t01);
+
+    MonoTime t1(t00 + MonoDelta::FromMilliseconds(100));
+    ASSERT_TRUE(t00.ComesBefore(t1));
+    ASSERT_TRUE(t01.ComesBefore(t1));
+    ASSERT_FALSE(t1.ComesBefore(t00));
+    ASSERT_FALSE(t1.ComesBefore(t01));
+    EXPECT_TRUE(t00 <= t1);
+    EXPECT_TRUE(t01 <= t1);
+    EXPECT_FALSE(t1 <= t00);
+    EXPECT_FALSE(t1 <= t01);
+  }
+
+  // bool operator>(const MonoTime& lhs, const MonoTime& rhs);
+  {
+    MonoTime t0 = MonoTime::Now();
+    MonoTime t1(t0 + MonoDelta::FromMilliseconds(100));
+    ASSERT_TRUE(t0.ComesBefore(t1));
+    ASSERT_FALSE(t1.ComesBefore(t0));
+    EXPECT_TRUE(t0 < t1);
+    EXPECT_FALSE(t1 < t0);
+  }
+
+  // bool operator>=(const MonoTime& lhs, const MonoTime& rhs);
+  {
+    MonoTime t00 = MonoTime::Now();
+    MonoTime t01(t00);
+    ASSERT_TRUE(t00.Equals(t00));
+    ASSERT_TRUE(t00.Equals(t01));
+    ASSERT_TRUE(t01.Equals(t00));
+    ASSERT_TRUE(t01.Equals(t01));
+    EXPECT_TRUE(t00 >= t00);
+    EXPECT_TRUE(t00 >= t01);
+    EXPECT_TRUE(t01 >= t00);
+    EXPECT_TRUE(t01 >= t01);
+
+    MonoTime t1(t00 + MonoDelta::FromMilliseconds(100));
+    ASSERT_TRUE(t00.ComesBefore(t1));
+    ASSERT_TRUE(t01.ComesBefore(t1));
+    ASSERT_FALSE(t1.ComesBefore(t00));
+    ASSERT_FALSE(t1.ComesBefore(t01));
+    EXPECT_FALSE(t00 >= t1);
+    EXPECT_FALSE(t01 >= t1);
+    EXPECT_TRUE(t1 >= t00);
+    EXPECT_TRUE(t1 >= t01);
+  }
+
+  // MonoDelta operator-(const MonoTime& t0, const MonoTime& t1);
+  {
+    const int64_t deltas[] = { 100, -100 };
+
+    MonoTime tmp = MonoTime::Now();
+    for (auto d : deltas) {
+      MonoDelta delta = MonoDelta::FromMilliseconds(d);
+
+      MonoTime start = tmp;
+      tmp.AddDelta(delta);
+      MonoTime end = tmp;
+      MonoDelta delta_o = end - start;
+      EXPECT_TRUE(delta.Equals(delta_o));
+    }
+  }
+
+  // MonoTime operator+(const MonoTime& t, const MonoDelta& delta);
+  {
+    MonoTime start = MonoTime::Now();
+
+    MonoDelta delta_0 = MonoDelta::FromMilliseconds(0);
+    MonoTime end_0 = start + delta_0;
+    EXPECT_TRUE(end_0.Equals(start));
+
+    MonoDelta delta_1 = MonoDelta::FromMilliseconds(1);
+    MonoTime end_1 = start + delta_1;
+    EXPECT_TRUE(end_1 > end_0);
+    end_0.AddDelta(delta_1);
+    EXPECT_TRUE(end_0.Equals(end_1));
+  }
+
+  // MonoTime operator-(const MonoTime& t, const MonoDelta& delta);
+  {
+    MonoTime start = MonoTime::Now();
+
+    MonoDelta delta_0 = MonoDelta::FromMilliseconds(0);
+    MonoTime end_0 = start - delta_0;
+    EXPECT_TRUE(end_0.Equals(start));
+
+    MonoDelta delta_1 = MonoDelta::FromMilliseconds(1);
+    MonoTime end_1 = start - delta_1;
+    EXPECT_TRUE(end_1 < end_0);
+    end_1.AddDelta(delta_1);
+    EXPECT_TRUE(end_1.Equals(end_0));
+  }
+}
+
 TEST(TestMonoTimePerf, TestMonoTimePerf) {
   alarm(360);
   DoTestMonoTimePerf();

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/monotime.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/monotime.cc b/src/kudu/util/monotime.cc
index 511dd15..b67be42 100644
--- a/src/kudu/util/monotime.cc
+++ b/src/kudu/util/monotime.cc
@@ -223,6 +223,16 @@ bool MonoTime::Equals(const MonoTime& other) const {
   return nanos_ == other.nanos_;
 }
 
+MonoTime& MonoTime::operator+=(const MonoDelta& delta) {
+  this->AddDelta(delta);
+  return *this;
+}
+
+MonoTime& MonoTime::operator-=(const MonoDelta& delta) {
+  this->AddDelta(MonoDelta(-1 * delta.nano_delta_));
+  return *this;
+}
+
 MonoTime::MonoTime(const struct timespec &ts) {
   // Monotonic time resets when the machine reboots.  The 64-bit limitation
   // means that we can't represent times larger than 292 years, which should be
@@ -248,4 +258,68 @@ void SleepFor(const MonoDelta& delta) {
   base::SleepForNanoseconds(delta.ToNanoseconds());
 }
 
+bool operator==(const MonoDelta &lhs, const MonoDelta &rhs) {
+  return lhs.Equals(rhs);
+}
+
+bool operator!=(const MonoDelta &lhs, const MonoDelta &rhs) {
+  return !lhs.Equals(rhs);
+}
+
+bool operator<(const MonoDelta &lhs, const MonoDelta &rhs) {
+  return lhs.LessThan(rhs);
+}
+
+bool operator<=(const MonoDelta &lhs, const MonoDelta &rhs) {
+  return lhs.LessThan(rhs) || lhs.Equals(rhs);
+}
+
+bool operator>(const MonoDelta &lhs, const MonoDelta &rhs) {
+  return lhs.MoreThan(rhs);
+}
+
+bool operator>=(const MonoDelta &lhs, const MonoDelta &rhs) {
+  return lhs.MoreThan(rhs) || lhs.Equals(rhs);
+}
+
+bool operator==(const MonoTime& lhs, const MonoTime& rhs) {
+  return lhs.Equals(rhs);
+}
+
+bool operator!=(const MonoTime& lhs, const MonoTime& rhs) {
+  return !lhs.Equals(rhs);
+}
+
+bool operator<(const MonoTime& lhs, const MonoTime& rhs) {
+  return lhs.ComesBefore(rhs);
+}
+
+bool operator<=(const MonoTime& lhs, const MonoTime& rhs) {
+  return lhs.ComesBefore(rhs) || lhs.Equals(rhs);
+}
+
+bool operator>(const MonoTime& lhs, const MonoTime& rhs) {
+  return rhs.ComesBefore(lhs);
+}
+
+bool operator>=(const MonoTime& lhs, const MonoTime& rhs) {
+  return rhs.ComesBefore(lhs) || rhs.Equals(lhs);
+}
+
+MonoTime operator+(const MonoTime& t, const MonoDelta& delta) {
+  MonoTime tmp(t);
+  tmp.AddDelta(delta);
+  return tmp;
+}
+
+MonoTime operator-(const MonoTime& t, const MonoDelta& delta) {
+  MonoTime tmp(t);
+  tmp.AddDelta(MonoDelta::FromNanoseconds(-delta.ToNanoseconds()));
+  return tmp;
+}
+
+MonoDelta operator-(const MonoTime& t_end, const MonoTime& t_beg) {
+  return t_end.GetDeltaSince(t_beg);
+}
+
 } // namespace kudu

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/monotime.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/monotime.h b/src/kudu/util/monotime.h
index 8aa99a8..007c54d 100644
--- a/src/kudu/util/monotime.h
+++ b/src/kudu/util/monotime.h
@@ -131,6 +131,7 @@ class KUDU_EXPORT MonoDelta {
 
   friend class MonoTime;
   FRIEND_TEST(TestMonoTime, TestDeltaConversions);
+
   explicit MonoDelta(int64_t delta);
   int64_t nano_delta_;
 };
@@ -216,6 +217,24 @@ class KUDU_EXPORT MonoTime {
   ///   is the same as the one represented by the other.
   bool Equals(const MonoTime& other) const;
 
+  /// @name Syntactic sugar: increment/decrement operators for MonoTime.
+  ///@{
+  ///
+  /// Add a delta to the point in time represented by the object.
+  ///
+  /// @param [in] delta
+  ///   The delta to add.
+  /// @return Reference to the modified object.
+  MonoTime& operator+=(const MonoDelta& delta);
+
+  /// Substract a delta from the point in time represented by the object.
+  ///
+  /// @param [in] delta
+  ///   The delta to substract.
+  /// @return Reference to the modified object.
+  MonoTime& operator-=(const MonoDelta& delta);
+  ///@}
+
  private:
   friend class MonoDelta;
   FRIEND_TEST(TestMonoTime, TestTimeSpec);
@@ -239,6 +258,155 @@ class KUDU_EXPORT MonoTime {
 ///   The time interval to sleep for.
 void KUDU_EXPORT SleepFor(const MonoDelta& delta);
 
+/// @name Syntactic sugar: binary operators for MonoDelta.
+///@{
+///
+/// @param [in] lhs
+///   A time interval for comparison: the left-hand operand.
+/// @param [in] rhs
+///   A time interval for comparison: the right-hand operand.
+/// @return @c true iff the time interval represented by @c lhs is equal
+///   to the time interval represented by @c rhs.
+bool KUDU_EXPORT operator==(const MonoDelta &lhs, const MonoDelta &rhs);
+
+/// @param [in] lhs
+///   A time interval for comparison: the left-hand operand.
+/// @param [in] rhs
+///   A time interval for comparison: the right-hand operand.
+/// @return @c true iff the time interval represented by @c lhs is not equal
+///   to the time interval represented by @c rhs.
+bool KUDU_EXPORT operator!=(const MonoDelta &lhs, const MonoDelta &rhs);
+
+/// @param [in] lhs
+///   A time interval for comparison: the left-hand operand.
+/// @param [in] rhs
+///   A time interval for comparison: the right-hand operand.
+/// @return @c true iff the time interval represented by @c lhs is shorter
+///   than the time interval represented by @c rhs.
+bool KUDU_EXPORT operator<(const MonoDelta &lhs, const MonoDelta &rhs);
+
+/// @param [in] lhs
+///   A time interval for comparison: the left-hand operand.
+/// @param [in] rhs
+///   A time interval for comparison: the right-hand operand.
+/// @return @c true iff the time interval represented by @c lhs is shorter
+///   than or equal to the time interval represented by @c rhs.
+bool KUDU_EXPORT operator<=(const MonoDelta &lhs, const MonoDelta &rhs);
+
+/// @param [in] lhs
+///   A time interval for comparison: the left-hand operand.
+/// @param [in] rhs
+///   A time interval for comparison: the right-hand operand.
+/// @return @c true iff the time interval represented by @c lhs is longer
+///   than the time interval represented by @c rhs.
+bool KUDU_EXPORT operator>(const MonoDelta &lhs, const MonoDelta &rhs);
+
+/// @param [in] lhs
+///   A time interval for comparison: the left-hand operand.
+/// @param [in] rhs
+///   A time interval for comparison: the right-hand operand.
+/// @return @c true iff the time interval represented by @c lhs is longer
+///   than or equal to the time interval represented by @c rhs.
+bool KUDU_EXPORT operator>=(const MonoDelta &lhs, const MonoDelta &rhs);
+///@}
+
+/// @name Syntactic sugar: binary operators for MonoTime.
+///@{
+///
+/// Check if the specified objects represent the same point in time.
+///
+/// This is a handy operator which is semantically equivalent to
+/// MonoTime::Equals().
+///
+/// @param [in] lhs
+///   The left-hand operand.
+/// @param [in] rhs
+///   The right-hand operand.
+/// @return @c true iff the given objects represent the same point in time.
+bool KUDU_EXPORT operator==(const MonoTime& lhs, const MonoTime& rhs);
+
+/// Check if the specified objects represent different points in time.
+///
+/// This is a handy operator which is semantically equivalent to the negation of
+/// MonoTime::Equals().
+///
+/// @param [in] lhs
+///   The left-hand operand.
+/// @param [in] rhs
+///   The right-hand operand.
+/// @return @c true iff the given object represents a different point in time
+///   than the specified one.
+bool KUDU_EXPORT operator!=(const MonoTime& lhs, const MonoTime& rhs);
+
+/// @param [in] lhs
+///   The left-hand operand.
+/// @param [in] rhs
+///   The right-hand operand.
+/// @return @c true iff the @c lhs object represents an earlier point in time
+///   than the @c rhs object.
+bool KUDU_EXPORT operator<(const MonoTime& lhs, const MonoTime& rhs);
+
+/// @param [in] lhs
+///   The left-hand operand.
+/// @param [in] rhs
+///   The right-hand operand.
+/// @return @c true iff the @c lhs object represents an earlier than or
+///   the same point in time as the @c rhs object.
+bool KUDU_EXPORT operator<=(const MonoTime& lhs, const MonoTime& rhs);
+
+/// @param [in] lhs
+///   The left-hand operand.
+/// @param [in] rhs
+///   The right-hand operand.
+/// @return @c true iff the @c lhs object represents a later point in time
+///   than the @c rhs object.
+bool KUDU_EXPORT operator>(const MonoTime& lhs, const MonoTime& rhs);
+
+/// @param [in] lhs
+///   The left-hand operand.
+/// @param [in] rhs
+///   The right-hand operand.
+/// @return @c true iff the @c lhs object represents a later than or
+///   the same point in time as the @c rhs object.
+bool KUDU_EXPORT operator>=(const MonoTime& lhs, const MonoTime& rhs);
+///@}
+
+/// @name Syntactic sugar: mixed binary operators for MonoTime/MonoDelta.
+///@{
+///
+/// Add the specified time interval to the given point in time.
+///
+/// @param [in] t
+///   A MonoTime object representing the given point in time.
+/// @param [in] delta
+///   A MonoDelta object representing the specified time interval.
+/// @return A MonoTime object representing the resulting point in time.
+MonoTime KUDU_EXPORT operator+(const MonoTime& t, const MonoDelta& delta);
+
+/// Subtract the specified time interval from the given point in time.
+///
+/// @param [in] t
+///   A MonoTime object representing the given point in time.
+/// @param [in] delta
+///   A MonoDelta object representing the specified time interval.
+/// @return A MonoTime object representing the resulting point in time.
+MonoTime KUDU_EXPORT operator-(const MonoTime& t, const MonoDelta& delta);
+
+/// Compute the time interval between the specified points in time.
+///
+/// Semantically, this is equivalent to t0.GetDeltaSince(t1).
+///
+/// @param [in] t_end
+///   The second point in time.  Semantically corresponds to the end
+///   of the resulting time interval.
+/// @param [in] t_beg
+///   The first point in time.  Semantically corresponds to the beginning
+///   of the resulting time interval.
+/// @return A MonoDelta object representing the time interval between the
+///   specified points in time.
+MonoDelta KUDU_EXPORT operator-(const MonoTime& t_end, const MonoTime& t_begin);
+///@}
+
 } // namespace kudu
 
 #endif

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/net/socket.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/net/socket.cc b/src/kudu/util/net/socket.cc
index 150b7b2..5d68a51 100644
--- a/src/kudu/util/net/socket.cc
+++ b/src/kudu/util/net/socket.cc
@@ -434,7 +434,7 @@ Status Socket::BlockingWrite(const uint8_t *buf, size_t buflen, size_t *nwritten
   while (tot_written < buflen) {
     int32_t inc_num_written = 0;
     int32_t num_to_write = buflen - tot_written;
-    MonoDelta timeout = deadline.GetDeltaSince(MonoTime::Now());
+    MonoDelta timeout = deadline - MonoTime::Now();
     if (PREDICT_FALSE(timeout.ToNanoseconds() <= 0)) {
       return Status::TimedOut("BlockingWrite timed out");
     }
@@ -505,7 +505,7 @@ Status Socket::BlockingRecv(uint8_t *buf, size_t amt, size_t *nread, const MonoT
   while (tot_read < amt) {
     int32_t inc_num_read = 0;
     int32_t num_to_read = amt - tot_read;
-    MonoDelta timeout = deadline.GetDeltaSince(MonoTime::Now());
+    MonoDelta timeout = deadline - MonoTime::Now();
     if (PREDICT_FALSE(timeout.ToNanoseconds() <= 0)) {
       return Status::TimedOut("");
     }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/striped64-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/striped64-test.cc b/src/kudu/util/striped64-test.cc
index f5dbdcf..6cabdce 100644
--- a/src/kudu/util/striped64-test.cc
+++ b/src/kudu/util/striped64-test.cc
@@ -124,8 +124,8 @@ void RunMultiTest(int64_t num_operations, int64_t num_threads) {
   MultiThreadTest<LongAdder> test(num_operations, num_threads);
   test.Run();
   MonoTime end2 = MonoTime::Now();
-  MonoDelta basic = end1.GetDeltaSince(start);
-  MonoDelta striped = end2.GetDeltaSince(end1);
+  MonoDelta basic = end1 - start;
+  MonoDelta striped = end2 - end1;
   LOG(INFO) << "Basic counter took   " << basic.ToMilliseconds() << "ms.";
   LOG(INFO) << "Striped counter took " << striped.ToMilliseconds() << "ms.";
 }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/striped64.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/striped64.cc b/src/kudu/util/striped64.cc
index d949735..a0951c7 100644
--- a/src/kudu/util/striped64.cc
+++ b/src/kudu/util/striped64.cc
@@ -32,7 +32,7 @@ namespace internal {
 //
 
 HashCode::HashCode() {
-  Random r(MonoTime::Now().GetDeltaSince(MonoTime::Min()).ToNanoseconds());
+  Random r((MonoTime::Now() - MonoTime::Min()).ToNanoseconds());
   const uint64_t hash = r.Next64();
   code_ = (hash == 0) ? 1 : hash;  // Avoid zero to allow xorShift rehash
 }

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/test_util.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/test_util.cc b/src/kudu/util/test_util.cc
index b26302a..b002d43 100644
--- a/src/kudu/util/test_util.cc
+++ b/src/kudu/util/test_util.cc
@@ -183,11 +183,10 @@ string GetTestDataDirectory() {
 
 void AssertEventually(const std::function<void(void)>& f,
                       const MonoDelta& timeout) {
-  MonoTime deadline = MonoTime::Now();
-  deadline.AddDelta(timeout);
+  const MonoTime deadline = MonoTime::Now() + timeout;
   int attempts = 0;
 
-  while (MonoTime::Now().ComesBefore(deadline)) {
+  while (MonoTime::Now() < deadline) {
     // Capture any assertion failures within this scope (i.e. from their function)
     // into 'results'
     testing::TestPartResultArray results;

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/threadpool.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/threadpool.cc b/src/kudu/util/threadpool.cc
index c7ec317..00cd6f8 100644
--- a/src/kudu/util/threadpool.cc
+++ b/src/kudu/util/threadpool.cc
@@ -254,8 +254,7 @@ void ThreadPool::Wait() {
 }
 
 bool ThreadPool::WaitUntil(const MonoTime& until) {
-  MonoDelta relative = until.GetDeltaSince(MonoTime::Now());
-  return WaitFor(relative);
+  return WaitFor(until - MonoTime::Now());
 }
 
 bool ThreadPool::WaitFor(const MonoDelta& delta) {
@@ -329,7 +328,7 @@ void ThreadPool::DispatchThread(bool permanent) {
 
     // Update metrics
     MonoTime now(MonoTime::Now());
-    int64_t queue_time_us = now.GetDeltaSince(entry.submit_time).ToMicroseconds();
+    int64_t queue_time_us = (now - entry.submit_time).ToMicroseconds();
     TRACE_COUNTER_INCREMENT(queue_time_trace_metric_name_, queue_time_us);
     if (queue_time_us_histogram_) {
       queue_time_us_histogram_->Increment(queue_time_us);

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/throttler-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/throttler-test.cc b/src/kudu/util/throttler-test.cc
index 9bf800d..57563d2 100644
--- a/src/kudu/util/throttler-test.cc
+++ b/src/kudu/util/throttler-test.cc
@@ -33,14 +33,14 @@ TEST_F(ThrottlerTest, TestOpThrottle) {
   MonoTime now = MonoTime::Now();
   Throttler t0(now, 1000, 1000*1000, 1);
   // Fill up bucket
-  now.AddDelta(MonoDelta::FromMilliseconds(2000));
+  now += MonoDelta::FromMilliseconds(2000);
   // Check throttle behavior for 1 second.
   for (int p = 0; p < 10; p++) {
     for (int i = 0; i < 100; i++) {
       ASSERT_TRUE(t0.Take(now, 1, 1));
     }
     ASSERT_FALSE(t0.Take(now, 1, 1));
-    now.AddDelta(MonoDelta::FromMilliseconds(100));
+    now += MonoDelta::FromMilliseconds(100);
   }
 }
 
@@ -49,14 +49,14 @@ TEST_F(ThrottlerTest, TestIOThrottle) {
   MonoTime now = MonoTime::Now();
   Throttler t0(now, 50000, 1000*1000, 1);
   // Fill up bucket
-  now.AddDelta(MonoDelta::FromMilliseconds(2000));
+  now += MonoDelta::FromMilliseconds(2000);
   // Check throttle behavior for 1 second.
   for (int p = 0; p < 10; p++) {
     for (int i = 0; i < 100; i++) {
       ASSERT_TRUE(t0.Take(now, 1, 1000));
     }
     ASSERT_FALSE(t0.Take(now, 1, 1000));
-    now.AddDelta(MonoDelta::FromMilliseconds(100));
+    now += MonoDelta::FromMilliseconds(100);
   }
 }
 
@@ -65,9 +65,9 @@ TEST_F(ThrottlerTest, TestBurst) {
   MonoTime now = MonoTime::Now();
   Throttler t0(now, 2000, 1000*1000, 5);
   // Fill up bucket
-  now.AddDelta(MonoDelta::FromMilliseconds(2000));
+  now += MonoDelta::FromMilliseconds(2000);
   for (int i = 0; i < 100; i++) {
-    now.AddDelta(MonoDelta::FromMilliseconds(1));
+    now += MonoDelta::FromMilliseconds(1);
     ASSERT_TRUE(t0.Take(now, 1, 5000));
   }
   ASSERT_TRUE(t0.Take(now, 1, 100000));

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/throttler.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/throttler.cc b/src/kudu/util/throttler.cc
index 6207bdb..108d5db 100644
--- a/src/kudu/util/throttler.cc
+++ b/src/kudu/util/throttler.cc
@@ -51,12 +51,12 @@ bool Throttler::Take(MonoTime now, uint64_t op, uint64_t byte) {
 }
 
 void Throttler::Refill(MonoTime now) {
-  int64_t d = now.GetDeltaSince(next_refill_).ToMicroseconds();
+  int64_t d = (now - next_refill_).ToMicroseconds();
   if (d < 0) {
     return;
   }
   uint64_t num_period = d / kRefillPeriodMicros + 1;
-  next_refill_.AddDelta(MonoDelta::FromMicroseconds(num_period * kRefillPeriodMicros));
+  next_refill_ += MonoDelta::FromMicroseconds(num_period * kRefillPeriodMicros);
   op_token_ += num_period * op_refill_;
   op_token_ = std::min(op_token_, op_token_max_);
   byte_token_ += num_period * byte_refill_;

http://git-wip-us.apache.org/repos/asf/kudu/blob/34b7f1eb/src/kudu/util/trace-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/trace-test.cc b/src/kudu/util/trace-test.cc
index a30e559..6c38b0c 100644
--- a/src/kudu/util/trace-test.cc
+++ b/src/kudu/util/trace-test.cc
@@ -660,27 +660,27 @@ class TraceEventSyntheticDelayTest : public KuduTest,
     return delay;
   }
 
-  void AdvanceTime(MonoDelta delta) { now_.AddDelta(delta); }
+  void AdvanceTime(MonoDelta delta) { now_ += delta; }
 
   int TestFunction() {
     MonoTime start = Now();
     { TRACE_EVENT_SYNTHETIC_DELAY("test.Delay"); }
     MonoTime end = Now();
-    return end.GetDeltaSince(start).ToMilliseconds();
+    return (end - start).ToMilliseconds();
   }
 
   int AsyncTestFunctionBegin() {
     MonoTime start = Now();
     { TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("test.AsyncDelay"); }
     MonoTime end = Now();
-    return end.GetDeltaSince(start).ToMilliseconds();
+    return (end - start).ToMilliseconds();
   }
 
   int AsyncTestFunctionEnd() {
     MonoTime start = Now();
     { TRACE_EVENT_SYNTHETIC_DELAY_END("test.AsyncDelay"); }
     MonoTime end = Now();
-    return end.GetDeltaSince(start).ToMilliseconds();
+    return (end - start).ToMilliseconds();
   }
 
  private:
@@ -769,11 +769,11 @@ TEST_F(TraceEventSyntheticDelayTest, BeginParallel) {
   EXPECT_FALSE(!end_times[1].Initialized());
 
   delay->EndParallel(end_times[0]);
-  EXPECT_GE(Now().GetDeltaSince(start_time).ToMilliseconds(), kTargetDurationMs);
+  EXPECT_GE((Now() - start_time).ToMilliseconds(), kTargetDurationMs);
 
   start_time = Now();
   delay->EndParallel(end_times[1]);
-  EXPECT_LT(Now().GetDeltaSince(start_time).ToMilliseconds(), kShortDurationMs);
+  EXPECT_LT((Now() - start_time).ToMilliseconds(), kShortDurationMs);
 }
 
 TEST_F(TraceTest, TestVLogTrace) {