You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.1 KiB

  1. /* -*- mode: C; c-basic-offset: 4 -*- */
  2. #ident "$Id$"
  3. #ident "Copyright (c) 2011 Tokutek Inc. All rights reserved."
  4. // generate a tree with a single leaf node containing duplicate keys
  5. // check that brt verify finds them
  6. #include "includes.h"
  7. #include <brt-cachetable-wrappers.h>
  8. #include "test.h"
  9. static BRTNODE
  10. make_node(BRT brt, int height) {
  11. BRTNODE node = NULL;
  12. int n_children = (height == 0) ? 1 : 0;
  13. toku_create_new_brtnode(brt, &node, height, n_children);
  14. if (n_children) BP_STATE(node,0) = PT_AVAIL;
  15. return node;
  16. }
  17. static void
  18. append_leaf(BRTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) {
  19. assert(leafnode->height == 0);
  20. DBT thekey; toku_fill_dbt(&thekey, key, keylen);
  21. DBT theval; toku_fill_dbt(&theval, val, vallen);
  22. // get an index that we can use to create a new leaf entry
  23. uint32_t idx = toku_omt_size(BLB_BUFFER(leafnode, 0));
  24. // apply an insert to the leaf node
  25. MSN msn = next_dummymsn();
  26. BRT_MSG_S cmd = { BRT_INSERT, msn, xids_get_root_xids(), .u.id = { &thekey, &theval } };
  27. brt_leaf_apply_cmd_once(leafnode, BLB(leafnode, 0), &cmd, idx, NULL, NULL, NULL, NULL);
  28. // dont forget to dirty the node
  29. leafnode->dirty = 1;
  30. }
  31. static void
  32. populate_leaf(BRTNODE leafnode, int k, int v) {
  33. append_leaf(leafnode, &k, sizeof k, &v, sizeof v);
  34. }
  35. static void
  36. test_dup_in_leaf(int do_verify) {
  37. int r;
  38. // cleanup
  39. char fname[]= __FILE__ ".brt";
  40. r = unlink(fname);
  41. assert(r == 0 || (r == -1 && errno == ENOENT));
  42. // create a cachetable
  43. CACHETABLE ct = NULL;
  44. r = toku_brt_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER);
  45. assert(r == 0);
  46. // create the brt
  47. TOKUTXN null_txn = NULL;
  48. DB *null_db = NULL;
  49. BRT brt = NULL;
  50. r = toku_open_brt(fname, 1, &brt, 1024, 256, ct, null_txn, toku_builtin_compare_fun, null_db);
  51. assert(r == 0);
  52. // discard the old root block
  53. u_int32_t fullhash = 0;
  54. CACHEKEY *rootp;
  55. rootp = toku_calculate_root_offset_pointer(brt->h, &fullhash);
  56. BRTNODE newroot = make_node(brt, 0);
  57. populate_leaf(newroot, htonl(2), 1);
  58. populate_leaf(newroot, htonl(2), 2);
  59. // set the new root to point to the new tree
  60. *rootp = newroot->thisnodename;
  61. // unpin the new root
  62. toku_unpin_brtnode(brt, newroot);
  63. if (do_verify) {
  64. r = toku_verify_brt(brt);
  65. assert(r != 0);
  66. }
  67. // flush to the file system
  68. r = toku_close_brt(brt, 0);
  69. assert(r == 0);
  70. // shutdown the cachetable
  71. r = toku_cachetable_close(&ct);
  72. assert(r == 0);
  73. }
  74. static int
  75. usage(void) {
  76. return 1;
  77. }
  78. int
  79. test_main (int argc , const char *argv[]) {
  80. int do_verify = 1;
  81. for (int i = 1; i < argc; i++) {
  82. const char *arg = argv[i];
  83. if (strcmp(arg, "-v") == 0) {
  84. verbose++;
  85. continue;
  86. }
  87. if (strcmp(arg, "-q") == 0) {
  88. verbose = 0;
  89. continue;
  90. }
  91. if (strcmp(arg, "--verify") == 0 && i+1 < argc) {
  92. do_verify = atoi(argv[++i]);
  93. continue;
  94. }
  95. return usage();
  96. }
  97. test_dup_in_leaf(do_verify);
  98. return 0;
  99. }