Main Page | Class Hierarchy | Class List | File List | Class Members

CacheManager.cs

00001 using System;
00002 using System.Text;
00003 using System.Collections;
00004 using System.Collections.Specialized;
00005 
00006 namespace Common
00007 {
00011         public class CacheManager {
00012                 protected Cache cache; // the underlying cache
00013                 protected long cacheSize; // size of the underlying cache;
00014                 public URIMapper uriMapper; // contains all of the URI <-> CHK mappings, along with the response headers to issue.
00015                 protected Object SyncRoot; // synchronisation root
00016 
00018 
00019 
00020 
00021 
00022                 public CacheManager(long cacheSize) {
00023                         this.cacheSize = cacheSize;
00024                         cache = new Cache(cacheSize, this);
00025                         uriMapper = new URIMapper();
00026                         SyncRoot = new Object();
00027                 }
00028 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038                 public bool CanService(HTTPRequest request) {
00039                         return (uriMapper.Contains(request.URI));
00040                 }
00041 
00048                 public HTTPResponse Get(HTTPRequest request) {
00049                         lock (SyncRoot) {
00050                                 // we're assuming here that the we do have a URI entry here.
00051                                 HTTPResponse result = null;
00052                                 HTTPBody resultBody = null;
00053                                 lock (uriMapper.SyncRoot) {
00054                                         URIMappingEntry mappingEntry = (URIMappingEntry)uriMapper[request.URI];
00055                                         // only get the body if there is one.
00056                                         if (mappingEntry.CHK != null) {
00057                                                 resultBody = cache.Get(mappingEntry.CHK);
00058                                         } 
00059                                         HTTPResponseHeader resultHeader = new HTTPResponseHeader(mappingEntry.Headers);
00060                                         result = new HTTPResponse(resultHeader);
00061                                         if (resultBody != null) {
00062                                                 result.AppendBody(resultBody);
00063                                         }
00064                                         // update URI <-> CHK mapper LRU information (Do this outside this method if you have to)
00065                                         //mappingEntry.Freshen();
00066                                 }
00067                                 return result;
00068                         }
00069                 }
00070 
00078                 public void UpdateURIMapping(Uri URI, byte[] chk, string headers) {
00079                         if (uriMapper.Contains(URI)) {
00080                                 ((URIMappingEntry)uriMapper[URI]).Freshen(chk, headers);
00081                         } else {
00082                                 uriMapper.Add(URI, new URIMappingEntry(URI, chk, headers));
00083                         }
00084                 }
00085 
00091                 public bool CacheContains(byte[] chk) {
00092                         return cache.Contains(chk);
00093                 }
00094 
00100                 public void UpdateCache(HTTPResponse response, Uri requestURI) {
00101                         if (response != null) {
00102                                 lock (SyncRoot) {
00103                                         lock(uriMapper.SyncRoot) {
00104                                                 // step 1: Add data to the cache. Put will noop if already there.
00105                                                 byte[] responseChk = cache.Put(response.Body);
00106                                                 UpdateURIMapping(requestURI, responseChk, response.Headers);
00107                                         }
00108                                 }
00109                         }
00110                 }
00111 
00118                 public HTTPBody GetByChk(byte[] chk) {
00119                         return cache.Get(chk);
00120                 }
00121                 public static byte[] Patch(byte[] originalDocument, ArrayList changeHunks) {
00122                         /*      if (no more hunks) {
00123                          *              append remainder of source to destination
00124                          *      } else { // hunks remaining
00125                          *      identify 1st line in hunk (alpha 1, 2nd in range is alpha2)
00126                          *              copy everything from src up to (not including) src[alpha1] in hunk, to destination
00127                          *              switch (hunk.Type) {
00128                          *                      add: {
00129                          *                      copy line alpha1 from src
00130                          *                      append to destination the complete lines content of current hunk
00131                          *                      advance to line alpha1 + 1
00132                          *                      break;
00133                          *                      }
00134                          *                      change: {
00135                          *                      append to destination the entire line contents of current hunk
00136                          *                      advance to alpha2 + 1
00137                          *                      break;
00138                          *                      }
00139                          *                      delete: {
00140                          *                      advance to alpha2 + 1
00141                          *                      }
00142                          *              }
00143                          *      }
00144                          * */
00145                         Console.WriteLine("- Beginning Patch process");
00146                         string original = Encoding.ASCII.GetString(originalDocument);
00147                         StringCollection source = new StringCollection();
00148                         StringCollection target = new StringCollection();
00149                         StringBuilder result = new StringBuilder();
00150                         int currentSrcLine = 0;
00151                         IEnumerator hunkEnum = changeHunks.GetEnumerator();
00152 
00153                         source.AddRange(original.Split(new char[] {'\n'}));
00154                         
00155                         while(currentSrcLine < source.Count) {
00156                                 if (!hunkEnum.MoveNext()) { // advances to next hunk. False if no more hunks
00157                                         while (currentSrcLine < source.Count) {
00158                                                 target.Add(source[currentSrcLine] + '\n');
00159                                                 currentSrcLine++;
00160                                         }
00161                                 } else { // there are more hunks to process
00162                                         JLibDiff.Hunk currentHunk = (JLibDiff.Hunk)hunkEnum.Current;
00163                                         int firstLineSrc = currentHunk.lowLine(0) - 1;
00164                                         // advance until hunk begins to influence
00165                                         while (currentSrcLine < firstLineSrc) {
00166                                                 target.Add(source[currentSrcLine] + '\n');
00167                                                 currentSrcLine++;
00168                                         }
00169                                         switch(currentHunk.GetType().Name) {
00170                                                 case "HunkAdd" : {
00171                                                         if (currentHunk.lowLine(0) != 0) {
00172                                                                 target.Add(source[currentSrcLine]); // copy 1st line
00173                                                         }
00174                                                         for (int i = 0; i < currentHunk.numLines(1); i++) {
00175                                                                 target.Add(currentHunk.relNum(1, i));
00176                                                         }
00177                                                         currentSrcLine++;
00178                                                         break; 
00179                                                 }
00180                                                 case "HunkChange": { 
00181                                                         for (int i = 0; i < currentHunk.numLines(1); i++) {
00182                                                                 target.Add(currentHunk.relNum(1, i));
00183                                                         }
00184                                                         currentSrcLine = currentHunk.highLine(0); // +1 canceled by -1 for zero based counting
00185                                                         break; 
00186                                                 }
00187                                                 case "HunkDel" : { 
00188                                                         currentSrcLine = currentHunk.highLine(0); // +1 canceled by -1 for zero based counting
00189                                                         break; }
00190                                                 default: { throw new Exception("Unknown Hunk type"); }
00191                                         } // end switch
00192                                 } // end if then else
00193                         } // end while
00194                         
00195                         foreach (string s in target) {
00196                                 result.Append(s);
00197                         }
00198                         Console.WriteLine("- Patch Process Complete");
00199                         return Encoding.ASCII.GetBytes(result.ToString());
00200                 }
00201 
00202                 public static ArrayList Diff(System.IO.Stream oldDocStream, System.IO.Stream newDocStream) {
00203                         JLibDiff.diff myDiff = new JLibDiff.diff();
00204                         myDiff.diffBuffer(new System.IO.StreamReader(oldDocStream), new System.IO.StreamReader(newDocStream));
00205                         myDiff.print();
00206                         return myDiff.getHunk();
00207                 }
00208         }
00209 }

Generated on Mon May 8 22:07:27 2006 by  doxygen 1.3.9.1