core: Split-off cache, display, reader.
[mes.git] / cache.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #define CACHE_SIZE 30
22 #define ENV_HEAD 15
23
24 #if! ENV_CACHE
25 SCM cache_invalidate (SCM x){}
26 SCM cache_invalidate_range (SCM p,SCM a){}
27 SCM cache_save (SCM p){}
28 SCM cache_lookup (SCM x){}
29 #else // ENV_CACHE
30
31 SCM env_cache_cars[CACHE_SIZE];
32 SCM env_cache_cdrs[CACHE_SIZE];
33 int cache_threshold = 0;
34 SCM
35 cache_save (SCM p)
36 {
37   int n = g_cells[car (p)].hits;
38   if (n < cache_threshold) return cell_unspecified;
39   int j = -1;
40   for (int i=0; i < CACHE_SIZE; i++) {
41     if (!env_cache_cars[i]) {
42       j = i;
43       break;
44     }
45     if (env_cache_cars[i] == car (p)) return cell_unspecified;
46     if (n > g_cells[env_cache_cars[i]].hits) {
47       n = g_cells[env_cache_cars[i]].hits;
48       j = i;
49     }
50   }
51   if (j >= 0) {
52     cache_threshold = g_cells[car (p)].hits;
53     env_cache_cars[j] = car (p);
54     env_cache_cdrs[j] = cdr (p);
55   }
56   return cell_unspecified;
57 }
58
59 SCM
60 cache_lookup (SCM x)
61 {
62   for (int i=0; i < CACHE_SIZE; i++) {
63     if (!env_cache_cars[i]) break;
64     if (env_cache_cars[i] == x) return env_cache_cdrs[i];
65   }
66   return cell_undefined;
67 }
68
69 SCM
70 cache_invalidate (SCM x)
71 {
72   for (int i=0; i < CACHE_SIZE; i++) {
73     if (env_cache_cars[i] == x) {
74       env_cache_cars[i] = 0;
75       break;
76     }
77   }
78   return cell_unspecified;
79 }
80
81 SCM
82 cache_invalidate_range (SCM p, SCM a)
83 {
84   do {
85     cache_invalidate (caar (p));
86     p = cdr (p);
87   } while (p != a);
88   return cell_unspecified;
89 }
90
91 SCM
92 assq_ref_cache (SCM x, SCM a) ///((internal))
93 {
94   g_cells[x].hits++;
95   SCM c = cache_lookup (x);
96   if (c != cell_undefined) return c;
97   int i = 0;
98   while (a != cell_nil && x != CAAR (a)) {i++;a = cdr (a);}
99   if (a == cell_nil) return cell_undefined;
100   if (i>ENV_HEAD) cache_save (car (a));
101   return cdar (a);
102 }
103 #endif // ENV_CACHE