aboutsummaryrefslogtreecommitdiff
path: root/include/cnn1986_cache.c
blob: 303ef5792a7c0739efa62347de8485d998ab50ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#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 = 1000000;
node_t *head = NULL, *tail = NULL;

int cnn1986_cache_init(void) { return EXIT_SUCCESS; }

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(const uint64_t key[4],
											 float *out_result) {
	node_t *c = head;
	while (c != NULL) {
		// Either seek next or move to front and return
		uint8_t fail = 0;
		for (int k=0; k<4; k++) {
			if (c->key[k] != key[k]) {
				fail = 1; break;
			}
		}

		if (fail == 1) {
			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;
		}
	}
	// Failed to find it
	return EXIT_FAILURE;
}

int cnn1986_cache_insert(const uint64_t key[4], 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;
	for (int k=0; k<4; k++) new->key[k] = key[k];
	new->result = in_result;
	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;
}