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 + -
显示快捷键?