1 //  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #pragma once
7 #ifndef ROCKSDB_LITE
8 
9 #include <functional>
10 #include <memory>
11 
12 #include "rocksdb/rocksdb_namespace.h"
13 #include "rocksdb/status.h"
14 
15 namespace ROCKSDB_NAMESPACE {
16 
17 class TraceRecord;
18 class TraceRecordResult;
19 
20 struct ReplayOptions {
21   // Number of threads used for replaying. If 0 or 1, replay using
22   // single thread.
23   uint32_t num_threads;
24 
25   // Enables fast forwarding a replay by increasing/reducing the delay between
26   // the ingested traces.
27   //   If > 0.0 and < 1.0, slow down the replay by this amount.
28   //   If 1.0, replay the operations at the same rate as in the trace stream.
29   //   If > 1, speed up the replay by this amount.
30   double fast_forward;
31 
ReplayOptionsReplayOptions32   ReplayOptions() : num_threads(1), fast_forward(1.0) {}
33 
ReplayOptionsReplayOptions34   ReplayOptions(uint32_t num_of_threads, double fast_forward_ratio)
35       : num_threads(num_of_threads), fast_forward(fast_forward_ratio) {}
36 };
37 
38 // Replayer helps to replay the captured RocksDB query level operations.
39 // The Replayer can either be created from DB::NewReplayer method, or be
40 // instantiated via db_bench today, on using "replay" benchmark.
41 class Replayer {
42  public:
43   virtual ~Replayer() = default;
44 
45   // Make some preparation before replaying the trace. This will also reset the
46   // replayer in order to restart replaying.
47   virtual Status Prepare() = 0;
48 
49   // Return the timestamp when the trace recording was started.
50   virtual uint64_t GetHeaderTimestamp() const = 0;
51 
52   // Atomically read one trace into a TraceRecord (excluding the header and
53   // footer traces).
54   // Return Status::OK() on success;
55   // Status::Incomplete() if Prepare() was not called or no more available
56   // trace;
57   // Status::NotSupported() if the read trace type is not supported.
58   virtual Status Next(std::unique_ptr<TraceRecord>* record) = 0;
59 
60   // Execute one TraceRecord.
61   // Return Status::OK() if the execution was successful. Get/MultiGet traces
62   // will still return Status::OK() even if they got Status::NotFound()
63   // from DB::Get() or DB::MultiGet();
64   // Status::Incomplete() if Prepare() was not called or no more available
65   // trace;
66   // Status::NotSupported() if the operation is not supported;
67   // Otherwise, return the corresponding error status.
68   //
69   // The actual operation execution status and result(s) will be saved in
70   // result. For example, a GetQueryTraceRecord will have its DB::Get() status
71   // and the returned value saved in a SingleValueTraceExecutionResult.
72   virtual Status Execute(const std::unique_ptr<TraceRecord>& record,
73                          std::unique_ptr<TraceRecordResult>* result) = 0;
74 
75   // Replay all the traces from the provided trace stream, taking the delay
76   // between the traces into consideration.
77   //
78   // result_callback reports the status of executing a trace record, and the
79   // actual operation execution result (See the description for Execute()).
80   virtual Status Replay(
81       const ReplayOptions& options,
82       const std::function<void(Status, std::unique_ptr<TraceRecordResult>&&)>&
83           result_callback) = 0;
84 };
85 
86 }  // namespace ROCKSDB_NAMESPACE
87 #endif  // ROCKSDB_LITE
88