aboutsummaryrefslogtreecommitdiffstats
path: root/cache.c
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-05-11 04:48:26 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-05-11 04:48:26 +0800
commitc884bf85b74b87db27359b4de22ccaf06a6ba933 (patch)
treef531bbee81452b26f79dded76e1dd66d5a01c58a /cache.c
downloaddevel-c884bf85b74b87db27359b4de22ccaf06a6ba933.tar.gz
devel-c884bf85b74b87db27359b4de22ccaf06a6ba933.tar.xz
devel-c884bf85b74b87db27359b4de22ccaf06a6ba933.zip
The first version of v0.1
Diffstat (limited to 'cache.c')
-rw-r--r--cache.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/cache.c b/cache.c
new file mode 100644
index 0000000..bfcdf29
--- /dev/null
+++ b/cache.c
@@ -0,0 +1,97 @@
+#include "cache.h"
+#include <stdio.h>
+#include <malloc.h>
+
+
+/*
+ * Each CachePtr contains:
+ * - Block pointer
+ * - LRU previous pointer
+ * - LRU next pointer
+ * - Block data buffer address
+ * The first entry is the head node of the list
+ */
+struct cache_struct cache[CACHE_ENTRIES + 1] = {0,};
+
+
+/**
+ * cache_init:
+ *
+ * Initialize the cache data structres.
+ *
+ */
+void cache_init(void)
+{
+ struct cache_struct *prev, *cur;
+ int i;
+
+ cur = cache;
+ prev = &cache[CACHE_ENTRIES];
+
+ for ( i = 0; i < CACHE_ENTRIES + 1; i++ ) {
+ cur->sector = 0;
+ cur->prev = prev;
+ prev->next = cur;
+ cur->data = NULL;
+
+ prev = cur;
+ cur = &cache[i+1];
+ }
+}
+
+
+
+
+/**
+ * get_cache_sector:
+ *
+ * Check for a particular SECTOR in the sector cache,
+ * and if it is already there, just do nothing and return;
+ * otherwise load it and updata the relative cache
+ * structre with data pointer.
+ *
+ * @param: sector, the sector number we want check.
+ * @retrun: return the most recent cache structure pointer
+ *
+ */
+struct cache_struct * get_cache_sector(int sector)
+{
+ struct cache_struct *cs = &cache[1];
+ struct cache_struct *head, *last;
+ int i;
+
+ for ( i = 0; i < CACHE_ENTRIES; i ++ ) {
+ if ( cs->sector == sector )
+ goto hit;
+ else
+ cs = &cache[i + 1];
+ }
+
+ /* we missed it here, so we need to load it */
+ miss:
+ /* free the first cache's buffer first */
+ if ( cache[0].next->data)
+ free(cache[0].next->data);
+ /* store it at head of real cache */
+ cs = cache[0].next;
+
+ cs->sector = sector;
+ cs->data = (void*)getonesec(sector);
+
+ hit:
+ /* remove cs from current position in list */
+ cs->prev->next = cs->next;
+ cs->next->prev = cs->prev;
+
+
+ /* add to just before head node */
+ last = cache[0].prev;
+ head = cache;
+
+ last->next = cs;
+ cs->prev = last;
+ head->prev = cs;
+ cs->next = head;
+
+ return cs;
+}