/* * Carrot2 project. * * Copyright (C) 2002-2016, Dawid Weiss, Stanisław Osiński. * All rights reserved. * * Refer to the full license file "carrot2.LICENSE" * in the root folder of the repository checkout or at: * http://www.carrot2.org/carrot2.LICENSE */ package org.carrot2.core; import org.carrot2.util.annotations.AspectModified; import org.carrot2.util.pool.FixedSizePool; /** * Creates {@link Controller}s in a number of common configurations. The most useful * configurations are: * <ul> * <li>{@link #createSimple()}: for one-time processing and quick experiments with the * code;</li> * <li>{@link #createCachingPooling(Class...)}: for long-running applications (e.g. web * applications) handling repeated (cacheable) requests.</li> * </ul> */ public final class ControllerFactory { private ControllerFactory() { // No instantiation } /** * Creates a controller with no processing component pooling and no results caching. * The returned controller will instantiate new processing component instances for each * processing request and will not perform any caching of the processing results. * <p> * This controller is useful for one-time processing or fast experiments with the * code. For long-running applications (e.g. web applications), consider using a * controller with component pooling and/or caching. * </p> * * @see #createPooling() * @see #createCaching(Class...) * @see #create(boolean, Class...) */ public static Controller createSimple() { return create(false); } /** * Creates a controller with processing component pooling but with no results caching. * The returned controller will maintain an internal pool of processing components, so * that they are reused between processing requests. Soft references are used to cache * component instances. There is no upper bound on the number of instances the pool * may cache. * <p> * Use this controller in long-running applications and when your processing * components are expensive to create. For applications that handle large numbers of * repeated requests, consider using a caching and pooling controller. * </p> * * @see #create(boolean, Class...) * @see #createPooling(int) */ public static Controller createPooling() { return create(true); } /** * Creates a controller with processing component pooling but with no results caching. * The returned controller will maintain an internal fixed-size, hard-referenced * pool of processing components, so that they are reused between processing requests. * <p> * Use this controller in long-running applications and when your processing * components are expensive to create. For applications that handle large numbers of * repeated requests, consider using a caching and pooling controller. * </p> * * @param instancePoolSize Number of instances created for a single component * class-ID pair. For computational components it is sensible to set this pool to the * number of CPU cores available on the machine. * * @see #create(int, Class...) * @see #createPooling() * @see Runtime#availableProcessors() */ public static Controller createPooling(int instancePoolSize) { return create(instancePoolSize); } /** * Creates a controller with no processing component pooling but with results caching. * The returned controller will maintain a cache of the processing results. For each * component whose results are to be cached, if there comes a repeated request for * processing with that component with the same set of input attributes, the result * will be returned from the cache. The returned controller will instantiate new * processing components object for each processing request whose result has not yet * been cached. * <p> * Uses of this specific controller are rather limited. Use it if your application is * handling large numbers of repeated requests but you don't want to have the * components pooled for some reason. Make sure the processing components are cheap to * create, otherwise performance will suffer. * </p> * * @param cachedProcessingComponents classes of components whose output should be cached * by the controller. If a superclass is provided here, e.g. * {@link IDocumentSource}, all its subclasses will be subject to caching. * If {@link IProcessingComponent} is provided here, output of all * components will be cached. */ @SafeVarargs public static Controller createCaching( Class<? extends IProcessingComponent>... cachedProcessingComponents) { return create(false, cachedProcessingComponents); } /** * Creates a controller with processing component pooling and results caching. The * returned controller combines processing component pooling and processing results * caching. * <p> * Use this component in long-running applications that handle repeated requests. * </p> * * @param cachedProcessingComponents classes of components whose output should be cached * by the controller. If a superclass is provided here, e.g. * {@link IDocumentSource}, all its subclasses will be subject to caching. * If {@link IProcessingComponent} is provided here, output of all * components will be cached. */ @SafeVarargs public static Controller createCachingPooling( Class<? extends IProcessingComponent>... cachedProcessingComponents) { return create(true, cachedProcessingComponents); } /** * Creates a controller with the specified pooling and caching settings. * * @param componentPooling if <code>true</code>, component pooling * will be performed (soft pool), otherwise no component pool will be used. * @param cachedProcessingComponents classes of components whose output should be cached * by the controller. If a superclass is provided here, e.g. * {@link IDocumentSource}, all its subclasses will be subject to caching. * If {@link IProcessingComponent} is provided here, output of all * components will be cached. */ @SafeVarargs public static Controller create(boolean componentPooling, Class<? extends IProcessingComponent>... cachedProcessingComponents) { final IProcessingComponentManager baseManager = (componentPooling ? new PoolingProcessingComponentManager() : new SimpleProcessingComponentManager()); return new Controller(addCachingManager(baseManager, cachedProcessingComponents)); } /** * Creates a controller with the specified fixed-size pooling and caching settings. * * @param instancePoolSize Number of instances created for a single component class-ID * pair. For computational components it is sensible to set this pool to * the number of CPU cores available on the machine. * @param cachedProcessingComponents classes of components whose output should be * cached by the controller. If a superclass is provided here, e.g. * {@link IDocumentSource}, all its subclasses will be subject to caching. * If {@link IProcessingComponent} is provided here, output of all * components will be cached. */ @SafeVarargs public static Controller create(int instancePoolSize, Class<? extends IProcessingComponent>... cachedProcessingComponents) { if (instancePoolSize <= 0) throw new IllegalArgumentException("Instance pool size must be greater than zero: " + instancePoolSize); final IProcessingComponentManager baseManager = new PoolingProcessingComponentManager( new FixedSizePool<IProcessingComponent, String>(instancePoolSize)); return new Controller(addCachingManager(baseManager, cachedProcessingComponents)); } /** * Adds caching manager wrapper if caching is requested. */ @AspectModified("Throws an exception in .NET") @SafeVarargs private static IProcessingComponentManager addCachingManager( IProcessingComponentManager baseManager, Class<? extends IProcessingComponent>... cachedProcessingComponents) { if (cachedProcessingComponents.length == 0) return baseManager; return new CachingProcessingComponentManager(baseManager, cachedProcessingComponents); } }