cachestore.java
来自「很棒的web服务器源代码」· Java 代码 · 共 1,263 行 · 第 1/3 页
JAVA
1,263 行
} /** * UnLoad a "loaded" generation. WARNING: not synchronized. * @param the loaded generation * @exception InvalidCacheException if the cache is corrupted */ protected void unloadGeneration(CacheGeneration cg) throws InvalidCacheException { try { Writer writer = new BufferedWriter(new FileWriter(cg.getGenerationFile())); getSerializer().writeGeneration(cg, writer); state.notifyGenerationUnloaded(cg); } catch (FileNotFoundException ex) { String msg = "Generation file does not exists: "+ cg.getGenerationFile().getAbsolutePath(); throw new InvalidCacheException(msg); } catch (IOException ex) { String msg = "IOError writing on "+ cg.getGenerationFile().getAbsolutePath(); throw new InvalidCacheException(msg); } } /** * Save a generation. * @param the generation to be saved * @exception InvalidCacheException if the cache is corrupted */ protected void saveGeneration(CacheGeneration cg) throws InvalidCacheException { if (cg.isLoaded() && (! cg.isSaved())) { try { Writer writer = new BufferedWriter(new FileWriter(cg.getGenerationFile())); getSerializer().writeGeneration(cg, writer); cg.setSaved(true); } catch (FileNotFoundException ex) { String msg = "Generation file does not exists: "+ cg.getGenerationFile().getAbsolutePath(); throw new InvalidCacheException(msg); } catch (IOException ex) { String msg = "IOError writing on "+ cg.getGenerationFile().getAbsolutePath(); throw new InvalidCacheException(msg); } } } /** * Compute the generation identifier from filename. Filenames * looks like gen-001 * @param file the generation file * @return the generation number */ private int getGenerationId(File file) { String name = file.getName(); int idx = name.indexOf('-') + 1; String num = name.substring(idx); try { return Integer.parseInt(num); } catch (NumberFormatException ex) { return -1; } } /** * Load the generations. Only a subset of the generations will * actually be loaded, some generations will only have a description * (URLs, size) in memory. * This method load some generations (until cr_limit is reached) and the * remaining generations (if any) will only be a set of * CachedResourceDescription. */ protected synchronized void loadGenerations() throws InvalidCacheException { generations = new SyncLRUList(); File genfiles[] = getGenerationFiles(); if (genfiles == null) { throw new InvalidCacheException("No generation files!"); } int len = genfiles.length; Vector sorted = new Vector(len); //sort generation files for (int i = 0 ; i < len ; i++) { Sorter.orderedFileInsert(genfiles[i], sorted); } sorted.copyInto(genfiles); //load generations for (int i = 0 ; i < len ; i++) { int id = -1; try { File genfile = genfiles[i]; id = getGenerationId(genfile); if (id != -1) { //valid generation filename CacheGeneration gen = new CacheGeneration(this, generationlimit); Reader reader = new BufferedReader(new FileReader(genfile)); if (state.getCrCount() < cr_limit) { getSerializer().readGeneration(gen, reader); } else { getSerializer().readDescription(gen, reader); } gen.setId(id); gen.setGenerationFile(genfile); generations.toHead(gen); } else if (debug) { System.err.println("Invalid generation filename : "+ genfiles[i].getName()); } } catch (FileNotFoundException ex) { if (debug) { String msg = "File not found generation["+id+"]"; System.err.println(msg+" "+ex.getMessage()); } } catch (IOException ioex) { if (debug) { String msg = "Error loading generation ["+id+"]"; System.err.println(msg+" "+ioex.getMessage()); } } } } /** * Load the store state */ protected void loadState() { try { Reader reader = new BufferedReader(new FileReader(statefile)); state = (StoreState) getSerializer().read(reader); } catch (IOException ex) { if (debug) { System.err.println("Can't load StoreState : "+ex.getMessage()); } state = new StoreState(); } } /** * Save the current state */ protected void saveState() { state.sync(); try { Writer writer = new BufferedWriter(new FileWriter(statefile)); getSerializer().write(state, writer); } catch (IOException ex) { if (debug) { System.err.println("Can't load StoreState : "+ex.getMessage()); } } } /** * get the number of bytes the garbage collector needs to collect * to keep the cache in good state, it will only move the resource * to the delete list, another check has to be done to save physical space * @return a long, the number of bytes to save */ public long getRequiredByteNumber() { return (long)(state.getByteCount() - (bytelimit * gc_kept_ratio)); } /** * get the cached size of this cache * @return a long, the number of bytes cached */ public synchronized long getCachedByteCount() { return state.getByteCount(); } /** * get the number of bytes used phisycally by this cache * @return a long, the number of bytes cached */ public synchronized long getStoredByteCount() { return state.getStoreCount(); } /** * get the number of bytes available for the cache memory * @return a long, the number of bytes free */ public synchronized long getCachedByteFree() { return (bytelimit - state.getByteCount()); } /** * synchronize the internal database with the storage */ public synchronized void sync() { CacheGeneration cg = (CacheGeneration) generations.getHead(); if (cg == null) { // nothing to save return; } do { try { saveGeneration(cg); } catch (InvalidCacheException ex) { if (debug) { System.err.println("Unable to save generation ["+ cg.getId()+"] "+ex.getMessage()); } } cg = getNextGeneration(cg); } while (cg != null); saveState(); } /** * Remove the given CachedResource from the given CacheGeneration. * WARNING: not synchronized * @exception NoSuchResourceException if this resource was not in this * generation */ protected void removeResource(CacheGeneration cg, CachedResource cr) throws NoSuchResourceException { cg.removeResource(cr); state.notifyResourceRemoved(cr); } /** * Get a cached resource relative to the given URL. WARNING: the * CachedResource returned is no more in the CacheStore. * @param url the URL of the CachedResource * @return a CachedResource or null * @see #storeCachedResource * @exception InvalidCacheException if the cache is corrupted */ public CachedResource getCachedResource(String url) throws InvalidCacheException { CacheGeneration cg = (CacheGeneration)generations.getHead(); if (cg == null) return null; do { CachedResource cr = null; if (cg.isLoaded()) { // The generation is already loaded cr = cg.lookupResource(url); } else if (cg.containsResource(url)) { // load this generation and unload the LRU loaded // generation if necessary loadGeneration(cg); cr = cg.lookupResource(url); } // found something? if (cr != null) { try { synchronized(this) { removeResource(cg, cr); } } catch (NoSuchResourceException ex) { //should not happen } return cr; } // try with next generation cg = getNextGeneration(cg); } while (cg != null); return null; } /** * extract a cached resource from the store * @param the cached resource to be extracted * @return the extracted cached resource * @exception InvalidCacheException if the cache is corrupted */ public CachedResource getCachedResource(CachedResource cr) throws InvalidCacheException { CacheGeneration cg = cr.generation; if (cg != null) { try { synchronized(this) { removeResource(cg, cr); } } catch (NoSuchResourceException ex) { //should not happen } return cr; } // FIXME do the lookup, but we shouldn't end up here anyway return cr; } /** * Resize the generation in order to be able to store the given * Resource. * @param cg the generation to resize * @param cr the CachedResource to store. */ protected synchronized void resizeGeneration(CacheGeneration cg, CachedResource cr) { if (debug) { System.out.println("Resizing generation "+cg.getId()); } long real_size = Math.max(cr.getContentLength(), cr.getCurrentLength()); if (real_size > generationlimit) { cg.setByteLimit(real_size); generationlimit = (bytelimit - real_size) / (max_generation - 1); } else if (debug) { System.out.println("Asked for a not necessary resize!"); } } /** * Get a cached resource relative to the given URL. WARNING: the * CachedResource returned is still in the cache store! * @param url the URL of the CachedResource * @return a CachedResource or null * @see #storeCachedResource * @exception InvalidCacheException if the cache is corrupted */ public CachedResource getCachedResourceReference(String url) throws InvalidCacheException { CacheGeneration cg = (CacheGeneration)generations.getHead(); if (cg == null) return null; do { CachedResource cr = null; if (cg.isLoaded()) { // The generation is already loaded cr = cg.lookupResource(url); } else if (cg.containsResource(url)) { // load this generation and unload the LRU loaded // generation if necessary loadGeneration(cg); cr = cg.lookupResource(url); } // found something? if (cr != null) { return cr; } // try with next generation cg = getNextGeneration(cg); } while (cg != null); return null; } /** * update this cached resource from generation x ot the latest * @param the cached resource to be updated * @return the updated * @exception InvalidCacheException if the cache is corrupted */ public CachedResource updateResourceGeneration(CachedResource cr) throws InvalidCacheException { CacheGeneration cg = (CacheGeneration)generations.getHead(); if (cg != cr.generation) { try { synchronized(this) { removeResource(cr.generation, cr); } } catch (NoSuchResourceException ex) { //should not happen } storeCachedResource(cr, cr.getCurrentLength()); } return cr; } /** * Store a newly created (or updated) CachedResource. * @param cr the CachedResource to store * @exception InvalidCacheException if the cache is corrupted * @return <code>true</code> if the resource has been cached */ public boolean storeCachedResource(CachedResource cr) throws InvalidCacheException { return storeCachedResource(cr, 0); } /** * Store a newly created (or updated) CachedResource. * @param cr the CachedResource to store * @return <code>true</code> if the resource has been cached * @exception InvalidCacheException if the cache is corrupted */ public boolean storeCachedResource(CachedResource cr, long oldsize) throws InvalidCacheException { CacheGeneration cg = (CacheGeneration)generations.getHead(); long size = cr.getCurrentLength(); long maxsize = (long)(((double) bytelimit) * threshold); // size > threshold, can't cache it... if (size > maxsize) { return false; } if (cg != null) { // firt try to add in last generation if (cg.addResource(cr, size, oldsize)) { // success return true; } // create a new generation CacheGeneration new_cg = addNewGeneration(); if (new_cg != null) { // generation created if (! new_cg.addResource(cr, size, oldsize)) { // resize generation resizeGeneration(new_cg, cr); // try again if (! new_cg.addResource(cr, size, oldsize)) { String msg = "Unable to add a cachedResource in a "+
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?