Author: lektran Date: Tue Dec 23 05:04:35 2014 New Revision: 1647483 URL: http://svn.apache.org/r1647483 Log: OFBIZ-4098 Implement step 1 of the cache refactoring: 1. Reduce UtilCache down to a utility class containing only static methods 2. Move global cache management responsibilities to an OFBizCacheManager implementation 3. Move individual cache management responsibilities to an OFBizCache implementation 4. Change all UtilCache object references to OFBizCache references
Next step: extract interfaces from OFBizCacheManager and OFBizCache Added: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java (with props) ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java (with props) Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/.classpath ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/content/src/org/ofbiz/content/ContentManagementServices.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/order/src/org/ofbiz/order/order/OrderContentWrapper.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/party/src/org/ofbiz/party/content/PartyContentWrapper.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/config/ProductConfigWorker.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductContentWrapper.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductPromoContentWrapper.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/workeffort/src/org/ofbiz/workeffort/content/WorkEffortContentWrapper.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/config/ResourceLoader.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/metrics/MetricsFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/BshUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/GroovyUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/JNDIContextFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/OfbizBshBsfEngine.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/PatternFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/ScriptUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/UtilProperties.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/CacheListener.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/UtilCache.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/test/UtilCacheTests.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/collections/FlexibleMapAccessor.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/string/NodeELResolver.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/template/FreeMarkerWorker.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/template/XslTransform.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/common/src/org/ofbiz/common/CommonEvents.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/datafile/src/org/ofbiz/datafile/ModelDataFileReader.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entity/src/org/ofbiz/entity/cache/AbstractCache.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entity/src/org/ofbiz/entity/cache/AbstractEntityConditionCache.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entity/src/org/ofbiz/entity/cache/EntityCache.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entity/src/org/ofbiz/entity/model/ModelFieldTypeReader.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entity/src/org/ofbiz/entity/model/ModelGroupReader.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entity/src/org/ofbiz/entity/model/ModelReader.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/entityext/src/org/ofbiz/entityext/eca/EntityEcaUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/minilang/src/org/ofbiz/minilang/SimpleMapProcessor.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/minilang/src/org/ofbiz/minilang/SimpleMethod.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/security/src/org/ofbiz/security/SecurityFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/service/src/org/ofbiz/service/ServiceDispatcher.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/service/src/org/ofbiz/service/config/ServiceConfigUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/service/src/org/ofbiz/service/engine/BSFEngine.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/service/src/org/ofbiz/service/mail/ServiceMcaUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/webapp/src/org/ofbiz/webapp/WebAppUtil.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/webapp/src/org/ofbiz/webapp/control/ConfigXMLReader.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/webapp/src/org/ofbiz/webapp/event/BsfEventHandler.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/webapp/src/org/ofbiz/webapp/ftl/OfbizCacheStorage.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/webtools/src/org/ofbiz/webtools/UtilCacheEvents.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/webtools/src/org/ofbiz/webtools/artifactinfo/ArtifactInfoFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/cache/AbstractCache.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/cache/ScreenCache.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/form/FormFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/menu/MenuFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/screen/HtmlWidget.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/screen/ScreenFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/widget/src/org/ofbiz/widget/tree/TreeFactory.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/specialpurpose/pos/src/org/ofbiz/pos/config/ButtonEventConfig.java ofbiz/branches/OFBIZ-4098-make-cache-pluggable/specialpurpose/pos/src/org/ofbiz/pos/screen/PosDialog.java Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/.classpath URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/.classpath?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/.classpath (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/.classpath Tue Dec 23 05:04:35 2014 @@ -160,7 +160,6 @@ <classpathentry kind="src" path="applications/workeffort/src"/> <classpathentry kind="src" path="specialpurpose/appserver/src"/> <classpathentry excluding="org/ofbiz/base/config/CoberturaInstrumenter.java" kind="src" path="framework/base/src"/> - <classpathentry kind="src" path="framework/bi/src"/> <classpathentry kind="src" path="specialpurpose/birt/src"/> <classpathentry kind="src" path="framework/catalina/src"/> <classpathentry kind="src" path="framework/common/src"/> @@ -172,7 +171,6 @@ <classpathentry kind="src" path="framework/minilang/src"/> <classpathentry kind="src" path="framework/security/src"/> <classpathentry kind="src" path="framework/service/src"/> - <classpathentry kind="src" path="framework/sql/src"/> <classpathentry kind="src" path="framework/start/src"/> <classpathentry kind="src" path="framework/testtools/src"/> <classpathentry excluding="org/ofbiz/webapp/view/JasperReportsPdfViewHandler.java|org/ofbiz/webapp/view/JasperReportsXmlViewHandler.java|org/ofbiz/webapp/view/JasperReportsJXlsViewHandler.java|org/ofbiz/webapp/view/JasperReportsPoiXlsViewHandler.java" kind="src" path="framework/webapp/src"/> Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/content/src/org/ofbiz/content/ContentManagementServices.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/content/src/org/ofbiz/content/ContentManagementServices.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/content/src/org/ofbiz/content/ContentManagementServices.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/content/src/org/ofbiz/content/ContentManagementServices.java Tue Dec 23 05:04:35 2014 @@ -37,6 +37,7 @@ import org.ofbiz.base.util.UtilGenerics; import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilProperties; import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.content.content.ContentServices; import org.ofbiz.content.content.ContentWorker; @@ -1174,7 +1175,7 @@ public class ContentManagementServices { public static Map<String, Object> clearContentAssocViewCache(DispatchContext dctx, Map<String, ? extends Object> context) throws GenericServiceException{ Map<String, Object> results = FastMap.newInstance(); - UtilCache<?, ?> utilCache = UtilCache.findCache("entitycache.entity-list.default.ContentAssocViewFrom"); + OFBizCache<?, ?> utilCache = UtilCache.findCache("entitycache.entity-list.default.ContentAssocViewFrom"); if (utilCache != null) { utilCache.clear(); @@ -1191,7 +1192,7 @@ public class ContentManagementServices { public static Map<String, Object> clearContentAssocDataResourceViewCache(DispatchContext dctx, Map<String, ? extends Object> context) throws GenericServiceException{ Map<String, Object> results = FastMap.newInstance(); - UtilCache<?, ?> utilCache = UtilCache.findCache("entitycache.entity-list.default.ContentAssocViewDataResourceFrom"); + OFBizCache<?, ?> utilCache = UtilCache.findCache("entitycache.entity-list.default.ContentAssocViewDataResourceFrom"); if (utilCache != null) { utilCache.clear(); } Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/order/src/org/ofbiz/order/order/OrderContentWrapper.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/order/src/org/ofbiz/order/order/OrderContentWrapper.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/order/src/org/ofbiz/order/order/OrderContentWrapper.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/order/src/org/ofbiz/order/order/OrderContentWrapper.java Tue Dec 23 05:04:35 2014 @@ -32,6 +32,7 @@ import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.UtilHttp; import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.content.content.ContentWorker; import org.ofbiz.entity.Delegator; @@ -48,7 +49,7 @@ public class OrderContentWrapper { public static final String module = OrderContentWrapper.class.getName(); public static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, String> orderContentCache = UtilCache.createUtilCache("order.content", true); // use soft reference to free up memory if needed + private static final OFBizCache<String, String> orderContentCache = UtilCache.createUtilCache("order.content", true); // use soft reference to free up memory if needed public static OrderContentWrapper makeOrderContentWrapper(GenericValue order, HttpServletRequest request) { return new OrderContentWrapper(order, request); Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/party/src/org/ofbiz/party/content/PartyContentWrapper.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/party/src/org/ofbiz/party/content/PartyContentWrapper.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/party/src/org/ofbiz/party/content/PartyContentWrapper.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/party/src/org/ofbiz/party/content/PartyContentWrapper.java Tue Dec 23 05:04:35 2014 @@ -21,6 +21,7 @@ package org.ofbiz.party.content; import org.ofbiz.content.content.ContentWrapper; import org.ofbiz.content.content.ContentWorker; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.base.util.*; import org.ofbiz.entity.GenericValue; @@ -48,7 +49,7 @@ public class PartyContentWrapper impleme public static final String module = PartyContentWrapper.class.getName(); public static final String CACHE_KEY_SEPARATOR = "::"; - private static final UtilCache<String, String> partyContentCache = UtilCache.createUtilCache("party.content.rendered", true); + private static final OFBizCache<String, String> partyContentCache = UtilCache.createUtilCache("party.content.rendered", true); protected LocalDispatcher dispatcher; protected GenericValue party; Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/config/ProductConfigWorker.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/config/ProductConfigWorker.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/config/ProductConfigWorker.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/config/ProductConfigWorker.java Tue Dec 23 05:04:35 2014 @@ -44,6 +44,7 @@ import org.ofbiz.product.product.Product import org.ofbiz.product.store.ProductStoreWorker; import org.ofbiz.service.LocalDispatcher; import org.ofbiz.webapp.website.WebSiteWorker; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; /** @@ -55,7 +56,7 @@ public class ProductConfigWorker { public static final String resource = "ProductUiLabels"; public static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, ProductConfigWrapper> productConfigCache = UtilCache.createUtilCache("product.config", true); // use soft reference to free up memory if needed + private static final OFBizCache<String, ProductConfigWrapper> productConfigCache = UtilCache.createUtilCache("product.config", true); // use soft reference to free up memory if needed public static ProductConfigWrapper getProductConfigWrapper(String productId, String currencyUomId, HttpServletRequest request) { ProductConfigWrapper configWrapper = null; Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductContentWrapper.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductContentWrapper.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductContentWrapper.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductContentWrapper.java Tue Dec 23 05:04:35 2014 @@ -35,6 +35,7 @@ import org.ofbiz.base.util.StringUtil; import org.ofbiz.base.util.UtilHttp; import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.GeneralRuntimeException; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.content.content.ContentWorker; import org.ofbiz.content.content.ContentWrapper; @@ -54,7 +55,7 @@ public class ProductContentWrapper imple public static final String module = ProductContentWrapper.class.getName(); public static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, String> productContentCache = UtilCache.createUtilCache("product.content.rendered", true); + private static final OFBizCache<String, String> productContentCache = UtilCache.createUtilCache("product.content.rendered", true); public static ProductContentWrapper makeProductContentWrapper(GenericValue product, HttpServletRequest request) { return new ProductContentWrapper(product, request); Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductPromoContentWrapper.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductPromoContentWrapper.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductPromoContentWrapper.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/product/src/org/ofbiz/product/product/ProductPromoContentWrapper.java Tue Dec 23 05:04:35 2014 @@ -37,6 +37,7 @@ import org.ofbiz.base.util.StringUtil; import org.ofbiz.base.util.UtilHttp; import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.content.content.ContentWorker; import org.ofbiz.content.content.ContentWrapper; @@ -59,7 +60,7 @@ public class ProductPromoContentWrapper public static final String module = ProductPromoContentWrapper.class.getName(); public static final String SEPARATOR = "::"; // cache key separator - private static final UtilCache<String, String> productPromoContentCache = UtilCache.createUtilCache("product.promo.content.rendered", true); + private static final OFBizCache<String, String> productPromoContentCache = UtilCache.createUtilCache("product.promo.content.rendered", true); public static ProductPromoContentWrapper makeProductPromoContentWrapper(GenericValue productPromo, HttpServletRequest request) { return new ProductPromoContentWrapper(productPromo, request); Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/workeffort/src/org/ofbiz/workeffort/content/WorkEffortContentWrapper.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/workeffort/src/org/ofbiz/workeffort/content/WorkEffortContentWrapper.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/workeffort/src/org/ofbiz/workeffort/content/WorkEffortContentWrapper.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/applications/workeffort/src/org/ofbiz/workeffort/content/WorkEffortContentWrapper.java Tue Dec 23 05:04:35 2014 @@ -38,6 +38,7 @@ import org.ofbiz.base.util.GeneralExcept import org.ofbiz.base.util.UtilValidate; import org.ofbiz.base.util.GeneralRuntimeException; import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.service.LocalDispatcher; import javolution.util.FastMap; @@ -51,7 +52,7 @@ public class WorkEffortContentWrapper im public static final String module = WorkEffortContentWrapper.class.getName(); public static final String CACHE_KEY_SEPARATOR = "::"; - private static final UtilCache<String, String> workEffortContentCache = UtilCache.createUtilCache("workeffort.content.rendered", true); + private static final OFBizCache<String, String> workEffortContentCache = UtilCache.createUtilCache("workeffort.content.rendered", true); protected LocalDispatcher dispatcher; protected GenericValue workEffort; Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/config/ResourceLoader.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/config/ResourceLoader.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/config/ResourceLoader.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/config/ResourceLoader.java Tue Dec 23 05:04:35 2014 @@ -24,6 +24,7 @@ import java.net.URL; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilURL; import org.ofbiz.base.util.UtilXml; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -34,9 +35,9 @@ import org.w3c.dom.Element; public abstract class ResourceLoader { public static final String module = ResourceLoader.class.getName(); - private static final UtilCache<String, ResourceLoader> loaderCache = UtilCache.createUtilCache("resource.ResourceLoaders", 0, 0); + private static final OFBizCache<String, ResourceLoader> loaderCache = UtilCache.createUtilCache("resource.ResourceLoaders", 0, 0); // This cache is temporary - we will use it until the framework has been refactored to eliminate DOM tree caching, then it can be removed. - private static final UtilCache<String, Document> domCache = UtilCache.createUtilCache("resource.DomTrees", 0, 0); + private static final OFBizCache<String, Document> domCache = UtilCache.createUtilCache("resource.DomTrees", 0, 0); public static InputStream loadResource(String xmlFilename, String location, String loaderName) throws GenericConfigException { ResourceLoader loader = getLoader(xmlFilename, loaderName); Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/metrics/MetricsFactory.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/metrics/MetricsFactory.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/metrics/MetricsFactory.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/metrics/MetricsFactory.java Tue Dec 23 05:04:35 2014 @@ -35,6 +35,7 @@ import org.ofbiz.base.lang.LockedBy; import org.ofbiz.base.lang.ThreadSafe; import org.ofbiz.base.util.Assert; import org.ofbiz.base.util.UtilProperties; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.w3c.dom.Element; @@ -43,7 +44,7 @@ import org.w3c.dom.Element; */ @ThreadSafe public final class MetricsFactory { - private static final UtilCache<String, Metrics> METRICS_CACHE = UtilCache.createUtilCache("base.metrics", 0, 0); + private static final OFBizCache<String, Metrics> METRICS_CACHE = UtilCache.createUtilCache("base.metrics", 0, 0); /** * A "do-nothing" <code>Metrics</code> instance. */ Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/BshUtil.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/BshUtil.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/BshUtil.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/BshUtil.java Tue Dec 23 05:04:35 2014 @@ -28,6 +28,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import bsh.BshClassManager; @@ -45,7 +46,7 @@ public final class BshUtil { public static final String module = BshUtil.class.getName(); protected static ConcurrentHashMap<ClassLoader, BshClassManager> masterClassManagers = new ConcurrentHashMap<ClassLoader, BshClassManager>(); - private static final UtilCache<String, Interpreter.ParsedScript> parsedScripts = UtilCache.createUtilCache("script.BshLocationParsedCache", 0, 0, false); + private static final OFBizCache<String, Interpreter.ParsedScript> parsedScripts = UtilCache.createUtilCache("script.BshLocationParsedCache", 0, 0, false); /** * Evaluate a BSH condition or expression Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/GroovyUtil.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/GroovyUtil.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/GroovyUtil.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/GroovyUtil.java Tue Dec 23 05:04:35 2014 @@ -35,6 +35,7 @@ import org.codehaus.groovy.control.Compi import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.runtime.InvokerHelper; import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; /** @@ -45,7 +46,7 @@ public class GroovyUtil { public static final String module = GroovyUtil.class.getName(); - private static final UtilCache<String, Class<?>> parsedScripts = UtilCache.createUtilCache("script.GroovyLocationParsedCache", 0, 0, false); + private static final OFBizCache<String, Class<?>> parsedScripts = UtilCache.createUtilCache("script.GroovyLocationParsedCache", 0, 0, false); private static final GroovyClassLoader groovyScriptClassLoader; static { Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/JNDIContextFactory.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/JNDIContextFactory.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/JNDIContextFactory.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/JNDIContextFactory.java Tue Dec 23 05:04:35 2014 @@ -25,6 +25,7 @@ import javax.naming.InitialContext; import org.ofbiz.base.config.GenericConfigException; import org.ofbiz.base.config.JNDIConfigUtil; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; /** @@ -34,7 +35,7 @@ import org.ofbiz.base.util.cache.UtilCac public class JNDIContextFactory { public static final String module = JNDIContextFactory.class.getName(); - private static final UtilCache<String, InitialContext> contexts = UtilCache.createUtilCache("entity.JNDIContexts", 0, 0); + private static final OFBizCache<String, InitialContext> contexts = UtilCache.createUtilCache("entity.JNDIContexts", 0, 0); /** * Return the initial context according to the entityengine.xml parameters that correspond to the given prefix Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/OfbizBshBsfEngine.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/OfbizBshBsfEngine.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/OfbizBshBsfEngine.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/OfbizBshBsfEngine.java Tue Dec 23 05:04:35 2014 @@ -41,6 +41,7 @@ import org.apache.bsf.BSFException; import org.apache.bsf.BSFManager; import org.apache.bsf.util.BSFEngineImpl; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; /** @@ -61,7 +62,7 @@ public class OfbizBshBsfEngine extends B protected Interpreter interpreter; protected boolean installedApplyMethod; - private static final UtilCache<String, Interpreter.ParsedScript> parsedScripts = UtilCache.createUtilCache("script.BshBsfParsedCache", 0, 0, false); + private static final OFBizCache<String, Interpreter.ParsedScript> parsedScripts = UtilCache.createUtilCache("script.BshBsfParsedCache", 0, 0, false); @SuppressWarnings("unchecked") @Override Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/PatternFactory.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/PatternFactory.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/PatternFactory.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/PatternFactory.java Tue Dec 23 05:04:35 2014 @@ -21,6 +21,7 @@ package org.ofbiz.base.util; import org.apache.oro.text.regex.MalformedPatternException; import org.apache.oro.text.regex.Pattern; import org.apache.oro.text.regex.Perl5Compiler; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; /** @@ -30,7 +31,7 @@ import org.ofbiz.base.util.cache.UtilCac public class PatternFactory { public static final String module = PatternFactory.class.getName(); - private static final UtilCache<String, Pattern> compiledPerl5Patterns = UtilCache.createUtilCache("regularExpression.compiledPerl5Patterns", false); + private static final OFBizCache<String, Pattern> compiledPerl5Patterns = UtilCache.createUtilCache("regularExpression.compiledPerl5Patterns", false); /** * Compiles and caches a Perl5 regexp pattern for the given string pattern. Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/ScriptUtil.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/ScriptUtil.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/ScriptUtil.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/ScriptUtil.java Tue Dec 23 05:04:35 2014 @@ -48,6 +48,7 @@ import javax.script.SimpleScriptContext; import org.codehaus.groovy.runtime.InvokerHelper; import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; /** @@ -69,7 +70,7 @@ public final class ScriptUtil { public static final String RESULT_KEY = "result"; /** The <code>ScriptHelper</code> key. */ public static final String SCRIPT_HELPER_KEY = "ofbiz"; - private static final UtilCache<String, CompiledScript> parsedScripts = UtilCache.createUtilCache("script.ParsedScripts", 0, 0, false); + private static final OFBizCache<String, CompiledScript> parsedScripts = UtilCache.createUtilCache("script.ParsedScripts", 0, 0, false); private static final Object[] EMPTY_ARGS = {}; private static ScriptHelperFactory helperFactory = null; /** A set of script names - derived from the JSR-223 scripting engines. */ Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/UtilProperties.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/UtilProperties.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/UtilProperties.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/UtilProperties.java Tue Dec 23 05:04:35 2014 @@ -45,6 +45,7 @@ import java.util.ResourceBundle; import java.util.Set; import org.ofbiz.base.location.FlexibleLocation; +import org.ofbiz.base.util.cache.OFBizCache; import org.ofbiz.base.util.cache.UtilCache; import org.ofbiz.base.util.collections.ResourceBundleMapWrapper; import org.ofbiz.base.util.string.FlexibleStringExpander; @@ -70,12 +71,12 @@ public class UtilProperties implements S /** An instance of the generic cache for storing the non-locale-specific properties. * Each Properties instance is keyed by the resource String. */ - private static final UtilCache<String, Properties> resourceCache = UtilCache.createUtilCache("properties.UtilPropertiesResourceCache"); + private static final OFBizCache<String, Properties> resourceCache = UtilCache.createUtilCache("properties.UtilPropertiesResourceCache"); /** An instance of the generic cache for storing the non-locale-specific properties. * Each Properties instance is keyed by the file's URL. */ - private static final UtilCache<String, Properties> urlCache = UtilCache.createUtilCache("properties.UtilPropertiesUrlCache"); + private static final OFBizCache<String, Properties> urlCache = UtilCache.createUtilCache("properties.UtilPropertiesUrlCache"); protected static Locale fallbackLocale = null; protected static Set<Locale> defaultCandidateLocales = null; @@ -1012,7 +1013,7 @@ public class UtilProperties implements S * properties file format. */ public static class UtilResourceBundle extends ResourceBundle { - private static final UtilCache<String, UtilResourceBundle> bundleCache = UtilCache.createUtilCache("properties.UtilPropertiesBundleCache"); + private static final OFBizCache<String, UtilResourceBundle> bundleCache = UtilCache.createUtilCache("properties.UtilPropertiesBundleCache"); protected Properties properties = null; protected Locale locale = null; protected int hashCode = hashCode(); Modified: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/CacheListener.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/CacheListener.java?rev=1647483&r1=1647482&r2=1647483&view=diff ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/CacheListener.java (original) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/CacheListener.java Tue Dec 23 05:04:35 2014 @@ -20,9 +20,9 @@ package org.ofbiz.base.util.cache; public interface CacheListener<K, V> { - public void noteKeyRemoval(UtilCache<K, V> cache, K key, V oldValue); + public void noteKeyRemoval(OFBizCache<K, V> cache, K key, V oldValue); - public void noteKeyAddition(UtilCache<K, V> cache, K key, V newValue); + public void noteKeyAddition(OFBizCache<K, V> cache, K key, V newValue); - public void noteKeyUpdate(UtilCache<K, V> cache, K key, V newValue, V oldValue); + public void noteKeyUpdate(OFBizCache<K, V> cache, K key, V newValue, V oldValue); } Added: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java?rev=1647483&view=auto ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java (added) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java Tue Dec 23 05:04:35 2014 @@ -0,0 +1,931 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.cache; + +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import jdbm.helper.FastIterator; +import jdbm.htree.HTree; + +import org.ofbiz.base.concurrent.ExecutionPool; +import org.ofbiz.base.util.Debug; +import org.ofbiz.base.util.ObjectType; +import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.base.util.UtilObject; +import org.ofbiz.base.util.UtilValidate; +import org.ofbiz.base.util.cache.CacheListener; + +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; +import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap.Builder; +import com.googlecode.concurrentlinkedhashmap.EvictionListener; + +/** + * Generalized caching utility. Provides a number of caching features: + * <ul> + * <li>Limited or unlimited element capacity + * <li>If limited, removes elements with the LRU (Least Recently Used) algorithm + * <li>Keeps track of when each element was loaded into the cache + * <li>Using the expireTime can report whether a given element has expired + * <li>Counts misses and hits + * </ul> + * + */ +@SuppressWarnings("serial") +public class OFBizCache<K, V> implements Serializable, EvictionListener<Object, CacheLine<V>> { + + public static final String module = OFBizCache.class.getName(); + + /** The name of the UtilCache instance, is also the key for the instance in utilCacheTable. */ + private final String name; + + /** A count of the number of cache hits */ + protected AtomicLong hitCount = new AtomicLong(0); + + /** A count of the number of cache misses because it is not found in the cache */ + protected AtomicLong missCountNotFound = new AtomicLong(0); + /** A count of the number of cache misses because it expired */ + protected AtomicLong missCountExpired = new AtomicLong(0); + /** A count of the number of cache misses because it was cleared from the Soft Reference (ie garbage collection, etc) */ + protected AtomicLong missCountSoftRef = new AtomicLong(0); + + /** A count of the number of cache hits on removes */ + protected AtomicLong removeHitCount = new AtomicLong(0); + /** A count of the number of cache misses on removes */ + protected AtomicLong removeMissCount = new AtomicLong(0); + + /** The maximum number of elements in the cache. + * If set to 0, there will be no limit on the number of elements in the cache. + */ + protected int sizeLimit = 0; + protected int maxInMemory = 0; + + /** Specifies the amount of time since initial loading before an element will be reported as expired. + * If set to 0, elements will never expire. + */ + protected long expireTimeNanos = 0; + + /** Specifies whether or not to use soft references for this cache, defaults to false */ + protected boolean useSoftReference = false; + + /** Specifies whether or not to use file base stored for this cache, defaults to false */ + protected boolean useFileSystemStore = false; + private String fileStore = "runtime/data/ofbizcache"; + + /** The set of listeners to receive notifications when items are modified (either deliberately or because they were expired). */ + protected Set<CacheListener<K, V>> listeners = new CopyOnWriteArraySet<CacheListener<K, V>>(); + + protected transient HTree<Object, V> fileTable = null; + protected ConcurrentMap<Object, CacheLine<V>> memoryTable = null; + + protected JdbmRecordManager jdbmMgr; + + /** Constructor which specifies the cacheName as well as the sizeLimit, expireTime and useSoftReference. + * The passed sizeLimit, expireTime and useSoftReference will be overridden by values from cache.properties if found. + * @param sizeLimit The sizeLimit member is set to this value + * @param expireTime The expireTime member is set to this value + * @param cacheName The name of the cache. + * @param useSoftReference Specifies whether or not to use soft references for this cache. + */ + protected OFBizCache(OFBizCacheManager cacheManager, String cacheName, int sizeLimit, int maxInMemory, long expireTimeMillis, boolean useSoftReference, boolean useFileSystemStore, String propName, String... propNames) { + this.name = cacheName; + this.sizeLimit = sizeLimit; + this.maxInMemory = maxInMemory; + this.expireTimeNanos = TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS); + this.useSoftReference = useSoftReference; + this.useFileSystemStore = useFileSystemStore; + setPropertiesParams(propName); + if (propNames != null) { + setPropertiesParams(propNames); + } + long maxMemSize = this.maxInMemory; + if (maxMemSize == 0) maxMemSize = sizeLimit; + if (maxMemSize == 0) { + memoryTable = new ConcurrentHashMap<Object, CacheLine<V>>(); + } else { + // FIXME: Casting a long to an int isn't great + memoryTable = new Builder<Object, CacheLine<V>>() + .maximumWeightedCapacity((int) maxMemSize) + .listener(this) + .build(); + } + if (this.useFileSystemStore) { + jdbmMgr = cacheManager.getJdbmRecordManager(fileStore); + if (jdbmMgr != null) { + try { + this.fileTable = HTree.createInstance(jdbmMgr); + jdbmMgr.setNamedObject(cacheName, this.fileTable.getRecid()); + jdbmMgr.commit(); + } catch (IOException e) { + Debug.logError(e, module); + } + } + } + } + + public static String getPropertyParam(ResourceBundle res, String[] propNames, String parameter) { + try { + for (String propName : propNames) { + String key = propName.concat(".").concat(parameter); + if (res.containsKey(key)) { + try { + return res.getString(key); + } catch (MissingResourceException e) { + } + } + } + } catch (Exception e) { + Debug.logWarning(e, "Error getting " + parameter + " value from ResourceBundle for propNames: " + propNames, module); + } + return null; + } + + protected void setPropertiesParams(String cacheName) { + setPropertiesParams(new String[] {cacheName}); + } + + public void setPropertiesParams(String[] propNames) { + setPropertiesParams("cache", propNames); + } + + public void setPropertiesParams(String settingsResourceName, String[] propNames) { + ResourceBundle res = ResourceBundle.getBundle(settingsResourceName); + + if (res != null) { + String value = getPropertyParam(res, propNames, "maxSize"); + if (UtilValidate.isNotEmpty(value)) { + this.sizeLimit = Integer.parseInt(value); + } + value = getPropertyParam(res, propNames, "maxInMemory"); + if (UtilValidate.isNotEmpty(value)) { + this.maxInMemory = Integer.parseInt(value); + } + value = getPropertyParam(res, propNames, "expireTime"); + if (UtilValidate.isNotEmpty(value)) { + this.expireTimeNanos = TimeUnit.NANOSECONDS.convert(Long.parseLong(value), TimeUnit.MILLISECONDS); + } + value = getPropertyParam(res, propNames, "useSoftReference"); + if (value != null) { + useSoftReference = "true".equals(value); + } + value = getPropertyParam(res, propNames, "useFileSystemStore"); + if (value != null) { + useFileSystemStore = "true".equals(value); + } + value = getPropertyParam(res, new String[0], "cache.file.store"); + if (value != null) { + fileStore = value; + } + } + } + + private Object fromKey(Object key) { + return key == null ? ObjectType.NULL : key; + } + + @SuppressWarnings("unchecked") + private K toKey(Object key) { + return key == ObjectType.NULL ? null : (K) key; + } + + private void addAllFileTableKeys(Set<Object> keys) throws IOException { + FastIterator<Object> iter = fileTable.keys(); + Object key = null; + while ((key = iter.next()) != null) { + keys.add(key); + } + } + + public Object getCacheLineTable() { + throw new UnsupportedOperationException(); + } + + public boolean isEmpty() { + if (fileTable != null) { + try { + synchronized (this) { + return fileTable.keys().next() == null; + } + } catch (IOException e) { + Debug.logError(e, module); + return false; + } + } else { + return memoryTable.isEmpty(); + } + } + + /** Puts or loads the passed element into the cache + * @param key The key for the element, used to reference it in the hashtables and LRU linked list + * @param value The value of the element + */ + public V put(K key, V value) { + return putInternal(key, value, expireTimeNanos); + } + + public V putIfAbsent(K key, V value) { + return putIfAbsentInternal(key, value, expireTimeNanos); + } + + public V putIfAbsentAndGet(K key, V value) { + V cachedValue = putIfAbsent(key, value); + return (cachedValue != null? cachedValue: value); + } + + CacheLine<V> createSoftRefCacheLine(final Object key, V value, long loadTimeNanos, long expireTimeNanos) { + return tryRegister(loadTimeNanos, new SoftRefCacheLine<V>(value, loadTimeNanos, expireTimeNanos) { + @Override + CacheLine<V> changeLine(boolean useSoftReference, long expireTimeNanos) { + if (useSoftReference) { + if (differentExpireTime(expireTimeNanos)) { + return this; + } else { + return createSoftRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos); + } + } else { + return createHardRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos); + } + } + + @Override + void remove() { + removeInternal(key, this); + } + }); + } + + CacheLine<V> createHardRefCacheLine(final Object key, V value, long loadTimeNanos, long expireTimeNanos) { + return tryRegister(loadTimeNanos, new HardRefCacheLine<V>(value, loadTimeNanos, expireTimeNanos) { + @Override + CacheLine<V> changeLine(boolean useSoftReference, long expireTimeNanos) { + if (useSoftReference) { + return createSoftRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos); + } else { + if (differentExpireTime(expireTimeNanos)) { + return this; + } else { + return createHardRefCacheLine(key, getValue(), loadTimeNanos, expireTimeNanos); + } + } + } + + @Override + void remove() { + removeInternal(key, this); + } + }); + } + + private CacheLine<V> tryRegister(long loadTimeNanos, CacheLine<V> line) { + if (loadTimeNanos > 0) { + ExecutionPool.addPulse(line); + } + return line; + } + + private CacheLine<V> createCacheLine(K key, V value, long expireTimeNanos) { + long loadTimeNanos = expireTimeNanos > 0 ? System.nanoTime() : 0; + if (useSoftReference) { + return createSoftRefCacheLine(key, value, loadTimeNanos, expireTimeNanos); + } else { + return createHardRefCacheLine(key, value, loadTimeNanos, expireTimeNanos); + } + } + private V cancel(CacheLine<V> line) { + // FIXME: this is a race condition, the item could expire + // between the time it is replaced, and it is cancelled + V oldValue = line.getValue(); + ExecutionPool.removePulse(line); + line.cancel(); + return oldValue; + } + + /** Puts or loads the passed element into the cache + * @param key The key for the element, used to reference it in the hashtables and LRU linked list + * @param value The value of the element + * @param expireTimeMillis how long to keep this key in the cache + */ + public V put(K key, V value, long expireTimeMillis) { + return putInternal(key, value, TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS)); + } + + public V putIfAbsent(K key, V value, long expireTimeMillis) { + return putIfAbsentInternal(key, value, TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS)); + } + + V putInternal(K key, V value, long expireTimeNanos) { + Object nulledKey = fromKey(key); + CacheLine<V> oldCacheLine = memoryTable.put(nulledKey, createCacheLine(key, value, expireTimeNanos)); + V oldValue = oldCacheLine == null ? null : cancel(oldCacheLine); + if (fileTable != null) { + try { + synchronized (this) { + if (oldValue == null) oldValue = fileTable.get(nulledKey); + fileTable.put(nulledKey, value); + jdbmMgr.commit(); + } + } catch (IOException e) { + Debug.logError(e, module); + } + } + if (oldValue == null) { + noteAddition(key, value); + return null; + } else { + noteUpdate(key, value, oldValue); + return oldValue; + } + } + + V putIfAbsentInternal(K key, V value, long expireTimeNanos) { + Object nulledKey = fromKey(key); + V oldValue; + if (fileTable != null) { + try { + synchronized (this) { + oldValue = fileTable.get(nulledKey); + if (oldValue == null) { + memoryTable.put(nulledKey, createCacheLine(key, value, expireTimeNanos)); + fileTable.put(nulledKey, value); + jdbmMgr.commit(); + } + } + } catch (IOException e) { + Debug.logError(e, module); + oldValue = null; + } + } else { + CacheLine<V> newCacheLine = createCacheLine(key, value, expireTimeNanos); + CacheLine<V> oldCacheLine = memoryTable.putIfAbsent(nulledKey, newCacheLine); + if (oldCacheLine == null) { + oldValue = null; + } else { + oldValue = oldCacheLine.getValue(); + cancel(newCacheLine); + } + } + if (oldValue == null) { + noteAddition(key, value); + return null; + } else { + return oldValue; + } + } + + /** Gets an element from the cache according to the specified key. + * @param key The key for the element, used to reference it in the hashtables and LRU linked list + * @return The value of the element specified by the key + */ + public V get(Object key) { + boolean countGet = true; + Object nulledKey = fromKey(key); + CacheLine<V> line = memoryTable.get(nulledKey); + if (line == null) { + if (fileTable != null) { + V value; + try { + synchronized (this) { + value = fileTable.get(nulledKey); + } + } catch (IOException e) { + Debug.logError(e, module); + value = null; + } + if (value == null) { + missCountNotFound.incrementAndGet(); + return null; + } else { + hitCount.incrementAndGet(); + } + memoryTable.put(nulledKey, createCacheLine(UtilGenerics.<K>cast(key), value, expireTimeNanos)); + return value; + } else { + missCountNotFound.incrementAndGet(); + } + } else { + if (countGet) hitCount.incrementAndGet(); + } + return line != null ? line.getValue() : null; + } + + public Collection<V> values() { + if (fileTable != null) { + List<V> values = new LinkedList<V>(); + try { + synchronized (this) { + FastIterator<V> iter = fileTable.values(); + V value = iter.next(); + while (value != null) { + values.add(value); + value = iter.next(); + } + } + } catch (IOException e) { + Debug.logError(e, module); + } + return values; + } else { + List<V> valuesList = new LinkedList<V>(); + for (CacheLine<V> line: memoryTable.values()) { + valuesList.add(line.getValue()); + } + return valuesList; + } + } + + private long findSizeInBytes(Object o) { + try { + if (o == null) { + if (Debug.infoOn()) Debug.logInfo("Found null object in cache: " + getName(), module); + return 0; + } + if (o instanceof Serializable) { + return UtilObject.getByteCount(o); + } else { + if (Debug.infoOn()) Debug.logInfo("Unable to compute memory size for non serializable object; returning 0 byte size for object of " + o.getClass(), module); + return 0; + } + } catch (NotSerializableException e) { + // this happens when we try to get the byte count for an object which itself is + // serializable, but fails to be serialized, such as a map holding unserializable objects + if (Debug.warningOn()) { + Debug.logWarning("NotSerializableException while computing memory size; returning 0 byte size for object of " + e.getMessage(), module); + } + return 0; + } catch (Exception e) { + Debug.logWarning(e, "Unable to compute memory size for object of " + o.getClass(), module); + return 0; + } + } + + public long getSizeInBytes() { + long totalSize = 0; + if (fileTable != null) { + try { + synchronized (this) { + FastIterator<V> iter = fileTable.values(); + V value = iter.next(); + while (value != null) { + totalSize += findSizeInBytes(value); + value = iter.next(); + } + } + } catch (IOException e) { + Debug.logError(e, module); + return 0; + } + } else { + for (CacheLine<V> line: memoryTable.values()) { + totalSize += findSizeInBytes(line.getValue()); + } + } + return totalSize; + } + + /** Removes an element from the cache according to the specified key + * @param key The key for the element, used to reference it in the hashtables and LRU linked list + * @return The value of the removed element specified by the key + */ + public V remove(Object key) { + return this.removeInternal(key, true); + } + + /** This is used for internal remove calls because we only want to count external calls */ + @SuppressWarnings("unchecked") + protected synchronized V removeInternal(Object key, boolean countRemove) { + if (key == null) { + if (Debug.verboseOn()) Debug.logVerbose("In UtilCache tried to remove with null key, using NullObject" + this.name, module); + } + Object nulledKey = fromKey(key); + CacheLine<V> oldCacheLine; + V oldValue; + if (fileTable != null) { + try { + synchronized (this) { + try { + oldValue = fileTable.get(nulledKey); + } catch (IOException e) { + oldValue = null; + throw e; + } + fileTable.remove(nulledKey); + jdbmMgr.commit(); + } + } catch (IOException e) { + oldValue = null; + Debug.logError(e, module); + } + oldCacheLine = memoryTable.remove(nulledKey); + } else { + oldCacheLine = memoryTable.remove(nulledKey); + oldValue = oldCacheLine != null ? oldCacheLine.getValue() : null; + } + if (oldCacheLine != null) { + cancel(oldCacheLine); + } + if (oldValue != null) { + noteRemoval((K) key, oldValue); + if (countRemove) removeHitCount.incrementAndGet(); + return oldValue; + } else { + if (countRemove) removeMissCount.incrementAndGet(); + return null; + } + } + + protected synchronized void removeInternal(Object key, CacheLine<V> existingCacheLine) { + Object nulledKey = fromKey(key); + cancel(existingCacheLine); + if (!memoryTable.remove(nulledKey, existingCacheLine)) { + return; + } + if (fileTable != null) { + try { + synchronized (this) { + fileTable.remove(nulledKey); + jdbmMgr.commit(); + } + } catch (IOException e) { + Debug.logError(e, module); + } + } + noteRemoval(UtilGenerics.<K>cast(key), existingCacheLine.getValue()); + } + + /** Removes all elements from this cache */ + public synchronized void erase() { + if (fileTable != null) { + // FIXME: erase from memory too + synchronized (this) { + Set<Object> keys = new HashSet<Object>(); + try { + addAllFileTableKeys(keys); + } catch (IOException e) { + Debug.logError(e, module); + } + for (Object key: keys) { + try { + V value = fileTable.get(key); + noteRemoval(toKey(key), value); + removeHitCount.incrementAndGet(); + fileTable.remove(key); + jdbmMgr.commit(); + } catch (IOException e) { + Debug.logError(e, module); + } + } + } + memoryTable.clear(); + } else { + Iterator<Map.Entry<Object, CacheLine<V>>> it = memoryTable.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<Object, CacheLine<V>> entry = it.next(); + noteRemoval(toKey(entry.getKey()), entry.getValue().getValue()); + removeHitCount.incrementAndGet(); + it.remove(); + } + } + } + + public void clear() { + erase(); + clearCounters(); + } + + /** Getter for the name of the UtilCache instance. + * @return The name of the instance + */ + public String getName() { + return this.name; + } + + /** Returns the number of successful hits on the cache + * @return The number of successful cache hits + */ + public long getHitCount() { + return this.hitCount.get(); + } + + /** Returns the number of cache misses from entries that are not found in the cache + * @return The number of cache misses + */ + public long getMissCountNotFound() { + return this.missCountNotFound.get(); + } + + /** Returns the number of cache misses from entries that are expired + * @return The number of cache misses + */ + public long getMissCountExpired() { + return this.missCountExpired.get(); + } + + /** Returns the number of cache misses from entries that are have had the soft reference cleared out (by garbage collector and such) + * @return The number of cache misses + */ + public long getMissCountSoftRef() { + return this.missCountSoftRef.get(); + } + + /** Returns the number of cache misses caused by any reason + * @return The number of cache misses + */ + public long getMissCountTotal() { + return getMissCountSoftRef() + getMissCountNotFound() + getMissCountExpired(); + } + + public long getRemoveHitCount() { + return this.removeHitCount.get(); + } + + public long getRemoveMissCount() { + return this.removeMissCount.get(); + } + + /** Clears the hit and miss counters + */ + public void clearCounters() { + this.hitCount.set(0); + this.missCountNotFound.set(0); + this.missCountExpired.set(0); + this.missCountSoftRef.set(0); + this.removeHitCount.set(0); + this.removeMissCount.set(0); + } + + public void setMaxInMemory(int newInMemory) { + this.maxInMemory = newInMemory; + Map<Object, CacheLine<V>> oldmap = this.memoryTable; + + if (newInMemory > 0) { + if (this.memoryTable instanceof ConcurrentLinkedHashMap<?, ?>) { + ((ConcurrentLinkedHashMap<?, ?>) this.memoryTable).setCapacity(newInMemory); + return; + } else { + this.memoryTable =new Builder<Object, CacheLine<V>>() + .maximumWeightedCapacity(newInMemory) + .build(); + } + } else { + this.memoryTable = new ConcurrentHashMap<Object, CacheLine<V>>(); + } + + this.memoryTable.putAll(oldmap); + } + + public int getMaxInMemory() { + return maxInMemory; + } + + public void setSizeLimit(int newSizeLimit) { + this.sizeLimit = newSizeLimit; + } + + public int getSizeLimit() { + return sizeLimit; + } + + /** Sets the expire time for the cache elements. + * If 0, elements never expire. + * @param expireTimeMillis The expire time for the cache elements + */ + public void setExpireTime(long expireTimeMillis) { + // if expire time was <= 0 and is now greater, fill expire table now + if (expireTimeMillis > 0) { + this.expireTimeNanos = TimeUnit.NANOSECONDS.convert(expireTimeMillis, TimeUnit.MILLISECONDS); + for (Map.Entry<?, CacheLine<V>> entry: memoryTable.entrySet()) { + entry.setValue(entry.getValue().changeLine(useSoftReference, expireTimeNanos)); + } + } else { + this.expireTimeNanos = 0; + // if expire time was > 0 and is now <=, do nothing, just leave the load times in place, won't hurt anything... + } + } + + /** return the current expire time for the cache elements + * @return The expire time for the cache elements + */ + public long getExpireTime() { + return TimeUnit.MILLISECONDS.convert(expireTimeNanos, TimeUnit.NANOSECONDS); + } + + /** Set whether or not the cache lines should use a soft reference to the data */ + public void setUseSoftReference(boolean useSoftReference) { + if (this.useSoftReference != useSoftReference) { + this.useSoftReference = useSoftReference; + for (Map.Entry<?, CacheLine<V>> entry: memoryTable.entrySet()) { + entry.setValue(entry.getValue().changeLine(useSoftReference, expireTimeNanos)); + } + } + } + + /** Return whether or not the cache lines should use a soft reference to the data */ + public boolean getUseSoftReference() { + return this.useSoftReference; + } + + public boolean getUseFileSystemStore() { + return this.useFileSystemStore; + } + + /** Returns the number of elements currently in the cache + * @return The number of elements currently in the cache + */ + public long size() { + if (fileTable != null) { + int size = 0; + try { + synchronized (this) { + FastIterator<Object> iter = fileTable.keys(); + while (iter.next() != null) { + size++; + } + } + } catch (IOException e) { + Debug.logError(e, module); + } + return size; + } else { + return memoryTable.size(); + } + } + + /** Returns a boolean specifying whether or not an element with the specified key is in the cache. + * @param key The key for the element, used to reference it in the hashtables and LRU linked list + * @return True is the cache contains an element corresponding to the specified key, otherwise false + */ + public boolean containsKey(Object key) { + Object nulledKey = fromKey(key); + CacheLine<V> line = memoryTable.get(nulledKey); + if (line == null) { + if (fileTable != null) { + try { + synchronized (this) { + FastIterator<Object> iter = fileTable.keys(); + Object checkKey = null; + while ((checkKey = iter.next()) != null) { + if (nulledKey.equals(checkKey)) { + return true; + } + } + } + } catch (IOException e) { + Debug.logError(e, module); + } + } + return false; + } else { + return true; + } + } + + /** + * NOTE: this returns an unmodifiable copy of the keySet, so removing from here won't have an effect, + * and calling a remove while iterating through the set will not cause a concurrent modification exception. + * This behavior is necessary for now for the persisted cache feature. + */ + public Set<? extends K> getCacheLineKeys() { + // note that this must be a HashSet and not a FastSet in order to have a null value + Set<Object> keys; + + if (fileTable != null) { + keys = new HashSet<Object>(); + try { + synchronized (this) { + addAllFileTableKeys(keys); + } + } catch (IOException e) { + Debug.logError(e, module); + } + if (keys.remove(ObjectType.NULL)) { + keys.add(null); + } + } else { + if (memoryTable.containsKey(ObjectType.NULL)) { + keys = new HashSet<Object>(memoryTable.keySet()); + keys.remove(ObjectType.NULL); + keys.add(null); + } else { + keys = memoryTable.keySet(); + } + } + return Collections.unmodifiableSet(UtilGenerics.<Set<? extends K>>cast(keys)); + } + + public Collection<? extends CacheLine<V>> getCacheLineValues() { + throw new UnsupportedOperationException(); + } + + private Map<String, Object> createLineInfo(int keyNum, K key, CacheLine<V> line) { + Map<String, Object> lineInfo = new HashMap<String, Object>(); + lineInfo.put("elementKey", key); + + if (line.getLoadTimeNanos() > 0) { + lineInfo.put("expireTimeMillis", TimeUnit.MILLISECONDS.convert(line.getExpireTimeNanos() - System.nanoTime(), TimeUnit.NANOSECONDS)); + } + lineInfo.put("lineSize", findSizeInBytes(line.getValue())); + lineInfo.put("keyNum", keyNum); + return lineInfo; + } + + private Map<String, Object> createLineInfo(int keyNum, K key, V value) { + Map<String, Object> lineInfo = new HashMap<String, Object>(); + lineInfo.put("elementKey", key); + lineInfo.put("lineSize", findSizeInBytes(value)); + lineInfo.put("keyNum", keyNum); + return lineInfo; + } + + public Collection<? extends Map<String, Object>> getLineInfos() { + List<Map<String, Object>> lineInfos = new LinkedList<Map<String, Object>>(); + int keyIndex = 0; + for (K key: getCacheLineKeys()) { + Object nulledKey = fromKey(key); + if (fileTable != null) { + try { + synchronized (this) { + lineInfos.add(createLineInfo(keyIndex, key, fileTable.get(nulledKey))); + } + } catch (IOException e) { + Debug.logError(e, module); + } + } else { + CacheLine<V> line = memoryTable.get(nulledKey); + if (line != null) { + lineInfos.add(createLineInfo(keyIndex, key, line)); + } + } + keyIndex++; + } + return lineInfos; + } + + /** Send a key addition event to all registered listeners */ + protected void noteAddition(K key, V newValue) { + for (CacheListener<K, V> listener: listeners) { + listener.noteKeyAddition(this, key, newValue); + } + } + + /** Send a key removal event to all registered listeners */ + protected void noteRemoval(K key, V oldValue) { + for (CacheListener<K, V> listener: listeners) { + listener.noteKeyRemoval(this, key, oldValue); + } + } + + /** Send a key update event to all registered listeners */ + protected void noteUpdate(K key, V newValue, V oldValue) { + for (CacheListener<K, V> listener: listeners) { + listener.noteKeyUpdate(this, key, newValue, oldValue); + } + } + + /** Adds an event listener for key removals */ + public void addListener(CacheListener<K, V> listener) { + listeners.add(listener); + } + + /** Removes an event listener for key removals */ + public void removeListener(CacheListener<K, V> listener) { + listeners.remove(listener); + } + + @Override + public void onEviction(Object key, CacheLine<V> value) { + ExecutionPool.removePulse(value); + } +} Propchange: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCache.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java URL: http://svn.apache.org/viewvc/ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java?rev=1647483&view=auto ============================================================================== --- ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java (added) +++ ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java Tue Dec 23 05:04:35 2014 @@ -0,0 +1,209 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.cache; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.ofbiz.base.util.Debug; + +/** + * Generalized caching utility. Provides a number of caching features: + * <ul> + * <li>Limited or unlimited element capacity + * <li>If limited, removes elements with the LRU (Least Recently Used) algorithm + * <li>Keeps track of when each element was loaded into the cache + * <li>Using the expireTime can report whether a given element has expired + * <li>Counts misses and hits + * </ul> + * + */ +@SuppressWarnings("serial") +public class OFBizCacheManager { + + public static final String module = OFBizCacheManager.class.getName(); + + /** A static Map to keep track of all of the UtilCache instances. */ + private final ConcurrentHashMap<String, OFBizCache<?, ?>> ofbizCacheTable = new ConcurrentHashMap<String, OFBizCache<?, ?>>(); + + /** An index number appended to utilCacheTable names when there are conflicts. */ + private final ConcurrentHashMap<String, AtomicInteger> defaultIndices = new ConcurrentHashMap<String, AtomicInteger>(); + + /** The name of the UtilCache instance, is also the key for the instance in utilCacheTable. */ + private final String name; + + // weak ref on this + private static final ConcurrentMap<String, JdbmRecordManager> fileManagers = new ConcurrentHashMap<String, JdbmRecordManager>(); + + //TODO: Totally wrong description + /** Constructor which specifies the cacheName as well as the sizeLimit, expireTime and useSoftReference. + * The passed sizeLimit, expireTime and useSoftReference will be overridden by values from cache.properties if found. + * @param sizeLimit The sizeLimit member is set to this value + * @param expireTime The expireTime member is set to this value + * @param cacheName The name of the cache. + * @param useSoftReference Specifies whether or not to use soft references for this cache. + */ + public OFBizCacheManager(String name) { + this.name = name; + } + + public JdbmRecordManager getJdbmRecordManager(String fileStore) { + // create the manager the first time it is needed + JdbmRecordManager jdbmMgr = fileManagers.get(fileStore); + if (jdbmMgr == null) { + Debug.logImportant("Creating file system cache store for cache manager with name: " + this.name, module); + try { + String ofbizHome = System.getProperty("ofbiz.home"); + if (ofbizHome == null) { + Debug.logError("No ofbiz.home property set in environment", module); + } else { + jdbmMgr = new JdbmRecordManager(ofbizHome + "/" + fileStore); + } + } catch (IOException e) { + Debug.logError(e, "Error creating file system cache store for cache manager with name: " + this.name, module); + } + fileManagers.putIfAbsent(fileStore, jdbmMgr); + } + return fileManagers.get(fileStore); + } + + private String getNextDefaultIndex(String cacheName) { + AtomicInteger curInd = defaultIndices.get(cacheName); + if (curInd == null) { + defaultIndices.putIfAbsent(cacheName, new AtomicInteger(0)); + curInd = defaultIndices.get(cacheName); + } + int i = curInd.getAndIncrement(); + return i == 0 ? "" : Integer.toString(i); + } + + + /** Removes all elements from this cache */ + public void clearAllCaches() { + // We make a copy since clear may take time + for (OFBizCache<?,?> cache : ofbizCacheTable.values()) { + cache.clear(); + } + } + + public Set<String> getUtilCacheTableKeySet() { + Set<String> set = new HashSet<String>(ofbizCacheTable.size()); + set.addAll(ofbizCacheTable.keySet()); + return set; + } + + /** Getter for the name of the UtilCache instance. + * @return The name of the instance + */ + public String getName() { + return this.name; + } + + /** Checks for a non-expired key in a specific cache */ + public boolean validKey(String cacheName, Object key) { + OFBizCache<?, ?> cache = findCache(cacheName); + if (cache != null) { + if (cache.containsKey(key)) + return true; + } + return false; + } + + public void clearCachesThatStartWith(String startsWith) { + for (Map.Entry<String, OFBizCache<?, ?>> entry: ofbizCacheTable.entrySet()) { + String name = entry.getKey(); + if (name.startsWith(startsWith)) { + OFBizCache<?, ?> cache = entry.getValue(); + cache.clear(); + } + } + } + + public void clearCache(String cacheName) { + OFBizCache<?, ?> cache = findCache(cacheName); + if (cache == null) return; + cache.clear(); + } + + @SuppressWarnings("unchecked") + public <K, V> OFBizCache<K, V> getOrCreateUtilCache(String name, int sizeLimit, int maxInMemory, long expireTime, boolean useSoftReference, boolean useFileSystemStore, String... names) { + OFBizCache<K, V> existingCache = (OFBizCache<K, V>) ofbizCacheTable.get(name); + if (existingCache != null) return existingCache; + String cacheName = name + getNextDefaultIndex(name); + OFBizCache<K, V> newCache = new OFBizCache<K, V>(this, cacheName, sizeLimit, maxInMemory, expireTime, useSoftReference, useFileSystemStore, name, names); + ofbizCacheTable.putIfAbsent(name, newCache); + return (OFBizCache<K, V>) ofbizCacheTable.get(name); + } + + public <K, V> OFBizCache<K, V> createUtilCache(String name, int sizeLimit, int maxInMemory, long expireTime, boolean useSoftReference, boolean useFileSystemStore, String... names) { + String cacheName = name + getNextDefaultIndex(name); + return storeCache(new OFBizCache<K, V>(this, cacheName, sizeLimit, maxInMemory, expireTime, useSoftReference, useFileSystemStore, name, names)); + } + + public <K, V> OFBizCache<K, V> createUtilCache(String name, int sizeLimit, int maxInMemory, long expireTime, boolean useSoftReference, boolean useFileSystemStore) { + String cacheName = name + getNextDefaultIndex(name); + return storeCache(new OFBizCache<K, V>(this, cacheName, sizeLimit, maxInMemory, expireTime, useSoftReference, useFileSystemStore, name)); + } + + public <K,V> OFBizCache<K, V> createUtilCache(String name, int sizeLimit, long expireTime, boolean useSoftReference) { + String cacheName = name + getNextDefaultIndex(name); + return storeCache(new OFBizCache<K, V>(this, cacheName, sizeLimit, sizeLimit, expireTime, useSoftReference, false, name)); + } + + public <K,V> OFBizCache<K, V> createUtilCache(String name, int sizeLimit, long expireTime) { + String cacheName = name + getNextDefaultIndex(name); + return storeCache(new OFBizCache<K, V>(this, cacheName, sizeLimit, sizeLimit, expireTime, false, false, name)); + } + + public <K,V> OFBizCache<K, V> createUtilCache(int sizeLimit, long expireTime) { + String cacheName = "specified" + getNextDefaultIndex("specified"); + return storeCache(new OFBizCache<K, V>(this, cacheName, sizeLimit, sizeLimit, expireTime, false, false, "specified")); + } + + public <K,V> OFBizCache<K, V> createUtilCache(String name, boolean useSoftReference) { + String cacheName = name + getNextDefaultIndex(name); + return storeCache(new OFBizCache<K, V>(this, cacheName, 0, 0, 0, useSoftReference, false, "default", name)); + } + + public <K,V> OFBizCache<K, V> createUtilCache(String name) { + String cacheName = name + getNextDefaultIndex(name); + return storeCache(new OFBizCache<K, V>(this, cacheName, 0, 0, 0, false, false, "default", name)); + } + + public <K,V> OFBizCache<K, V> createUtilCache() { + String cacheName = "default" + getNextDefaultIndex("default"); + return storeCache(new OFBizCache<K, V>(this, cacheName, 0, 0, 0, false, false, "default")); + } + + private <K, V> OFBizCache<K, V> storeCache(OFBizCache<K, V> cache) { + ofbizCacheTable.put(cache.getName(), cache); + return cache; + } + + @SuppressWarnings("unchecked") + public <K, V> OFBizCache<K, V> findCache(String cacheName) { + return (OFBizCache<K, V>) ofbizCacheTable.get(cacheName); + } + +} Propchange: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/branches/OFBIZ-4098-make-cache-pluggable/framework/base/src/org/ofbiz/base/util/cache/OFBizCacheManager.java ------------------------------------------------------------------------------ svn:mime-type = text/plain