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