Skip to content
Snippets Groups Projects
Commit 11a5e65f authored by Florian Burgener's avatar Florian Burgener
Browse files

Deletion: conversion from iterative to recursive

parent 25661ee8
No related branches found
No related tags found
No related merge requests found
window.addEventListener('load', function() { // ==UserScript==
var table_AlgorithmSpecificControls = document.getElementById("AlgorithmSpecificControls"); // @name Automation
var insert_input = table_AlgorithmSpecificControls.children[0].children[0]; // @namespace http://tampermonkey.net/
var insert_button = table_AlgorithmSpecificControls.children[1].children[0]; // @version 0.1
var delete_input = table_AlgorithmSpecificControls.children[2].children[0]; // @description try to take over the world!
var delete_button = table_AlgorithmSpecificControls.children[3].children[0]; // @author You
// @match https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html
var table_GeneralAnimationControls = document.getElementById("GeneralAnimationControls"); // @icon https://www.google.com/s2/favicons?sz=64&domain=usfca.edu
var skip_button = table_GeneralAnimationControls.children[4].children[0]; // @grant none
// ==/UserScript==
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); (function() {
} 'use strict';
async function insert_keys(keys) { window.addEventListener('load', function() {
for (var i = 0; i < keys.length; i++) { var table_AlgorithmSpecificControls = document.getElementById("AlgorithmSpecificControls");
insert_input.value = keys[i]; var insert_input = table_AlgorithmSpecificControls.children[0].children[0];
insert_button.click(); var insert_button = table_AlgorithmSpecificControls.children[1].children[0];
skip_button.click(); var delete_input = table_AlgorithmSpecificControls.children[2].children[0];
await timeout(10); var delete_button = table_AlgorithmSpecificControls.children[3].children[0];
}
} var table_GeneralAnimationControls = document.getElementById("GeneralAnimationControls");
var skip_button = table_GeneralAnimationControls.children[4].children[0];
async function delete_keys(keys) {
for (var i = 0; i < keys.length; i++) { function timeout(ms) {
delete_input.value = keys[i]; return new Promise(resolve => setTimeout(resolve, ms));
delete_button.click(); }
skip_button.click();
await timeout(10); async function insert_keys(keys) {
} for (var i = 0; i < keys.length; i++) {
} insert_input.value = keys[i];
insert_button.click();
async function do_stuff() { skip_button.click();
var inputs_MaxDegree = document.getElementsByName("MaxDegree"); await timeout(10);
var input_MaxDegree = inputs_MaxDegree[2]; }
input_MaxDegree.checked = true; }
input_MaxDegree.click();
await timeout(500); async function delete_keys(keys) {
for (var i = 0; i < keys.length; i++) {
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]); delete_input.value = keys[i];
await delete_keys([65, 57, 47, 28, 51]); delete_button.click();
await insert_keys([100]); skip_button.click();
await delete_keys([48, 41, 60, 5, 8, 21, 86, 100, 88, 95, 49, 56, 55]); await timeout(10);
} }
}
do_stuff();
}, false); 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);
})();
...@@ -66,14 +66,14 @@ void BPTree_destroy(BPTreeNode **root) { ...@@ -66,14 +66,14 @@ void BPTree_destroy(BPTreeNode **root) {
void BPTree_print(BPTreeNode *root, int depth) { void BPTree_print(BPTreeNode *root, int depth) {
for (int i = 0; i < depth; i++) { for (int i = 0; i < depth; i++) {
printf(" "); printf(" ");
} }
IntegerArray_print(root->keys); IntegerArray_print(root->keys);
for (int i = 0; i < depth; i++) { for (int i = 0; i < depth; i++) {
printf(" "); printf(" ");
} }
printf("*"); printf(" ");
IntegerArray_print(root->data); IntegerArray_print(root->data);
for (int i = 0; i < root->children->size; i++) { 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 ...@@ -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 *main_node, BPTreeNode *secondary_node, int pivot_index);
static void merge(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling); static void merge(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling);
static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node); static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node);
static void deletion_rebalance(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key); static bool _BPTree_delete(BPTreeNode *root, uint64_t key, BPTreeNode *parent);
static void replace_deleted_key_internal(BPTreeNodeArray *parents, int i, uint64_t key); static BPTreeNode *traverse(BPTreeNode *root, uint64_t key);
static void deletion_rebalance(BPTreeNode *root, BPTreeNode *parent);
static uint64_t find_smallest_key(BPTreeNode *root) { static uint64_t find_smallest_key(BPTreeNode *root) {
if (root->is_leaf) { if (root->is_leaf) {
...@@ -414,67 +415,58 @@ static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node) { ...@@ -414,67 +415,58 @@ static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node) {
return parent->children->items[child_index - 1]; return parent->children->items[child_index - 1];
} }
static void deletion_rebalance(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key) { static BPTreeNode *traverse(BPTreeNode *root, uint64_t key) {
BPTreeNode *parent = NULL; int virtual_insertion_index = lower_bound(root->keys, key);
if (parents->size > 0) { if (virtual_insertion_index < root->keys->size && root->keys->items[virtual_insertion_index] == key) {
parent = BPTreeNodeArray_pop(parents); virtual_insertion_index += 1;
} }
if (node != root && node->keys->size < node->order) { return root->children->items[virtual_insertion_index];
int child_index = find_child_index(parent, node); }
BPTreeNode *sibling = find_sibling(parent, node);
if (sibling->keys->size == sibling->order) {
merge(parent, node, sibling);
if (parent == root && parent->keys->size == 0) { static void deletion_rebalance(BPTreeNode *root, BPTreeNode *parent) {
shrink(root); int child_index = find_child_index(parent, root);
parent = NULL; BPTreeNode *sibling = find_sibling(parent, root);
}
} else {
if (node->is_leaf) {
steal_leaf(parent, node, child_index, sibling);
} else {
steal_internal(parent, node, child_index, sibling);
}
}
}
if (parent != NULL) { if (sibling->keys->size == sibling->order) {
deletion_rebalance(root, parents, parent, key); 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) { static bool _BPTree_delete(BPTreeNode *root, uint64_t key, BPTreeNode *parent) {
if (i < 0) { if (!root->is_leaf && !_BPTree_delete(traverse(root, key), key, root)) {
return; return false;
} }
BPTreeNode *node = parents->items[i];
int index; int index;
if (IntegerArray_binary_search(node->keys, key, &index)) { bool is_found = IntegerArray_binary_search(root->keys, key, &index);
node->keys->items[index] = find_smallest_key(node->children->items[index + 1]); if (root->is_leaf && !is_found) {
return false;
} }
replace_deleted_key_internal(parents, i - 1, key); if (root->is_leaf) {
} IntegerArray_delete_at_index(root->keys, index);
IntegerArray_delete_at_index(root->data, index);
void BPTree_delete(BPTreeNode *root, uint64_t key) { } else if (is_found) {
BPTreeNodeArray *parents; root->keys->items[index] = find_smallest_key(root->children->items[index + 1]);
BPTreeNode *leaf = find_leaf(root, key, &parents); }
int index; if (parent == NULL && root->keys->size == 0) {
if (!IntegerArray_binary_search(leaf->keys, key, &index)) { shrink(root);
BPTreeNodeArray_destroy(&parents);
return;
} }
IntegerArray_delete_at_index(leaf->keys, index); if (parent != NULL && root->keys->size < root->order) {
IntegerArray_delete_at_index(leaf->data, index); deletion_rebalance(root, parent);
}
replace_deleted_key_internal(parents, parents->size - 1, key); return true;
deletion_rebalance(root, parents, leaf, key); }
BPTreeNodeArray_destroy(&parents); bool BPTree_delete(BPTreeNode *root, uint64_t key) {
return _BPTree_delete(root, key, NULL);
} }
...@@ -27,6 +27,6 @@ void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data); ...@@ -27,6 +27,6 @@ void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data);
// Deletion // Deletion
void BPTree_delete(BPTreeNode *root, uint64_t key); bool BPTree_delete(BPTreeNode *root, uint64_t key);
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment