memfile_ubench.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright (C) 2012 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 <sstream>
  15. #include <vector>
  16. #include <map>
  17. #include <iostream>
  18. #include "memfile_ubench.h"
  19. #include <boost/shared_ptr.hpp>
  20. using namespace std;
  21. struct Lease4 {
  22. uint32_t addr;
  23. std::vector<uint8_t> hwaddr;
  24. std::vector<uint8_t> client_id;
  25. uint32_t valid_lft;
  26. uint32_t recycle_time;
  27. time_t cltt;
  28. uint32_t pool_id;
  29. bool fixed;
  30. std::string hostname;
  31. bool fqdn_fwd;
  32. bool fqdn_rev;
  33. std::string options;
  34. std::string comments;
  35. };
  36. typedef boost::shared_ptr<Lease4> Lease4Ptr;
  37. std::map<uint32_t /* addr */, Lease4Ptr /* lease info */> ip4Hash;
  38. typedef std::map<uint32_t, Lease4Ptr>::iterator leaseIt;
  39. bool addLease(Lease4Ptr lease) {
  40. if (ip4Hash.find(lease->addr) != ip4Hash.end()) {
  41. // there is such an address already in the hash
  42. return false;
  43. }
  44. ip4Hash.insert(pair<uint32_t, Lease4Ptr>(lease->addr, lease));
  45. return (true);
  46. }
  47. Lease4Ptr getLease(uint32_t addr) {
  48. leaseIt x = ip4Hash.find(addr);
  49. if (x != ip4Hash.end())
  50. return x->second; // found
  51. // not found
  52. return Lease4Ptr();
  53. }
  54. bool updateLease(uint32_t addr, uint32_t new_cltt) {
  55. leaseIt x = ip4Hash.find(addr);
  56. if (x != ip4Hash.end()) {
  57. x->second->cltt = new_cltt;
  58. return true;
  59. }
  60. return false;
  61. }
  62. bool deleteLease(uint32_t addr) {
  63. leaseIt x = ip4Hash.find(addr);
  64. if (x != ip4Hash.end()) {
  65. ip4Hash.erase(x);
  66. return true;
  67. }
  68. return false;
  69. }
  70. memfile_uBenchmark::memfile_uBenchmark(const string& filename,
  71. uint32_t num_iterations)
  72. :uBenchmark(num_iterations), Filename_(filename) {
  73. }
  74. void memfile_uBenchmark::failure(const char* operation) {
  75. throw string(operation);
  76. }
  77. void memfile_uBenchmark::connect() {
  78. File_.open(Filename_.c_str());
  79. if (!File_.is_open()) {
  80. failure("Failed to create output file");
  81. }
  82. }
  83. void memfile_uBenchmark::disconnect() {
  84. File_.close();
  85. }
  86. void memfile_uBenchmark::createLease4Test() {
  87. if (!File_.is_open()) {
  88. throw "Lease file not open for writing.";
  89. }
  90. uint32_t addr = BASE_ADDR4; // Let's start with 1.0.0.0 address
  91. char hwaddr_tmp[20];
  92. uint8_t hwaddr_len = 20; // not a real field
  93. char client_id_tmp[128];
  94. uint8_t client_id_len = 128;
  95. uint32_t valid_lft = 1000; // we can use the same value for all leases
  96. uint32_t recycle_time = 0; // not supported in any foresable future,
  97. // so keep this as 0
  98. time_t cltt = time(NULL); // timestamp
  99. uint32_t pool_id = 0; // let's use pools 0-99
  100. bool fixed = false; //
  101. string hostname("foo"); // will generate it dynamically
  102. bool fqdn_fwd = true; // let's pretend to do AAAA update
  103. bool fqdn_rev = true; // let's pretend to do PTR update
  104. printf("CREATE: ");
  105. for (uint8_t i = 0; i < 20; i++) {
  106. hwaddr_tmp[i] = 65 + i;
  107. }
  108. vector<uint8_t> hwaddr(hwaddr_tmp, hwaddr_tmp+19);
  109. for (uint8_t i = 0; i < 128; i++) {
  110. client_id_tmp[i] = 33 + i;
  111. }
  112. vector<uint8_t> client_id(client_id_tmp, client_id_tmp+19);
  113. for (uint32_t i = 0; i < Num_; i++) {
  114. cltt++;
  115. Lease4Ptr lease = boost::shared_ptr<Lease4>(new Lease4());
  116. lease->addr = addr;
  117. lease->hwaddr = hwaddr;
  118. lease->client_id = client_id;
  119. lease->valid_lft = valid_lft;
  120. lease->recycle_time = 0;
  121. lease->cltt = cltt;
  122. lease->pool_id = 0;
  123. lease->fixed = false;
  124. lease->hostname = "foo";
  125. lease->fqdn_fwd = true;
  126. lease->fqdn_rev = true;
  127. if (!addLease(lease)) {
  128. failure("addLease() failed");
  129. } else {
  130. printf(".");
  131. };
  132. addr++;
  133. }
  134. printf("\n");
  135. }
  136. void memfile_uBenchmark::searchLease4Test() {
  137. if (!File_.is_open()) {
  138. throw "Lease file not open for writing.";
  139. }
  140. // this formula should roughly find something a lease in 90% cases
  141. float hitRatio = 0.5;
  142. printf("RETRIEVE: ");
  143. for (uint32_t i = 0; i < Num_; i++) {
  144. uint32_t x = BASE_ADDR4 + random() % int(Num_ / hitRatio);
  145. Lease4Ptr lease = getLease(x);
  146. if (lease) {
  147. printf(".");
  148. } else {
  149. printf("X");
  150. }
  151. }
  152. printf("\n");
  153. }
  154. void memfile_uBenchmark::updateLease4Test() {
  155. if (!File_.is_open()) {
  156. throw "Lease file not open for writing.";
  157. }
  158. printf("UPDATE: ");
  159. time_t cltt = time(NULL);
  160. for (uint32_t i = 0; i < Num_; i++) {
  161. uint32_t x = BASE_ADDR4 + random() % Num_;
  162. if (!updateLease(x, cltt)) {
  163. stringstream tmp;
  164. tmp << "UPDATE failed for lease " << hex << x << dec;
  165. failure(tmp.str().c_str());
  166. }
  167. printf(".");
  168. }
  169. printf("\n");
  170. }
  171. void memfile_uBenchmark::deleteLease4Test() {
  172. if (!File_.is_open()) {
  173. throw "Lease file not open for writing.";
  174. }
  175. printf("DELETE: ");
  176. char * errorMsg = NULL;
  177. for (uint32_t i = 0; i < Num_; i++) {
  178. uint32_t x = BASE_ADDR4 + i;
  179. if (!deleteLease(x)) {
  180. stringstream tmp;
  181. tmp << "UPDATE failed for lease " << hex << x << dec;
  182. failure(tmp.str().c_str());
  183. }
  184. printf(".");
  185. }
  186. printf("\n");
  187. }
  188. void memfile_uBenchmark::printInfo() {
  189. cout << "Using memory db + write-only file." << endl;
  190. }
  191. int main(int argc, const char * argv[]) {
  192. const char * filename = "dhcpd.leases";
  193. uint32_t num = 1000000;
  194. memfile_uBenchmark bench(filename, num);
  195. int result = bench.run();
  196. return (result);
  197. }