From 37da2899f40661e3e9631e497da8dc59b971cbd0 Mon Sep 17 00:00:00 2001 From: "Charles.Forsyth" Date: Fri, 22 Dec 2006 17:07:39 +0000 Subject: 20060303a --- appl/svc/httpd/cache.b | 188 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 appl/svc/httpd/cache.b (limited to 'appl/svc/httpd/cache.b') diff --git a/appl/svc/httpd/cache.b b/appl/svc/httpd/cache.b new file mode 100644 index 00000000..3d4549e4 --- /dev/null +++ b/appl/svc/httpd/cache.b @@ -0,0 +1,188 @@ +implement Cache; + +include "sys.m"; + sys : Sys; + +include "bufio.m"; + bufio : Bufio; +Iobuf : import bufio; + +include "lock.m"; + locks: Lock; + Semaphore: import locks; + +dbg_log : ref Sys->FD; + +include "cache.m"; + +HASHSIZE : con 1019; + +lru ,cache_size : int; # lru link, and maximum size of cache. +cur_size, cur_tag : int; # current size of cache and current number. + +lock: ref Semaphore; + +Cache_link : adt{ + name : string; # name of file + contents : array of byte; # contents + length : int; # length of file + qid:Sys->Qid; + tag : int; +}; + +tab := array[HASHSIZE] of list of Cache_link; + +hashasu(key : string,n : int): int +{ + i, h : int; + h=0; + i=0; + while(iQid) : int +{ + tmp : Cache_link; + hash : int; + lock.obtain(); + hash = hashasu(name,HASHSIZE); + if (dbg_log!=nil){ + sys->fprint(dbg_log,"current size is %d, adding %s\n", cur_size,name); + } + while (cur_size+length > cache_size) + throw_out(); + tmp.name =name; + tmp.contents = ctents; + tmp.length = length; + tmp.qid = qid; + tmp.tag = cur_tag; + cur_size+=length; + cur_tag++; + if (cur_tag<0) cur_tag=0; + tab[hash]= tmp :: tab[hash]; + lock.release(); + return 1; +} + +find(name : string, qid:Sys->Qid) : (int, array of byte) +{ + hash,flag,stale : int; + nlist : list of Cache_link; + retval : array of byte; + flag=0; + nlist=nil; + retval=nil; + stale=0; + lock.obtain(); + hash = hashasu(name,HASHSIZE); + tmp:=tab[hash]; + for(;tmp!=nil;tmp = tl tmp){ + link:=hd tmp; + if (link.name==name){ + if(link.qid.path==qid.path && link.qid.vers==qid.vers){ + link.tag=cur_tag; + cur_tag++; + flag = 1; + retval = (hd tmp).contents; + } else { # cache is stale + lru--; if(lru<0) lru = 0; + link.tag = lru; + stale = 1; + } + } + nlist = link :: nlist; + } + tab[hash]=nlist; + if (flag && (dbg_log!=nil)) + sys->fprint(dbg_log,"Found %s in cache, cur_tag is %d\n",name,cur_tag); + if (stale){ + if (dbg_log!=nil) + sys->fprint(dbg_log,"Stale %s in cache\n",name); + throw_out(); + } + lock.release(); + return (flag,retval); +} + +throw_out() +{ + nlist : list of Cache_link; + for(i:=0;ifprint(dbg_log,"LRU not found!!!\n"); + # now, the lru is in tab[i]... + nlist=nil; + for(;tab[i]!=nil;tab[i]=tl tab[i]){ + if ((hd tab[i]).tag==lru){ + if (dbg_log!=nil) + sys->fprint(dbg_log,"Throwing out %s\n",(hd tab[i]).name); + cur_size-=(hd tab[i]).length; + tab[i] = tl tab[i]; + } + if (tab[i]!=nil) + nlist = (hd tab[i]) :: nlist; + if (tab[i]==nil) break; + } + lru=find_lru(); + if (dbg_log!=nil) + sys->fprint(dbg_log,"New lru is %d",lru); + tab[i] = nlist; +} + +find_lru() : int +{ + min := cur_tag; + for(i:=0;iFD, csize : int) +{ + n : int; + for(n=0;nPATH; + locks = load Lock Lock->PATH; + locks->init(); + lock = Semaphore.new(); + dbg_log = log; + if (dbg_log!=nil) + sys->fprint(dbg_log,"Cache initialised, max size is %d K\n",cache_size); +} + +dump() : list of (string,int,int) +{ + retval: list of (string,int,int); + lock.obtain(); + for(i:=0;i