diff options
| author | tslil clingman <tslil@posteo.de> | 2021-01-23 15:37:33 -0500 |
|---|---|---|
| committer | tslil <tslil@posteo.de> | 2026-08-28 19:37:41 +0100 |
| commit | 2439dc2ab6a6c2a840c2d2c1deb3949b7b88f415 (patch) | |
| tree | 3c60d1bcec14531e1734f426013ef38d1d2f4df5 /include/cnn1986_treap_cache.c | |
| parent | 3f919c40804f024737bcf4da85027a980db6eb23 (diff) | |
Not correct usage, need to try hashing
Diffstat (limited to 'include/cnn1986_treap_cache.c')
| -rw-r--r-- | include/cnn1986_treap_cache.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/include/cnn1986_treap_cache.c b/include/cnn1986_treap_cache.c new file mode 100644 index 0000000..06553c1 --- /dev/null +++ b/include/cnn1986_treap_cache.c @@ -0,0 +1,198 @@ +#include "cnn1986_treap_cache.h" + +// =================================================================== +// Types +// =================================================================== + +typedef struct treap_node_s { + uint32_t weight; + struct treap_node_s *left, *right, *parent; + colour_stack_t colours[25]; + data_t celldat[25]; + uint8_t white_count, black_count; + float result; +} * TreapNode; + +enum E_CMP { EQ, GT, LT }; + +// =================================================================== +// Variables +// =================================================================== + +uint32_t cnn1986_num_cached; +uint32_t cnn1986_max_num_cached; // TODO +static TreapNode root; +static uint64_t xors = (uint64_t)123134124234879; + +// =================================================================== +// Helper declarations +// =================================================================== + +enum E_CMP compare_data(TreapNode n); +void recurse_tree(TreapNode n); +TreapNode new_treap_node(float in_result); +void bubble_up(TreapNode n); + +#define XORSHIFT { xors ^= xors >> 12; xors ^= xors << 25; xors ^= xors >> 27; } +#define RANDOM (xors *= 0x2545F4914F6CDD1D) + +// =================================================================== +// Exported functions +// =================================================================== + +int cnn1986_cache_init(void) { + root = NULL; + cnn1986_num_cached = 0; + return EXIT_SUCCESS; +} + +void cnn1986_cache_free(void) { + recurse_tree(root); + return; +} + +int cnn1986_cache_seek(float *out_result) { + if (root == NULL) return EXIT_FAILURE; + TreapNode n = root; + enum E_CMP e; + e = compare_data(n); + while (n != NULL && e != EQ) { + if (e == GT) n = n->right; + else n = n->left; + } + if (n == NULL) return EXIT_FAILURE; + *out_result = n->result; + return EXIT_SUCCESS; +} + +int cnn1986_cache_insert(float in_result) { + if (root == NULL) { + root = new_treap_node(in_result); + cnn1986_num_cached = 1; + return EXIT_SUCCESS; + } + TreapNode s = root, n = root, m = new_treap_node(in_result); + // Find the correct position by doing a BST traversal + enum E_CMP e; + while (n!=NULL) { + s = n; + e = compare_data(n); + if (e == LT) n = n->left; + else n = n->right; + } + // Make it a leaf + e = compare_data(s); + if (e == GT) s->right = m; + else s->left = m; + m->parent = s; + // Now bubble upward to satisfy the heap property + bubble_up(m); + cnn1986_num_cached++; + return EXIT_SUCCESS; +} + +// =================================================================== +// Helper implementations +// =================================================================== + +enum E_CMP compare_data(TreapNode n) { + if (n->white_count < white_count) return LT; + else if (n->white_count > white_count) return GT; + + if (n->black_count < black_count) return LT; + else if (n->black_count > black_count) return GT; + + for (int k = 0; k<25; k++) { + if (n->colours[k] < colours[k]) return LT; + if (n->colours[k] > colours[k]) return GT; + } + + for (int k = 0; k<25; k++) { + if (n->celldat[k] < celldat[k]) return LT; + if (n->celldat[k] > celldat[k]) return GT; + } + + return EQ; +} + +void recurse_tree(TreapNode n) { + if (n==NULL) return; + if (n->left != NULL) recurse_tree(n->left); + if (n->right != NULL) recurse_tree(n->right); + free(n); +} + +TreapNode new_treap_node(float in_result) { + TreapNode n = malloc(sizeof(struct treap_node_s)); + // TODO: trap + n->left = NULL; + n->right = NULL; + n->parent = NULL; + XORSHIFT; n->weight = RANDOM; + // Set key + for (int k = 0; k<25; k++) { + n->celldat[k] = celldat[k]; + n->colours[k] = colours[k]; + } + n->black_count = black_count; + n->white_count = white_count; + // Set value + n->result = in_result; + return n; +} + +void rotate_left(TreapNode n) { + TreapNode 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(TreapNode n) { + TreapNode 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(TreapNode 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; +} |
