All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.ehcache.pool.impl.DefaultSizeOfEngine Maven / Gradle / Ivy

/**
 *  Copyright 2003-2010 Terracotta, Inc.
 *
 *  Licensed 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 net.sf.ehcache.pool.impl;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.sf.ehcache.CacheException;
import net.sf.ehcache.pool.Size;
import net.sf.ehcache.pool.SizeOfEngine;
import net.sf.ehcache.pool.sizeof.AgentSizeOf;
import net.sf.ehcache.pool.sizeof.ReflectionSizeOf;
import net.sf.ehcache.pool.sizeof.SizeOf;
import net.sf.ehcache.pool.sizeof.UnsafeSizeOf;
import net.sf.ehcache.pool.sizeof.filter.AnnotationSizeOfFilter;
import net.sf.ehcache.pool.sizeof.filter.CombinationSizeOfFilter;
import net.sf.ehcache.pool.sizeof.filter.ResourceSizeOfFilter;
import net.sf.ehcache.pool.sizeof.filter.SizeOfFilter;
import net.sf.ehcache.util.ClassLoaderUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Alex Snaps
 */
public class DefaultSizeOfEngine implements SizeOfEngine {

    /**
     * System property defining a user specific resource based size-of filter.
     * 

* The resource pointed to by this property must be a list of fully qualified * field or class names, one per line: *

     * # This is a comment
     * org.mycompany.domain.MyType
     * org.mycompany.domain.MyOtherType.myField
     * 
* Fields or types matching against lines in this resource will be ignored * when calculating the size of the object graph. */ public static final String USER_FILTER_RESOURCE = "net.sf.ehcache.sizeof.filter"; private static final Logger LOG = LoggerFactory.getLogger(DefaultSizeOfEngine.class.getName()); private static final String VERBOSE_DEBUG_LOGGING = "net.sf.ehcache.sizeof.verboseDebugLogging"; private static final SizeOfFilter DEFAULT_FILTER; private static final boolean USE_VERBOSE_DEBUG_LOGGING; static { Collection filters = new ArrayList(); filters.add(new AnnotationSizeOfFilter()); try { filters.add(new ResourceSizeOfFilter(SizeOfEngine.class.getResource("builtin-sizeof.filter"))); } catch (IOException e) { LOG.warn("Built-in sizeof filter could not be loaded: {}", e); } SizeOfFilter userFilter = getUserFilter(); if (userFilter != null) { filters.add(userFilter); } DEFAULT_FILTER = new CombinationSizeOfFilter(filters.toArray(new SizeOfFilter[filters.size()])); USE_VERBOSE_DEBUG_LOGGING = getVerboseSizeOfDebugLogging(); } private final SizeOf sizeOf; private final int maxDepth; private final boolean abortWhenMaxDepthExceeded; /** * Creates a default size of engine using the best available sizing algorithm. * @param maxDepth the max object graph that will be traversed. * @param abortWhenMaxDepthExceeded true if the object traversal should be aborted when the max depth is exceeded */ public DefaultSizeOfEngine(int maxDepth, boolean abortWhenMaxDepthExceeded) { this.maxDepth = maxDepth; this.abortWhenMaxDepthExceeded = abortWhenMaxDepthExceeded; SizeOf bestSizeOf; try { bestSizeOf = new AgentSizeOf(DEFAULT_FILTER); LOG.info("using Agent sizeof engine"); } catch (UnsupportedOperationException e) { try { bestSizeOf = new UnsafeSizeOf(DEFAULT_FILTER); LOG.info("using Unsafe sizeof engine"); } catch (UnsupportedOperationException f) { try { bestSizeOf = new ReflectionSizeOf(DEFAULT_FILTER); LOG.info("using Reflection sizeof engine"); } catch (UnsupportedOperationException g) { throw new CacheException("A suitable SizeOf engine could not be loaded: " + e + ", " + f + ", " + g); } } } this.sizeOf = bestSizeOf; } private DefaultSizeOfEngine(DefaultSizeOfEngine defaultSizeOfEngine, int maxDepth, boolean abortWhenMaxDepthExceeded) { this.sizeOf = defaultSizeOfEngine.sizeOf; this.maxDepth = maxDepth; this.abortWhenMaxDepthExceeded = abortWhenMaxDepthExceeded; } /** * {@inheritDoc} */ public SizeOfEngine copyWith(int maxDepth, boolean abortWhenMaxDepthExceeded) { return new DefaultSizeOfEngine(this, maxDepth, abortWhenMaxDepthExceeded); } private static SizeOfFilter getUserFilter() { String userFilterProperty = System.getProperty(USER_FILTER_RESOURCE); if (userFilterProperty != null) { List filterUrls = new ArrayList(); try { filterUrls.add(new URL(userFilterProperty)); } catch (MalformedURLException e) { LOG.debug("MalformedURLException using {} as a URL", userFilterProperty); } try { filterUrls.add(new File(userFilterProperty).toURI().toURL()); } catch (MalformedURLException e) { LOG.debug("MalformedURLException using {} as a file URL", userFilterProperty); } filterUrls.add(ClassLoaderUtil.getStandardClassLoader().getResource(userFilterProperty)); for (URL filterUrl : filterUrls) { SizeOfFilter filter; try { filter = new ResourceSizeOfFilter(filterUrl); LOG.info("Using user supplied filter @ {}", filterUrl); return filter; } catch (IOException e) { LOG.debug("IOException while loading user size-of filter resource", e); } } } return null; } private static boolean getVerboseSizeOfDebugLogging() { String verboseString = System.getProperty(VERBOSE_DEBUG_LOGGING, "false").toLowerCase(); return verboseString.equals("true"); } /** * {@inheritDoc} */ public Size sizeOf(final Object key, final Object value, final Object container) { Size size = sizeOf.deepSizeOf(maxDepth, abortWhenMaxDepthExceeded, key, value, container); if (USE_VERBOSE_DEBUG_LOGGING && LOG.isDebugEnabled()) { LOG.debug("size of {}/{}/{} -> {}", new Object[]{key, value, container, size.getCalculated()}); } return size; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy