cachingprovider.java
来自「我想下载一个东西」· Java 代码 · 共 555 行 · 第 1/2 页
JAVA
555 行
/* JSPWiki - a JSP-based WikiWiki clone. Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package com.ecyrd.jspwiki.providers;import java.util.Properties;import java.util.Collection;import java.util.HashMap;import java.util.TreeSet;import java.util.Date;import java.util.ArrayList;import java.util.List;import java.util.Iterator;import java.io.IOException;import org.apache.log4j.Category;import com.ecyrd.jspwiki.*;import com.opensymphony.module.oscache.base.Cache;import com.opensymphony.module.oscache.base.NeedsRefreshException;/** * Heavily based on ideas by Chris Brooking. * * @author Janne Jalkanen * @since 1.6.4 */// FIXME: Keeps a list of all WikiPages in memory - should cache them too.public class CachingProvider implements WikiPageProvider{ private static final Category log = Category.getInstance(CachingProvider.class); private WikiPageProvider m_provider; private HashMap m_cache = new HashMap(); private Cache m_textCache; private long m_cacheMisses = 0; private long m_cacheHits = 0; private int m_milliSecondsBetweenChecks = 30000; /** * Defines, in seconds, the amount of time a text will live in the cache * at most before requiring a refresh. */ // FIXME: This can be long, since we check it on our own. private int m_refreshPeriod = 24*60*60; // Default is one day. public static final String PROP_CACHECHECKINTERVAL = "jspwiki.cachingProvider.cacheCheckInterval"; public static final String PROP_CACHECAPACITY = "jspwiki.cachingProvider.capacity"; private static final int DEFAULT_CACHECAPACITY = 200; // Good for a small wiki public void initialize( Properties properties ) throws NoRequiredPropertyException, IOException { log.debug("Initing CachingProvider"); m_milliSecondsBetweenChecks = TextUtil.parseIntParameter( properties.getProperty(PROP_CACHECHECKINTERVAL), m_milliSecondsBetweenChecks ); log.debug("Cache consistency checks every "+m_milliSecondsBetweenChecks+" ms"); // // Text cache capacity // int capacity = TextUtil.parseIntParameter( properties.getProperty(PROP_CACHECAPACITY), DEFAULT_CACHECAPACITY ); log.debug("Cache capacity "+capacity+" pages."); m_textCache = new Cache( true, false, "com.opensymphony.module.oscache.base.algorithm.LRUCache", capacity ); String classname = WikiEngine.getRequiredProperty( properties, PageManager.PROP_PAGEPROVIDER ); try { Class providerclass = WikiEngine.findWikiClass( classname, "com.ecyrd.jspwiki.providers" ); m_provider = (WikiPageProvider)providerclass.newInstance(); log.debug("Initializing real provider class "+m_provider); m_provider.initialize( properties ); } catch( ClassNotFoundException e ) { log.error("Unable to locate provider class "+classname,e); throw new IllegalArgumentException("no provider class"); } catch( InstantiationException e ) { log.error("Unable to create provider class "+classname,e); throw new IllegalArgumentException("faulty provider class"); } catch( IllegalAccessException e ) { log.error("Illegal access to provider class "+classname,e); throw new IllegalArgumentException("illegal provider class"); } } public boolean pageExists( String page ) { CacheItem item = (CacheItem)m_cache.get( page ); // // A null item means that the page either does not // exist, or has not yet been cached; a non-null // means that the page does exist. // if( item != null ) { return true; } // // If we have a list of all pages in memory, then any page // not in the cache must be non-existent. // // FIXME: There's a problem here; if someone modifies the // repository by adding a page outside JSPWiki, // we won't notice it. if( m_gotall ) { return false; } // // We could add the page to the cache here as well, // but in order to understand whether that is a // good thing or not we would need to analyze // the JSPWiki calling patterns extensively. Presumably // it would be a good thing if pageExists() is called // many times before the first getPageText() is called, // and the whole page is cached. // return m_provider.pageExists( page ); } public String getPageText( String page, int version ) throws ProviderException { String result; if( version == WikiPageProvider.LATEST_VERSION ) { result = getTextFromCache( page ); } else { CacheItem item = (CacheItem)m_cache.get( page ); // // Or is this the latest version fetched by version number? // if( item != null && item.m_page.getVersion() == version ) { result = getTextFromCache( page ); } else { result = m_provider.getPageText( page, version ); } } return result; } /** * Returns true, if the page has been changed outside of JSPWiki. */ private boolean checkIfPageChanged( CacheItem item ) { if( item == null ) return false; long currentTime = System.currentTimeMillis(); if( currentTime - item.m_lastChecked > m_milliSecondsBetweenChecks ) { try { WikiPage cached = item.m_page; WikiPage current = m_provider.getPageInfo( cached.getName(), LATEST_VERSION ); item.m_lastChecked = currentTime; long epsilon = 1000L; // FIXME: This should be adjusted according to provider granularity. Date currentModified = current.getLastModified(); Date cachedModified = cached.getLastModified(); if( currentModified != null && cachedModified != null && currentModified.getTime() - cachedModified.getTime() > epsilon ) { log.debug("Page "+current.getName()+" has been externally modified, refreshing contents."); return true; } } catch( ProviderException e ) { log.error("While checking cache, got error: ",e); } } return false; } /** * Removes the page from cache, and attempts to reload all information. */ private synchronized void revalidatePage( WikiPage page ) throws ProviderException { m_cache.remove( page.getName() ); m_textCache.flushEntry( page.getName() ); addPage( page.getName(), null ); // If fetch fails, we want info to go directly to user } /** * Attempts to fetch text from the cache. */ private String getTextFromCache( String page ) throws ProviderException { CacheItem item = (CacheItem)m_cache.get( page ); // // Check if page has been changed externally. If it has, then // we need to refresh all of the information. // if( checkIfPageChanged( item ) ) { revalidatePage( item.m_page ); item = (CacheItem) m_cache.get( page ); } if( item == null ) { // Page has never been seen. // log.debug("Page "+page+" never seen."); String text = m_provider.getPageText( page, WikiPageProvider.LATEST_VERSION ); addPage( page, text ); m_cacheMisses++; return text; } else { String text; try
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?