rippled
Timing_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/basics/BasicConfig.h>
21 #include <ripple/basics/safe_cast.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/beast/utility/temp_dir.h>
24 #include <ripple/beast/xor_shift_engine.h>
25 #include <ripple/nodestore/DummyScheduler.h>
26 #include <ripple/nodestore/Manager.h>
27 #include <ripple/unity/rocksdb.h>
28 #include <boost/algorithm/string.hpp>
29 #include <atomic>
30 #include <beast/unit_test/thread.hpp>
31 #include <chrono>
32 #include <iterator>
33 #include <limits>
34 #include <map>
35 #include <random>
36 #include <sstream>
37 #include <stdexcept>
38 #include <test/nodestore/TestBase.h>
39 #include <test/unit_test/SuiteJournal.h>
40 #include <thread>
41 #include <type_traits>
42 #include <utility>
43 
44 #ifndef NODESTORE_TIMING_DO_VERIFY
45 #define NODESTORE_TIMING_DO_VERIFY 0
46 #endif
47 
48 namespace ripple {
49 namespace NodeStore {
50 
51 // Fill memory with random bits
52 template <class Generator>
53 static void
54 rngcpy(void* buffer, std::size_t bytes, Generator& g)
55 {
56  using result_type = typename Generator::result_type;
57  while (bytes >= sizeof(result_type))
58  {
59  auto const v = g();
60  memcpy(buffer, &v, sizeof(v));
61  buffer = reinterpret_cast<std::uint8_t*>(buffer) + sizeof(v);
62  bytes -= sizeof(v);
63  }
64 
65  if (bytes > 0)
66  {
67  auto const v = g();
68  memcpy(buffer, &v, bytes);
69  }
70 }
71 
72 // Instance of node factory produces a deterministic sequence
73 // of random NodeObjects within the given
74 class Sequence
75 {
76 private:
77  enum { minLedger = 1, maxLedger = 1000000, minSize = 250, maxSize = 1250 };
78 
83 
84 public:
85  explicit Sequence(std::uint8_t prefix)
86  : prefix_(prefix)
87  // uniform distribution over hotLEDGER - hotTRANSACTION_NODE
88  // but exclude hotTRANSACTION = 2 (removed)
89  , d_type_({1, 1, 0, 1, 1})
91  {
92  }
93 
94  // Returns the n-th key
95  uint256
97  {
98  gen_.seed(n + 1);
99  uint256 result;
100  rngcpy(&*result.begin(), result.size(), gen_);
101  return result;
102  }
103 
104  // Returns the n-th complete NodeObject
107  {
108  gen_.seed(n + 1);
109  uint256 key;
110  auto const data = static_cast<std::uint8_t*>(&*key.begin());
111  *data = prefix_;
112  rngcpy(data + 1, key.size() - 1, gen_);
113  Blob value(d_size_(gen_));
114  rngcpy(&value[0], value.size(), gen_);
116  safe_cast<NodeObjectType>(d_type_(gen_)), std::move(value), key);
117  }
118 
119  // returns a batch of NodeObjects starting at n
120  void
122  {
123  b.clear();
124  b.reserve(size);
125  while (size--)
126  b.emplace_back(obj(n++));
127  }
128 };
129 
130 //----------------------------------------------------------------------------------
131 
132 class Timing_test : public beast::unit_test::suite
133 {
134 public:
135  enum {
136  // percent of fetches for missing nodes
138  };
139 
141 #ifndef NDEBUG
142  std::size_t const default_items = 10000;
143 #else
144  std::size_t const default_items = 100000; // release
145 #endif
146 
149 
150  struct Params
151  {
154  };
155 
156  static std::string
157  to_string(Section const& config)
158  {
159  std::string s;
160  for (auto iter = config.begin(); iter != config.end(); ++iter)
161  s += (iter != config.begin() ? "," : "") + iter->first + "=" +
162  iter->second;
163  return s;
164  }
165 
166  static std::string
168  {
170  ss << std::fixed << std::setprecision(3) << (d.count() / 1000.) << "s";
171  return ss.str();
172  }
173 
174  static Section
176  {
177  Section section;
179  boost::split(v, s, boost::algorithm::is_any_of(","));
180  section.append(v);
181  return section;
182  }
183 
184  //--------------------------------------------------------------------------
185 
186  // Workaround for GCC's parameter pack expansion in lambdas
187  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
188  template <class Body>
190  {
191  private:
194 
195  public:
197  : n_(n), c_(c)
198  {
199  }
200 
201  template <class... Args>
202  void
203  operator()(Args&&... args)
204  {
205  Body body(args...);
206  for (;;)
207  {
208  auto const i = c_++;
209  if (i >= n_)
210  break;
211  body(i);
212  }
213  }
214  };
215 
216  /* Execute parallel-for loop.
217 
218  Constructs `number_of_threads` instances of `Body`
219  with `args...` parameters and runs them on individual threads
220  with unique loop indexes in the range [0, n).
221  */
222  template <class Body, class... Args>
223  void
225  std::size_t const n,
226  std::size_t number_of_threads,
227  Args const&... args)
228  {
231  t.reserve(number_of_threads);
232  for (std::size_t id = 0; id < number_of_threads; ++id)
233  t.emplace_back(*this, parallel_for_lambda<Body>(n, c), args...);
234  for (auto& _ : t)
235  _.join();
236  }
237 
238  template <class Body, class... Args>
239  void
241  std::size_t const n,
242  std::size_t number_of_threads,
243  Args const&... args)
244  {
247  t.reserve(number_of_threads);
248  for (std::size_t id = 0; id < number_of_threads; ++id)
249  t.emplace_back(*this, parallel_for_lambda<Body>(n, c), id, args...);
250  for (auto& _ : t)
251  _.join();
252  }
253 
254  //--------------------------------------------------------------------------
255 
256  // Insert only
257  void
259  Section const& config,
260  Params const& params,
261  beast::Journal journal)
262  {
263  DummyScheduler scheduler;
264  auto backend = make_Backend(config, megabytes(4), scheduler, journal);
265  BEAST_EXPECT(backend != nullptr);
266  backend->open();
267 
268  class Body
269  {
270  private:
271  suite& suite_;
272  Backend& backend_;
273  Sequence seq_;
274 
275  public:
276  explicit Body(suite& s, Backend& backend)
277  : suite_(s), backend_(backend), seq_(1)
278  {
279  }
280 
281  void
282  operator()(std::size_t i)
283  {
284  try
285  {
286  backend_.store(seq_.obj(i));
287  }
288  catch (std::exception const& e)
289  {
290  suite_.fail(e.what());
291  }
292  }
293  };
294 
295  try
296  {
297  parallel_for<Body>(
298  params.items,
299  params.threads,
300  std::ref(*this),
301  std::ref(*backend));
302  }
303  catch (std::exception const&)
304  {
305 #if NODESTORE_TIMING_DO_VERIFY
306  backend->verify();
307 #endif
308  Rethrow();
309  }
310  backend->close();
311  }
312 
313  // Fetch existing keys
314  void
316  Section const& config,
317  Params const& params,
318  beast::Journal journal)
319  {
320  DummyScheduler scheduler;
321  auto backend = make_Backend(config, megabytes(4), scheduler, journal);
322  BEAST_EXPECT(backend != nullptr);
323  backend->open();
324 
325  class Body
326  {
327  private:
328  suite& suite_;
329  Backend& backend_;
330  Sequence seq1_;
333 
334  public:
335  Body(
336  std::size_t id,
337  suite& s,
338  Params const& params,
339  Backend& backend)
340  : suite_(s)
341  , backend_(backend)
342  , seq1_(1)
343  , gen_(id + 1)
344  , dist_(0, params.items - 1)
345  {
346  }
347 
348  void
349  operator()(std::size_t i)
350  {
351  try
352  {
355  obj = seq1_.obj(dist_(gen_));
356  backend_.fetch(obj->getHash().data(), &result);
357  suite_.expect(result && isSame(result, obj));
358  }
359  catch (std::exception const& e)
360  {
361  suite_.fail(e.what());
362  }
363  }
364  };
365  try
366  {
367  parallel_for_id<Body>(
368  params.items,
369  params.threads,
370  std::ref(*this),
371  std::ref(params),
372  std::ref(*backend));
373  }
374  catch (std::exception const&)
375  {
376 #if NODESTORE_TIMING_DO_VERIFY
377  backend->verify();
378 #endif
379  Rethrow();
380  }
381  backend->close();
382  }
383 
384  // Perform lookups of non-existent keys
385  void
387  Section const& config,
388  Params const& params,
389  beast::Journal journal)
390  {
391  DummyScheduler scheduler;
392  auto backend = make_Backend(config, megabytes(4), scheduler, journal);
393  BEAST_EXPECT(backend != nullptr);
394  backend->open();
395 
396  class Body
397  {
398  private:
399  suite& suite_;
400  // Params const& params_;
401  Backend& backend_;
402  Sequence seq2_;
405 
406  public:
407  Body(
408  std::size_t id,
409  suite& s,
410  Params const& params,
411  Backend& backend)
412  : suite_(s)
413  //, params_ (params)
414  , backend_(backend)
415  , seq2_(2)
416  , gen_(id + 1)
417  , dist_(0, params.items - 1)
418  {
419  }
420 
421  void
422  operator()(std::size_t i)
423  {
424  try
425  {
426  auto const key = seq2_.key(i);
428  backend_.fetch(key.data(), &result);
429  suite_.expect(!result);
430  }
431  catch (std::exception const& e)
432  {
433  suite_.fail(e.what());
434  }
435  }
436  };
437 
438  try
439  {
440  parallel_for_id<Body>(
441  params.items,
442  params.threads,
443  std::ref(*this),
444  std::ref(params),
445  std::ref(*backend));
446  }
447  catch (std::exception const&)
448  {
449 #if NODESTORE_TIMING_DO_VERIFY
450  backend->verify();
451 #endif
452  Rethrow();
453  }
454  backend->close();
455  }
456 
457  // Fetch with present and missing keys
458  void
460  Section const& config,
461  Params const& params,
462  beast::Journal journal)
463  {
464  DummyScheduler scheduler;
465  auto backend = make_Backend(config, megabytes(4), scheduler, journal);
466  BEAST_EXPECT(backend != nullptr);
467  backend->open();
468 
469  class Body
470  {
471  private:
472  suite& suite_;
473  // Params const& params_;
474  Backend& backend_;
475  Sequence seq1_;
476  Sequence seq2_;
480 
481  public:
482  Body(
483  std::size_t id,
484  suite& s,
485  Params const& params,
486  Backend& backend)
487  : suite_(s)
488  //, params_ (params)
489  , backend_(backend)
490  , seq1_(1)
491  , seq2_(2)
492  , gen_(id + 1)
493  , rand_(0, 99)
494  , dist_(0, params.items - 1)
495  {
496  }
497 
498  void
499  operator()(std::size_t i)
500  {
501  try
502  {
503  if (rand_(gen_) < missingNodePercent)
504  {
505  auto const key = seq2_.key(dist_(gen_));
507  backend_.fetch(key.data(), &result);
508  suite_.expect(!result);
509  }
510  else
511  {
514  obj = seq1_.obj(dist_(gen_));
515  backend_.fetch(obj->getHash().data(), &result);
516  suite_.expect(result && isSame(result, obj));
517  }
518  }
519  catch (std::exception const& e)
520  {
521  suite_.fail(e.what());
522  }
523  }
524  };
525 
526  try
527  {
528  parallel_for_id<Body>(
529  params.items,
530  params.threads,
531  std::ref(*this),
532  std::ref(params),
533  std::ref(*backend));
534  }
535  catch (std::exception const&)
536  {
537 #if NODESTORE_TIMING_DO_VERIFY
538  backend->verify();
539 #endif
540  Rethrow();
541  }
542  backend->close();
543  }
544 
545  // Simulate a rippled workload:
546  // Each thread randomly:
547  // inserts a new key
548  // fetches an old key
549  // fetches recent, possibly non existent data
550  void
551  do_work(Section const& config, Params const& params, beast::Journal journal)
552  {
553  DummyScheduler scheduler;
554  auto backend = make_Backend(config, megabytes(4), scheduler, journal);
555  BEAST_EXPECT(backend != nullptr);
556  backend->setDeletePath();
557  backend->open();
558 
559  class Body
560  {
561  private:
562  suite& suite_;
563  Params const& params_;
564  Backend& backend_;
565  Sequence seq1_;
570 
571  public:
572  Body(
573  std::size_t id,
574  suite& s,
575  Params const& params,
576  Backend& backend)
577  : suite_(s)
578  , params_(params)
579  , backend_(backend)
580  , seq1_(1)
581  , gen_(id + 1)
582  , rand_(0, 99)
583  , recent_(params.items, params.items * 2 - 1)
584  , older_(0, params.items - 1)
585  {
586  }
587 
588  void
589  operator()(std::size_t i)
590  {
591  try
592  {
593  if (rand_(gen_) < 200)
594  {
595  // historical lookup
598  auto const j = older_(gen_);
599  obj = seq1_.obj(j);
601  backend_.fetch(obj->getHash().data(), &result);
602  suite_.expect(result != nullptr);
603  suite_.expect(isSame(result, obj));
604  }
605 
606  char p[2];
607  p[0] = rand_(gen_) < 50 ? 0 : 1;
608  p[1] = 1 - p[0];
609  for (int q = 0; q < 2; ++q)
610  {
611  switch (p[q])
612  {
613  case 0: {
614  // fetch recent
617  auto const j = recent_(gen_);
618  obj = seq1_.obj(j);
619  backend_.fetch(obj->getHash().data(), &result);
620  suite_.expect(!result || isSame(result, obj));
621  break;
622  }
623 
624  case 1: {
625  // insert new
626  auto const j = i + params_.items;
627  backend_.store(seq1_.obj(j));
628  break;
629  }
630  }
631  }
632  }
633  catch (std::exception const& e)
634  {
635  suite_.fail(e.what());
636  }
637  }
638  };
639 
640  try
641  {
642  parallel_for_id<Body>(
643  params.items,
644  params.threads,
645  std::ref(*this),
646  std::ref(params),
647  std::ref(*backend));
648  }
649  catch (std::exception const&)
650  {
651 #if NODESTORE_TIMING_DO_VERIFY
652  backend->verify();
653 #endif
654  Rethrow();
655  }
656  backend->close();
657  }
658 
659  //--------------------------------------------------------------------------
660 
661  using test_func =
662  void (Timing_test::*)(Section const&, Params const&, beast::Journal);
664 
667  test_func f,
668  Section const& config,
669  Params const& params,
670  beast::Journal journal)
671  {
672  auto const start = clock_type::now();
673  (this->*f)(config, params, journal);
674  return std::chrono::duration_cast<duration_type>(
675  clock_type::now() - start);
676  }
677 
678  void
680  std::size_t threads,
681  test_list const& tests,
682  std::vector<std::string> const& config_strings)
683  {
684  using std::setw;
685  int w = 8;
686  for (auto const& test : tests)
687  if (w < test.first.size())
688  w = test.first.size();
689  log << threads << " Thread" << (threads > 1 ? "s" : "") << ", "
690  << default_items << " Objects" << std::endl;
691  {
693  ss << std::left << setw(10) << "Backend" << std::right;
694  for (auto const& test : tests)
695  ss << " " << setw(w) << test.first;
696  log << ss.str() << std::endl;
697  }
698 
699  using namespace beast::severities;
700  test::SuiteJournal journal("Timing_test", *this);
701 
702  for (auto const& config_string : config_strings)
703  {
704  Params params;
705  params.items = default_items;
706  params.threads = threads;
707  for (auto i = default_repeat; i--;)
708  {
709  beast::temp_dir tempDir;
710  Section config = parse(config_string);
711  config.set("path", tempDir.path());
713  ss << std::left << setw(10)
714  << get(config, "type", std::string()) << std::right;
715  for (auto const& test : tests)
716  ss << " " << setw(w)
717  << to_string(
718  do_test(test.second, config, params, journal));
719  ss << " " << to_string(config);
720  log << ss.str() << std::endl;
721  }
722  }
723  }
724 
725  void
726  run() override
727  {
728  testcase("Timing", beast::unit_test::abort_on_fail);
729 
730  /* Parameters:
731 
732  repeat Number of times to repeat each test
733  items Number of objects to create in the database
734 
735  */
736  std::string default_args =
737  "type=nudb"
738 #if RIPPLE_ROCKSDB_AVAILABLE
739  ";type=rocksdb,open_files=2000,filter_bits=12,cache_mb=256,"
740  "file_size_mb=8,file_size_mult=2"
741 #endif
742 #if 0
743  ";type=memory|path=NodeStore"
744 #endif
745  ;
746 
747  test_list const tests = {
748  {"Insert", &Timing_test::do_insert},
749  {"Fetch", &Timing_test::do_fetch},
750  {"Missing", &Timing_test::do_missing},
751  {"Mixed", &Timing_test::do_mixed},
752  {"Work", &Timing_test::do_work}};
753 
754  auto args = arg().empty() ? default_args : arg();
755  std::vector<std::string> config_strings;
756  boost::split(config_strings, args, boost::algorithm::is_any_of(";"));
757  for (auto iter = config_strings.begin(); iter != config_strings.end();)
758  if (iter->empty())
759  iter = config_strings.erase(iter);
760  else
761  ++iter;
762 
763  do_tests(1, tests, config_strings);
764  do_tests(4, tests, config_strings);
765  do_tests(8, tests, config_strings);
766  // do_tests (16, tests, config_strings);
767  }
768 };
769 
770 BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Timing, NodeStore, ripple, 1);
771 
772 } // namespace NodeStore
773 } // namespace ripple
ripple::NodeStore::Timing_test::to_string
static std::string to_string(Section const &config)
Definition: Timing_test.cpp:157
ripple::NodeStore::DummyScheduler
Simple NodeStore Scheduler that just peforms the tasks synchronously.
Definition: DummyScheduler.h:29
ripple::NodeStore::Sequence::batch
void batch(std::size_t n, Batch &b, std::size_t size)
Definition: Timing_test.cpp:121
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
sstream
std::setprecision
T setprecision(T... args)
std::chrono::steady_clock
ripple::NodeStore::Sequence::d_size_
std::uniform_int_distribution< std::uint32_t > d_size_
Definition: Timing_test.cpp:82
ripple::NodeStore::make_Backend
std::unique_ptr< Backend > make_Backend(Section const &config, std::size_t burstSize, Scheduler &scheduler, beast::Journal journal)
Create a Backend.
Definition: ManagerImp.cpp:127
std::string
STL class.
std::shared_ptr< NodeObject >
ripple::NodeStore::Timing_test::default_repeat
const std::size_t default_repeat
Definition: Timing_test.cpp:140
std::uniform_int_distribution< std::uint32_t >
utility
std::exception
STL class.
ripple::NodeStore::Timing_test::do_insert
void do_insert(Section const &config, Params const &params, beast::Journal journal)
Definition: Timing_test.cpp:258
ripple::Generator
Produces a sequence of secp256k1 key pairs.
Definition: SecretKey.cpp:59
std::discrete_distribution< std::uint32_t >
std::vector::reserve
T reserve(T... args)
ripple::NodeStore::Sequence::maxLedger
@ maxLedger
Definition: Timing_test.cpp:77
ripple::NodeStore::Sequence::maxSize
@ maxSize
Definition: Timing_test.cpp:77
std::vector< unsigned char >
std::vector::size
T size(T... args)
ripple::NodeObject::createObject
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
Definition: NodeObject.cpp:37
ripple::NodeStore::Sequence::d_type_
std::discrete_distribution< std::uint32_t > d_type_
Definition: Timing_test.cpp:81
ripple::NodeStore::Timing_test::parallel_for_lambda::operator()
void operator()(Args &&... args)
Definition: Timing_test.cpp:203
std::chrono::milliseconds
iterator
random
std::stringstream
STL class.
beast::severities
A namespace for easy access to logging severity values.
Definition: Journal.h:29
ripple::NodeStore::Timing_test::missingNodePercent
@ missingNodePercent
Definition: Timing_test.cpp:137
ripple::NodeStore::Timing_test::parallel_for_lambda::c_
std::atomic< std::size_t > & c_
Definition: Timing_test.cpp:193
ripple::NodeStore::Backend::store
virtual void store(std::shared_ptr< NodeObject > const &object)=0
Store a single object.
ripple::NodeStore::Sequence
Definition: Timing_test.cpp:74
ripple::NodeStore::Timing_test::do_fetch
void do_fetch(Section const &config, Params const &params, beast::Journal journal)
Definition: Timing_test.cpp:315
std::vector::clear
T clear(T... args)
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:426
ripple::Section::append
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
Definition: BasicConfig.cpp:40
stdexcept
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:73
ripple::NodeStore::rngcpy
static void rngcpy(void *buffer, std::size_t bytes, Generator &g)
Definition: Timing_test.cpp:54
thread
ripple::NodeStore::Timing_test::do_tests
void do_tests(std::size_t threads, test_list const &tests, std::vector< std::string > const &config_strings)
Definition: Timing_test.cpp:679
ripple::NodeStore::Timing_test::parallel_for
void parallel_for(std::size_t const n, std::size_t number_of_threads, Args const &... args)
Definition: Timing_test.cpp:224
ripple::NodeStore::BEAST_DEFINE_TESTSUITE_MANUAL_PRIO
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Timing, NodeStore, ripple, 1)
ripple::NodeStore::Timing_test::do_mixed
void do_mixed(Section const &config, Params const &params, beast::Journal journal)
Definition: Timing_test.cpp:459
ripple::NodeStore::Sequence::obj
std::shared_ptr< NodeObject > obj(std::size_t n)
Definition: Timing_test.cpp:106
chrono
ripple::Rethrow
void Rethrow()
Rethrow the exception currently being handled.
Definition: contract.h:48
ripple::NodeStore::Timing_test::do_work
void do_work(Section const &config, Params const &params, beast::Journal journal)
Definition: Timing_test.cpp:551
ripple::megabytes
constexpr auto megabytes(T value) noexcept
Definition: ByteUtilities.h:34
beast::detail::xor_shift_engine::seed
void seed(result_type seed)
Definition: xor_shift_engine.h:74
ripple::NodeStore::Sequence::minSize
@ minSize
Definition: Timing_test.cpp:77
ripple::NodeStore::Sequence::prefix_
std::uint8_t prefix_
Definition: Timing_test.cpp:80
std::vector::erase
T erase(T... args)
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint8_t
atomic
map
ripple::NodeStore::Timing_test::do_missing
void do_missing(Section const &config, Params const &params, beast::Journal journal)
Definition: Timing_test.cpp:386
ripple::NodeStore::Sequence::Sequence
Sequence(std::uint8_t prefix)
Definition: Timing_test.cpp:85
ripple::test::SuiteJournal
Definition: SuiteJournal.h:88
beast::temp_dir::path
std::string path() const
Get the native path for the temporary directory.
Definition: temp_dir.h:66
ripple::NodeStore::Sequence::key
uint256 key(std::size_t n)
Definition: Timing_test.cpp:96
ripple::NodeStore::Timing_test::Params
Definition: Timing_test.cpp:150
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::NodeStore::Timing_test::Params::items
std::size_t items
Definition: Timing_test.cpp:152
ripple::Section::set
void set(std::string const &key, std::string const &value)
Set a key/value pair.
Definition: BasicConfig.cpp:32
std::endl
T endl(T... args)
ripple::base_uint::begin
iterator begin()
Definition: base_uint.h:124
std::left
T left(T... args)
limits
ripple::NodeStore::Timing_test::parse
static Section parse(std::string s)
Definition: Timing_test.cpp:175
ripple::NodeStore::Sequence::minLedger
@ minLedger
Definition: Timing_test.cpp:77
std::vector::begin
T begin(T... args)
ripple::NodeStore::isSame
bool isSame(std::shared_ptr< NodeObject > const &lhs, std::shared_ptr< NodeObject > const &rhs)
Returns true if objects are identical.
Definition: TestBase.h:57
ripple::NodeStore::Timing_test::to_string
static std::string to_string(duration_type const &d)
Definition: Timing_test.cpp:167
std::chrono::milliseconds::count
T count(T... args)
std::fixed
T fixed(T... args)
ripple::NodeStore::Timing_test::parallel_for_lambda::parallel_for_lambda
parallel_for_lambda(std::size_t n, std::atomic< std::size_t > &c)
Definition: Timing_test.cpp:196
ripple::NodeStore::Timing_test::test_func
void(Timing_test::*)(Section const &, Params const &, beast::Journal) test_func
Definition: Timing_test.cpp:662
ripple::NodeStore::Timing_test::parallel_for_lambda::n_
const std::size_t n_
Definition: Timing_test.cpp:192
std::stringstream::str
T str(T... args)
std::size_t
ripple::NodeStore::Sequence::gen_
beast::xor_shift_engine gen_
Definition: Timing_test.cpp:79
beast::detail::xor_shift_engine
Definition: xor_shift_engine.h:32
ripple::NodeStore::Timing_test::run
void run() override
Definition: Timing_test.cpp:726
std::vector::end
T end(T... args)
ripple::NodeStore::Timing_test
Definition: Timing_test.cpp:132
std::setw
T setw(T... args)
ripple::NodeStore::Timing_test::Params::threads
std::size_t threads
Definition: Timing_test.cpp:153
ripple::NodeStore::Timing_test::default_items
const std::size_t default_items
Definition: Timing_test.cpp:142
ripple::NodeStore::Timing_test::do_test
duration_type do_test(test_func f, Section const &config, Params const &params, beast::Journal journal)
Definition: Timing_test.cpp:666
ripple::NodeStore::Backend::fetch
virtual Status fetch(void const *key, std::shared_ptr< NodeObject > *pObject)=0
Fetch a single object.
type_traits
ripple::NodeStore::Timing_test::parallel_for_lambda
Definition: Timing_test.cpp:189
beast::temp_dir
RAII temporary directory.
Definition: temp_dir.h:33
std::ref
T ref(T... args)
std::exception::what
T what(T... args)
ripple::get
T & get(EitherAmount &amt)
Definition: AmountSpec.h:116
ripple::NodeStore::Timing_test::parallel_for_id
void parallel_for_id(std::size_t const n, std::size_t number_of_threads, Args const &... args)
Definition: Timing_test.cpp:240
ripple::NodeStore::Backend
A backend used for the NodeStore.
Definition: Backend.h:37
std::chrono::steady_clock::now
T now(T... args)