diff --git a/Tampermonkey.js b/Tampermonkey.js index 69bd604ebc5022d001acc7ff006391442dbdbec9..b45a3ae56476341c031b5fa8799f5e311f35bc51 100644 --- a/Tampermonkey.js +++ b/Tampermonkey.js @@ -1,47 +1,62 @@ -window.addEventListener('load', function() { - var table_AlgorithmSpecificControls = document.getElementById("AlgorithmSpecificControls"); - var insert_input = table_AlgorithmSpecificControls.children[0].children[0]; - var insert_button = table_AlgorithmSpecificControls.children[1].children[0]; - var delete_input = table_AlgorithmSpecificControls.children[2].children[0]; - var delete_button = table_AlgorithmSpecificControls.children[3].children[0]; - - var table_GeneralAnimationControls = document.getElementById("GeneralAnimationControls"); - var skip_button = table_GeneralAnimationControls.children[4].children[0]; - - function timeout(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - - async function insert_keys(keys) { - for (var i = 0; i < keys.length; i++) { - insert_input.value = keys[i]; - insert_button.click(); - skip_button.click(); - await timeout(10); - } - } - - async function delete_keys(keys) { - for (var i = 0; i < keys.length; i++) { - delete_input.value = keys[i]; - delete_button.click(); - skip_button.click(); - await timeout(10); - } - } - - async function do_stuff() { - var inputs_MaxDegree = document.getElementsByName("MaxDegree"); - var input_MaxDegree = inputs_MaxDegree[2]; - input_MaxDegree.checked = true; - input_MaxDegree.click(); - await timeout(500); - - await insert_keys([8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55]); - await delete_keys([65, 57, 47, 28, 51]); - await insert_keys([100]); - await delete_keys([48, 41, 60, 5, 8, 21, 86, 100, 88, 95, 49, 56, 55]); - } - - do_stuff(); -}, false); +// ==UserScript== +// @name Automation +// @namespace http://tampermonkey.net/ +// @version 0.1 +// @description try to take over the world! +// @author You +// @match https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html +// @icon https://www.google.com/s2/favicons?sz=64&domain=usfca.edu +// @grant none +// ==/UserScript== + +(function() { + 'use strict'; + + window.addEventListener('load', function() { + var table_AlgorithmSpecificControls = document.getElementById("AlgorithmSpecificControls"); + var insert_input = table_AlgorithmSpecificControls.children[0].children[0]; + var insert_button = table_AlgorithmSpecificControls.children[1].children[0]; + var delete_input = table_AlgorithmSpecificControls.children[2].children[0]; + var delete_button = table_AlgorithmSpecificControls.children[3].children[0]; + + var table_GeneralAnimationControls = document.getElementById("GeneralAnimationControls"); + var skip_button = table_GeneralAnimationControls.children[4].children[0]; + + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async function insert_keys(keys) { + for (var i = 0; i < keys.length; i++) { + insert_input.value = keys[i]; + insert_button.click(); + skip_button.click(); + await timeout(10); + } + } + + async function delete_keys(keys) { + for (var i = 0; i < keys.length; i++) { + delete_input.value = keys[i]; + delete_button.click(); + skip_button.click(); + await timeout(10); + } + } + + async function do_stuff() { + var inputs_MaxDegree = document.getElementsByName("MaxDegree"); + var input_MaxDegree = inputs_MaxDegree[2]; + input_MaxDegree.checked = true; + input_MaxDegree.click(); + await timeout(500); + + await insert_keys([8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55]); + await delete_keys([65, 57, 47]); + // await insert_keys([100]); + // await delete_keys([48, 41, 60, 5, 8, 21, 86, 100, 88, 95, 49, 56, 55]); + } + + do_stuff(); + }, false); +})(); diff --git a/src/BPTree.c b/src/BPTree.c index b85d72184d2c732981cbbe0774a6c0349bcf673c..32d82bac5efcbbc567afd022b6d038683febd7a2 100644 --- a/src/BPTree.c +++ b/src/BPTree.c @@ -66,14 +66,14 @@ void BPTree_destroy(BPTreeNode **root) { void BPTree_print(BPTreeNode *root, int depth) { for (int i = 0; i < depth; i++) { - printf(" "); + printf(" "); } IntegerArray_print(root->keys); for (int i = 0; i < depth; i++) { - printf(" "); + printf(" "); } - printf("*"); + printf(" "); IntegerArray_print(root->data); for (int i = 0; i < root->children->size; i++) { @@ -280,8 +280,9 @@ static void steal_leaf(BPTreeNode *parent, BPTreeNode *node, int child_index, BP static void _merge(BPTreeNode *parent, BPTreeNode *main_node, BPTreeNode *secondary_node, int pivot_index); static void merge(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling); static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node); -static void deletion_rebalance(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key); -static void replace_deleted_key_internal(BPTreeNodeArray *parents, int i, uint64_t key); +static bool _BPTree_delete(BPTreeNode *root, uint64_t key, BPTreeNode *parent); +static BPTreeNode *traverse(BPTreeNode *root, uint64_t key); +static void deletion_rebalance(BPTreeNode *root, BPTreeNode *parent); static uint64_t find_smallest_key(BPTreeNode *root) { if (root->is_leaf) { @@ -414,67 +415,58 @@ static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node) { return parent->children->items[child_index - 1]; } -static void deletion_rebalance(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key) { - BPTreeNode *parent = NULL; +static BPTreeNode *traverse(BPTreeNode *root, uint64_t key) { + int virtual_insertion_index = lower_bound(root->keys, key); - if (parents->size > 0) { - parent = BPTreeNodeArray_pop(parents); + if (virtual_insertion_index < root->keys->size && root->keys->items[virtual_insertion_index] == key) { + virtual_insertion_index += 1; } - if (node != root && node->keys->size < node->order) { - int child_index = find_child_index(parent, node); - BPTreeNode *sibling = find_sibling(parent, node); - - if (sibling->keys->size == sibling->order) { - merge(parent, node, sibling); + return root->children->items[virtual_insertion_index]; +} - if (parent == root && parent->keys->size == 0) { - shrink(root); - parent = NULL; - } - } else { - if (node->is_leaf) { - steal_leaf(parent, node, child_index, sibling); - } else { - steal_internal(parent, node, child_index, sibling); - } - } - } +static void deletion_rebalance(BPTreeNode *root, BPTreeNode *parent) { + int child_index = find_child_index(parent, root); + BPTreeNode *sibling = find_sibling(parent, root); - if (parent != NULL) { - deletion_rebalance(root, parents, parent, key); + if (sibling->keys->size == sibling->order) { + merge(parent, root, sibling); + } else if (root->is_leaf) { + steal_leaf(parent, root, child_index, sibling); + } else { + steal_internal(parent, root, child_index, sibling); } } -static void replace_deleted_key_internal(BPTreeNodeArray *parents, int i, uint64_t key) { - if (i < 0) { - return; +static bool _BPTree_delete(BPTreeNode *root, uint64_t key, BPTreeNode *parent) { + if (!root->is_leaf && !_BPTree_delete(traverse(root, key), key, root)) { + return false; } - BPTreeNode *node = parents->items[i]; int index; - if (IntegerArray_binary_search(node->keys, key, &index)) { - node->keys->items[index] = find_smallest_key(node->children->items[index + 1]); + bool is_found = IntegerArray_binary_search(root->keys, key, &index); + if (root->is_leaf && !is_found) { + return false; } - replace_deleted_key_internal(parents, i - 1, key); -} - -void BPTree_delete(BPTreeNode *root, uint64_t key) { - BPTreeNodeArray *parents; - BPTreeNode *leaf = find_leaf(root, key, &parents); + if (root->is_leaf) { + IntegerArray_delete_at_index(root->keys, index); + IntegerArray_delete_at_index(root->data, index); + } else if (is_found) { + root->keys->items[index] = find_smallest_key(root->children->items[index + 1]); + } - int index; - if (!IntegerArray_binary_search(leaf->keys, key, &index)) { - BPTreeNodeArray_destroy(&parents); - return; + if (parent == NULL && root->keys->size == 0) { + shrink(root); } - IntegerArray_delete_at_index(leaf->keys, index); - IntegerArray_delete_at_index(leaf->data, index); + if (parent != NULL && root->keys->size < root->order) { + deletion_rebalance(root, parent); + } - replace_deleted_key_internal(parents, parents->size - 1, key); - deletion_rebalance(root, parents, leaf, key); + return true; +} - BPTreeNodeArray_destroy(&parents); +bool BPTree_delete(BPTreeNode *root, uint64_t key) { + return _BPTree_delete(root, key, NULL); } diff --git a/src/BPTree.h b/src/BPTree.h index 2c83b499629a5f195895f6ac10927aa5b17c77f0..74fb34e299448c7f6269a4f3913538e2db45dc5d 100644 --- a/src/BPTree.h +++ b/src/BPTree.h @@ -27,6 +27,6 @@ void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data); // Deletion -void BPTree_delete(BPTreeNode *root, uint64_t key); +bool BPTree_delete(BPTreeNode *root, uint64_t key); #endif