diff options
Diffstat (limited to 'include/cnn1986_cache.c')
| -rw-r--r-- | include/cnn1986_cache.c | 98 |
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; +} |
