summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/CLIncludeFileCache.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--command_line/CmdLine/Src/CLIncludeFileCache.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/command_line/CmdLine/Src/CLIncludeFileCache.c b/command_line/CmdLine/Src/CLIncludeFileCache.c
index e69de29..d479f36 100644
--- a/command_line/CmdLine/Src/CLIncludeFileCache.c
+++ b/command_line/CmdLine/Src/CLIncludeFileCache.c
@@ -0,0 +1,159 @@
+#include "cmdline.h"
+
+typedef struct CacheEntry {
+ struct CacheEntry *next;
+ struct CacheEntry *prev;
+ int locked;
+ int precompiled;
+ Handle text;
+ OSSpec spec;
+ UInt32 size;
+ UInt32 when;
+} CacheEntry;
+
+enum {
+ CACHE_SIZE = 0x800000
+};
+
+static CacheEntry *cachelist;
+static CacheEntry *freelist;
+static UInt32 availablecache;
+
+static CacheEntry *makecacheentry() {
+ CacheEntry *c = freelist;
+ if (c) {
+ freelist = c->next;
+ return c;
+ } else {
+ return xmalloc("include file cache", sizeof(CacheEntry));
+ }
+}
+
+static void insertcacheentry(CacheEntry *c) {
+ if (cachelist)
+ cachelist->prev = c;
+ c->next = cachelist;
+ c->prev = NULL;
+ cachelist = c;
+}
+
+static void deletecacheentry(CacheEntry *c) {
+ if (c->next)
+ c->next->prev = c->prev;
+ if (c->prev)
+ c->prev->next = c->next;
+ else
+ cachelist = c->next;
+}
+
+void InitializeIncludeCache() {
+ freelist = NULL;
+ cachelist = NULL;
+ availablecache = CACHE_SIZE;
+}
+
+void CleanupIncludeCache() {
+ CacheEntry *c;
+ CacheEntry *c1;
+
+ for (c = cachelist; c; c = c1) {
+ c1 = c->next;
+ if (c->text)
+ DisposeHandle(c->text);
+ xfree(c);
+ }
+
+ for (c = freelist; c; c = c1) {
+ c1 = c->next;
+ xfree(c);
+ }
+
+ InitializeIncludeCache();
+}
+
+void CacheIncludeFile(OSSpec *spec, Handle text, Boolean precompiled) {
+ UInt32 size;
+ CacheEntry *c;
+ CacheEntry *lru;
+
+ size = GetHandleSize(text);
+ if (precompiled) {
+ lru = NULL;
+ for (c = cachelist; c; c = c->next) {
+ if (c->precompiled) {
+ lru = c;
+ break;
+ }
+ }
+ if (lru) {
+ DisposeHandle(lru->text);
+ lru->text = NULL;
+ deletecacheentry(lru);
+ lru->next = freelist;
+ freelist = lru;
+ }
+ } else {
+ if ((SInt32) size > (SInt32) CACHE_SIZE) {
+ return;
+ } else {
+ while (size > availablecache) {
+ lru = NULL;
+ for (c = cachelist; c; c = c->next) {
+ if (!c->locked && !c->precompiled && (lru == NULL || c->when < lru->when))
+ lru = c;
+ }
+
+ if (lru) {
+ DisposeHandle(lru->text);
+ lru->text = NULL;
+ availablecache += lru->size;
+ deletecacheentry(lru);
+ lru->next = freelist;
+ freelist = lru;
+ } else {
+ return;
+ }
+ }
+ }
+ }
+
+ c = makecacheentry();
+ c->locked = 1;
+ c->precompiled = precompiled;
+ c->spec = *spec;
+ c->text = text;
+ c->size = size;
+ c->when = OS_GetMilliseconds();
+ insertcacheentry(c);
+
+ if (!precompiled)
+ availablecache -= size;
+}
+
+Handle CachedIncludeFile(OSSpec *spec, Boolean *precompiled) {
+ CacheEntry *c;
+
+ for (c = cachelist; c; c = c->next) {
+ if (OS_EqualSpec(&c->spec, spec)) {
+ c->when = OS_GetMilliseconds();
+ *precompiled = c->precompiled;
+ c->locked++;
+ return c->text;
+ }
+ }
+
+ return NULL;
+}
+
+void FreeIncludeFile(Handle text) {
+ CacheEntry *c;
+
+ for (c = cachelist; c; c = c->next) {
+ if (c->text == text) {
+ c->locked--;
+ return;
+ }
+ }
+
+ DisposeHandle(text);
+}