#include "tt_treap.h" // =================================================================== // Variables // =================================================================== uint32_t tt_num_cached; static tt_entry_t * root; // =================================================================== // Helper declarations // =================================================================== void recurse_tree(tt_entry_t *n); void bubble_up(tt_entry_t *n); tt_entry_t * new_treap_node(const uint64_t key, const enum TT_FLAG flag, const uint8_t depth, const float value, const action_t action); // =================================================================== // Exported functions // =================================================================== int tt_init(void) { root = NULL; tt_num_cached = 0; return EXIT_SUCCESS; } void tt_free(void) { recurse_tree(root); return; } tt_entry_t *tt_seek(const uint64_t key) { if (root == NULL) return NULL; tt_entry_t * n = root; while (n != NULL && n->key != key) { if (n->key > key) n = n->right; else n = n->left; } return n; } int tt_insert(const uint64_t key, const enum TT_FLAG flag, const uint8_t depth, const float value, const action_t action) { tt_entry_t *m = new_treap_node(key, flag, depth, value, action); if (root == NULL) { root = m; tt_num_cached = 1; return EXIT_SUCCESS; } tt_entry_t *s = root, *n = root; // Find the correct position by doing a BST traversal while (n!=NULL) { s = n; if (n->key >= key) n = n->right; else n = n->left; } // Make it a leaf if (s->key > key) s->right = m; else s->left = m; m->parent = s; // Now bubble upward to satisfy the heap property bubble_up(m); tt_num_cached++; return EXIT_SUCCESS; } // =================================================================== // Helper implementations // =================================================================== void recurse_tree(tt_entry_t *n) { if (n==NULL) return; if (n->left != NULL) recurse_tree(n->left); if (n->right != NULL) recurse_tree(n->right); free(n); } tt_entry_t * new_treap_node(const uint64_t key, const enum TT_FLAG flag, const uint8_t depth, const float value, const action_t action) { tt_entry_t *n = malloc(sizeof(struct treap_node_s)); // TODO: trap n->key = key; n->flag = flag; n->depth = depth; n->value = value; n->left = NULL; n->right = NULL; n->parent = NULL; n->action = action; XORSHIFT64; n->weight = RANDOM32; return n; } void rotate_left(tt_entry_t *n) { tt_entry_t *a = n->parent, *b = a->left, *c = n->left; /* We are the right child, so do this a n / \ / \ b n --> a d / \ / \ c d b c */ n->parent = a->parent; // We may have to repair one level up as well if (a->parent!=NULL) { if (a->parent->left == a) a->parent->left = n; else a->parent->right = n; } a->parent = n; n->left = a; a->parent = n; a->left = b; if (b!=NULL) b->parent = a; a->right = c; if (c!=NULL) c->parent = a; } void rotate_right(tt_entry_t *n) { tt_entry_t *a = n->parent, *b = a->right, *d = n->right; /* We are the left child, so do this a n / \ / \ n b --> c a / \ / \ c d d b */ n->parent = a->parent; // We may have to repair one level up as well if (a->parent!=NULL) { if (a->parent->left == a) a->parent->left = n; else a->parent->right = n; } a->parent = n; n->right = a; a->parent = n; a->left = d; if (d!=NULL) d->parent = a; a->right = b; if (b!=NULL) b->parent = a; } //This preserves the BST quality of the treap void bubble_up(tt_entry_t *n) { // Nothing to be done in this case if (n==NULL || n->parent == NULL) return; // Bubble until the treap invariants are satisfied while (n->parent != NULL && n->weight < n->parent->weight) { if (n->parent->left == n) rotate_right(n); else rotate_left(n); } if (n->parent == NULL) root = n; }