java.lang.Object
org.rrd4j.core.RrdDbPool

public class RrdDbPoolextends Object
This class should be used to synchronize access to RRD files in a multithreaded environment. This class should be also used to prevent opening of too many RRD files at the same time (thus avoiding operating system limits).

It can also be used a factory for RrdDb, using a default backend factory.

In case of interruptions, it throws IllegalStateException.

  • Field Details

    • INITIAL_CAPACITY

      public static final int INITIAL_CAPACITY
      Initial capacity of the pool i.e. maximum number of simultaneously open RRD. The pool will never open too many RRD at the same time.
      See Also:
    • maxCapacity

      private int maxCapacity
      Entries the pool may hold at once.
    • usage

      private Semaphore usage
      Permits limiting concurrent pool use.
    • usageWLock

      private final ReentrantReadWriteLock.WriteLock usageWLock
      Write lock for capacity changes.
    • usageRLock

      private final ReentrantReadWriteLock.ReadLock usageRLock
      Read lock for normal pool use.
    • fullCondition

      private final Condition fullCondition
      Condition awaited when the pool is full.
    • waitFull

      private final AtomicBoolean waitFull
      True while a thread waits for pool capacity.
    • pool

      private final ConcurrentMap<URI, RrdDbPool.RrdEntry> pool
      Pooled entries, by canonical URI.
    • defaultFactory

      private RrdBackendFactory defaultFactory
      Factory used for URIs without a scheme.
  • Constructor Details

    • RrdDbPool

      public RrdDbPool()
      Constructor for RrdDbPool. It will use the default backend factory.
    • RrdDbPool

      public RrdDbPool(RrdBackendFactory defaultFactory)
      Constructor for RrdDbPool.
      Parameters:
      defaultFactory - the default factory used when given a simple path of a RRD.
  • Method Details

    • getInstance

      public static RrdDbPool getInstance()
      Creates a single instance of the class on the first call, or returns already existing one. Uses Initialization On Demand Holder idiom.
      Returns:
      Single instance of this class
    • getOpenFileCount

      public int getOpenFileCount()
      Returns the number of open RRD.
      Returns:
      Number of currently open RRD held in the pool.
    • getOpenUri

      public URI[] getOpenUri()
      Returns an array of open RRD URI.
      Returns:
      Array with URI to open RRD held in the pool.
    • getOpenUriStream

      public java.util.stream.Stream<URI> getOpenUriStream()
      Returns an stream open RRD.
      Returns:
      Stream with canonical URI to open RRD path held in the pool.
    • getOpenFiles

      public String[] getOpenFiles()
      Returns an array of open RRD.
      Returns:
      Array with canonical path to open RRD path held in the pool.
    • getEntry

      private RrdDbPool.RrdEntry getEntry(URI uri, boolean cancreate) throws InterruptedException
      Finds or creates the pooled entry for a URI.
      Parameters:
      uri - the canonical URI
      cancreate - true to create a missing entry
      Returns:
      the entry, or null if not found
      Throws:
      InterruptedException - if interrupted while waiting
    • passNext

      private void passNext(RrdDbPool.ACTION a, RrdDbPool.RrdEntry e)
      Hands the freed slot to the next waiting request.
      Parameters:
      a - the action chosen for the waiter
      e - the entry being passed, may be null
    • requestRrdDb

      public RrdDb requestRrdDb(String path) throws IOException
      Requests a RrdDb reference for the given RRD path.
      • If the RRD is already open, previously returned RrdDb reference will be returned. Its usage count will be incremented by one.
      • If the RRD is not already open and the number of already open RRD is less than getCapacity(), it will be opened and a new RrdDb reference will be returned. If the RRD is not already open and the number of already open RRD is equal to getCapacity(), the method blocks until some RRD are closed.

      The path is transformed to an URI using the default factory defined at the creation of the pool.

      Parameters:
      path - Path to existing RRD.
      Returns:
      reference for the given RRD.
      Throws:
      IOException - Thrown in case of I/O error
    • requestRrdDb

      public RrdDb requestRrdDb(URI uri) throws IOException
      Requests a RrdDb reference for the given RRD URI.
      • If the RRD is already open, previously returned RrdDb reference will be returned. Its usage count will be incremented by one.
      • If the RRD is not already open and the number of already open RRD is less than getCapacity(), it will be opened and a new RrdDb reference will be returned. If the RRD is not already open and the number of already open RRD is equal to getCapacity(), the method blocks until some RRD are closed.

      If the default backend factory for the pool can handle this URI, it will be used, or else RrdBackendFactory.findFactory(URI) will be used to find the backend factory used.

      Parameters:
      uri - URI to existing RRD file
      Returns:
      reference for the give RRD file
      Throws:
      IOException - Thrown in case of I/O error
    • waitEmpty

      private RrdDbPool.RrdEntry waitEmpty(URI uri) throws InterruptedException
      Wait for a empty reference with no usage
      Parameters:
      uri - the canonical storage URI of the RRD to wait for
      Returns:
      an reference with no usage
      Throws:
      InterruptedException - if the thread is interrupted while waiting
    • requestEmpty

      private RrdDbPool.RrdEntry requestEmpty(URI uri) throws InterruptedException
      Got an empty reference, use it only if slots are available But don't hold any lock waiting for it
      Parameters:
      uri - the canonical storage URI of the RRD to wait for
      Returns:
      an reference with no usage
      Throws:
      InterruptedException - if the thread is interrupted while waiting
    • requestRrdDb

      RrdDb requestRrdDb(URI uri, RrdBackendFactory factory) throws IOException
      Request RRD
      Parameters:
      uri - the canonical storage URI of the RRD to open
      factory - the backend factory that opens the storage
      Returns:
      the pooled RrdDb, whose use count this call has incremented
      Throws:
      IOException - if the storage cannot be opened
    • requestRrdDb

      RrdDb requestRrdDb(RrdDef rrdDef, RrdBackendFactory factory) throws IOException
      Request RRD from definition
      Parameters:
      rrdDef - the definition of the RRD to create, which also supplies the canonical URI
      factory - the backend factory that opens the storage
      Returns:
      the newly created pooled RrdDb, with a use count of one
      Throws:
      IOException - if the storage cannot be created
    • requestRrdDb

      private RrdDb requestRrdDb(RrdDb.Builder builder, URI uri, RrdBackendFactory factory) throws IOException
      Opens or creates the database for a request.
      Parameters:
      builder - the database builder
      uri - the canonical URI
      factory - the backend factory
      Returns:
      the open database
      Throws:
      IOException - if the database cannot be opened
    • requestRrdDb

      RrdDb requestRrdDb(URI uri, RrdBackendFactory factory, DataImporter importer) throws IOException
      Request RRD with import
      Parameters:
      uri - the canonical storage URI of the RRD to create
      factory - the backend factory that opens the storage
      importer - the data importer run over the new RRD while it is still unpooled
      Returns:
      the newly created pooled RrdDb, with a use count of one
      Throws:
      IOException - if the storage cannot be created
    • requestRrdDb

      public RrdDb requestRrdDb(RrdDef rrdDef) throws IOException
      Requests a RrdDb reference for the given RRD definition object.
      • If the RRD with the path specified in the RrdDef object is already open, the method blocks until the file is closed.
      • If the RRD is not already open and the number of already open RRD is less than getCapacity(), a new RRD will be created and it's RrdDb reference will be returned. If the RRD is not already open and the number of already open RRD is equal to getCapacity(), the method blocks until some RrdDb references are closed.

      If the factory defined when creating the pool can handle the URI, it will be used, or else RrdBackendFactory.findFactory(URI) will be used.

      Parameters:
      rrdDef - Definition of the RRD file to be created.
      Returns:
      Reference to the newly created RRD file.
      Throws:
      IOException - Thrown in case of I/O error
      IllegalStateException - if the thread was interrupted
    • requestRrdDb

      public RrdDb requestRrdDb(String path, String sourcePath) throws IOException
      Requests a RrdDb reference for the given path. The RRD will be created from external data (from XML dump or RRDTool's binary RRD file).
      • If the RRD with the path specified is already open, the method blocks until the file is closed.
      • If the RRD is not already open and the number of already open RRD is less than getCapacity(), a new RRD will be created and it's RrdDb reference will be returned. If the RRD is not already open and the number of already open RRD is equal to getCapacity(), the method blocks until some RrdDb references are closed.

      The path is transformed to an URI using the default factory of the pool.

      Parameters:
      path - Path to the RRD that should be created.
      sourcePath - Path to external data which is to be converted to Rrd4j's native RRD file format.
      Returns:
      Reference to the newly created RRD.
      Throws:
      IOException - Thrown in case of I/O error
      IllegalStateException - if the thread was interrupted
    • requestRrdDb

      public RrdDb requestRrdDb(URI uri, String sourcePath) throws IOException
      Requests a RrdDb reference for the given URI. The RRD will be created from external data (from XML dump or RRDTool's binary RRD file).
      • If the RRD with the URI specified is already open, the method blocks until the file is closed.
      • If the RRD is not already open and the number of already open RRD is less than getCapacity(), a new RRD will be created and it's RrdDb reference will be returned. If the RRD is not already open and the number of already open RRD is equal to getCapacity(), the method blocks until some RrdDb references are closed.
      If the factory defined when creating the pool can handle the URI, it will be used, or else RrdBackendFactory.findFactory(URI) will be used to choose the factory.
      Parameters:
      uri - URI to the RRD that should be created
      sourcePath - Path to external data which is to be converted to Rrd4j's native RRD file format
      Returns:
      Reference to the newly created RRD
      Throws:
      IOException - Thrown in case of I/O error
      IllegalStateException - if the thread was interrupted
    • setCapacity

      public void setCapacity(int newCapacity)
      Sets the maximum number of simultaneously open RRD.
      Parameters:
      newCapacity - Maximum number of simultaneously open RRD.
      Throws:
      IllegalStateException - if called while the pool is not empty or the thread was interrupted.
    • getCapacity

      public int getCapacity()
      Returns the maximum number of simultaneously open RRD.
      Returns:
      maximum number of simultaneously open RRD
      Throws:
      IllegalStateException - if the thread was interrupted
    • getOpenCount

      public int getOpenCount(RrdDb rrdDb)
      Returns the number of usage for a RRD.
      Parameters:
      rrdDb - RrdDb reference for which informations is needed.
      Returns:
      the number of request for this RRD.
      Throws:
      IllegalStateException - if the thread was interrupted
    • getOpenCount

      public int getOpenCount(String path)
      Returns the number of usage for a RRD.

      The path is transformed to an URI using the default factory.

      Parameters:
      path - RRD's path for which informations is needed.
      Returns:
      the number of request for this RRD.
      Throws:
      IllegalStateException - if the thread was interrupted
    • getOpenCount

      public int getOpenCount(URI uri)
      Returns the number of usage for a RRD.
      Parameters:
      uri - RRD's URI for which informations is needed.
      Returns:
      the number of request for this RRD.
      Throws:
      IllegalStateException - if the thread was interrupted
    • getCanonicalUriUsage

      private int getCanonicalUriUsage(URI uri)
      Counts entries sharing a canonical path.
      Parameters:
      uri - the URI to count
      Returns:
      the number of users
    • lockEmpty

      public Lock lockEmpty(long timeout, TimeUnit unit) throws InterruptedException
      Wait until the pool is empty and return a lock that prevent any additions of new RrdDb references until it's released.
      Parameters:
      timeout - the time to wait for the write lock
      unit - the time unit of the timeout argument
      Returns:
      a lock to release when operations on this pool are finished.
      Throws:
      InterruptedException - if interrupted whole waiting for the lock
    • checkFactory

      private RrdBackendFactory checkFactory(URI uri)
      Resolves the backend factory for a URI.
      Parameters:
      uri - the URI to resolve
      Returns:
      the factory to use