fake_resolution.cc 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <resolver/bench/fake_resolution.h>
  15. #include <resolver/bench/dummy_work.h>
  16. #include <algorithm>
  17. #include <cstdlib>
  18. namespace isc {
  19. namespace resolver {
  20. namespace bench {
  21. // Parameters of the generated queries.
  22. // How much work is each operation?
  23. const size_t parse_size = 10000000;
  24. const size_t render_size = 10000000;
  25. const size_t send_size = 100000;
  26. const size_t cache_read_size = 1000000;
  27. const size_t cache_write_size = 1000000;
  28. // How large a change is to terminate in this iteration (either by getting
  29. // the complete answer, or by finding it in the cache). With 0.5, half the
  30. // queries are found in the cache directly. Half of the rest needs just one
  31. // upstream query. Etc.
  32. const float chance_complete = 0.5;
  33. // Number of milliseconds an upstream query can take. It picks a random number
  34. // in between.
  35. const size_t upstream_time_min = 2;
  36. const size_t upstream_time_max = 30;
  37. FakeQuery::FakeQuery(FakeInterface& interface) :
  38. interface_(&interface),
  39. outstanding_(false)
  40. {
  41. // Schedule what tasks are needed.
  42. // First, parse the query
  43. steps_.push_back(Step(Compute, parse_size));
  44. // Look into the cache if it is there
  45. steps_.push_back(Step(CacheRead, cache_read_size));
  46. while (1.0 * random() / RAND_MAX > chance_complete) {
  47. // Needs another step of recursion. Render the upstream query.
  48. steps_.push_back(Step(Compute, render_size));
  49. // Send it and wait for the answer.
  50. steps_.push_back(Step(Upstream, upstream_time_min +
  51. (random() *
  52. (upstream_time_max - upstream_time_min) /
  53. RAND_MAX)));
  54. // After it comes, parse the answer and store it in the cache.
  55. steps_.push_back(Step(Compute, parse_size));
  56. steps_.push_back(Step(CacheWrite, cache_write_size));
  57. }
  58. // Last, render the answer and send it.
  59. steps_.push_back(Step(Compute, render_size));
  60. steps_.push_back(Step(Send, send_size));
  61. // Reverse it, so we can pop_back the tasks as we work on them.
  62. std::reverse(steps_.begin(), steps_.end());
  63. }
  64. void
  65. FakeQuery::performTask(const StepCallback& callback) {
  66. // nextTask also does all the sanity checking we need.
  67. if (nextTask() == Upstream) {
  68. outstanding_ = true;
  69. interface_->scheduleUpstreamAnswer(this, callback,
  70. steps_.back().second);
  71. steps_.pop_back();
  72. } else {
  73. for (size_t i = 0; i < steps_.back().second; ++i) {
  74. dummy_work();
  75. }
  76. steps_.pop_back();
  77. callback();
  78. }
  79. }
  80. }
  81. }
  82. }