aboutsummaryrefslogtreecommitdiff
path: root/include/cnn1986_cache.c
diff options
context:
space:
mode:
authortslil clingman <tslil@posteo.de>2021-01-22 13:36:32 -0500
committertslil <tslil@posteo.de>2026-08-28 19:37:41 +0100
commite6a5b63bbeb36ff9d9d5f2c002395012a0d41fdf (patch)
tree36419c24a19ea6a7ec511cd67a54d9229d67ae1c /include/cnn1986_cache.c
parent703c875144bb365e6448b41493aa0d6615e10520 (diff)
Trying caching to speed things up
Diffstat (limited to 'include/cnn1986_cache.c')
-rw-r--r--include/cnn1986_cache.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/include/cnn1986_cache.c b/include/cnn1986_cache.c
new file mode 100644
index 0000000..d9545ac
--- /dev/null
+++ b/include/cnn1986_cache.c
@@ -0,0 +1,98 @@
+#include "cnn1986_cache.h"
+
+#define DATA_STONE_SHIFT 6
+#define DATA_COUNT_SHIFT (DATA_STONE_SHIFT+2)
+#define COLOUR_MASK 0x3F // 0b00111111
+
+uint32_t cnn1986_num_cached, cnn1986_max_num_cached;
+node_t *head = NULL, *tail = NULL;
+
+void cnn1986_cache_free(void) {
+ node_t *c = head, *n;
+ while (c) {
+ n = c->next;
+ free(c);
+ c = n;
+ }
+ head = NULL;
+ tail = NULL;
+}
+
+int cnn1986_cache_seek(float *out_result) {
+ node_t *c = head;
+
+ if (c == NULL) return EXIT_FAILURE;
+
+ uint8_t comp_data[25], fail;
+ for (int k=0; k<25; k++) {
+ comp_data[k] = (colours[k] & COLOUR_MASK)
+ | (STONE_AT(k) << DATA_STONE_SHIFT)
+ | (COUNT_AT(k) << DATA_COUNT_SHIFT);
+ }
+
+ // We've checked c = head already, so uncoditionally test it
+ do {
+ // Compare
+ fail = 0;
+ if (c->black_count == black_count && c->white_count == white_count) {
+ for (int k=0; k<25; k++) {
+ if (comp_data[k] != c->data[k]) {
+ fail = 1;
+ break;
+ }
+ }
+ } else { fail = 1; }
+
+ // Either seek next or move to front and return
+ if (fail) {
+ c = c->next;
+ } else {
+ *out_result = c->result;
+
+ // Move to front
+ if (c != head) {
+ if (tail == c) tail=c->prev;
+ if (c->next) c->next->prev = c->prev;
+ c->prev->next = c->next;
+ c->prev = NULL;
+ c->next = head;
+ head->prev = c;
+ head = c;
+ }
+
+ return EXIT_SUCCESS;
+ }
+ } while (c);
+
+ // Failed to find it
+ return EXIT_FAILURE;
+}
+
+int cnn1986_cache_insert(float in_result) {
+ node_t *new = malloc(sizeof(node_t));
+ if (new == NULL) return EXIT_FAILURE;
+ // TODO: check errno
+ new->prev = NULL;
+ new->next = head;
+ if (head) head->prev = new;
+ head = new;
+ new->result = in_result;
+ new->white_count = white_count;
+ new->black_count = black_count;
+ for (int k=0; k<25; k++) {
+ new->data[k] = (colours[k] & COLOUR_MASK)
+ | (STONE_AT(k) << DATA_STONE_SHIFT)
+ | (COUNT_AT(k) << DATA_COUNT_SHIFT);
+ }
+ if (cnn1986_num_cached == 0) tail = new;
+ cnn1986_num_cached++;
+
+ if (cnn1986_num_cached > cnn1986_max_num_cached) {
+ tail = tail->prev;
+ free(tail->next);
+ tail->next = NULL;
+ cnn1986_num_cached--;
+ }
+
+ return EXIT_SUCCESS;
+}