Package hudson.util

Class KeyedDataStorage<T,​P>

  • Direct Known Subclasses:
    FingerprintMap

    public abstract class KeyedDataStorage<T,​P>
    extends Object
    Convenient base class for implementing data storage.

    One typical pattern of data storage in Hudson is the one that Fingerprint uses, where each data is keyed by an unique key (MD5 sum), and that key is used to determine the file system location of the data. On memory, each data is represented by one object (Fingerprint), and write access to the same data is coordinated by using synchronization.

    With such storage, care has to be taken to ensure that there's only one data object in memory for any given key. That means load and create operation needs to be synchronized. This class implements this logic in a fairly efficient way, and thus intends to help plugins that want to use such data storage.

    Since:
    1.87
    Author:
    Kohsuke Kawaguchi
    See Also:
    FingerprintMap
    • Field Detail

      • totalQuery

        public final AtomicInteger totalQuery
        Total number of queries into this storage.
      • cacheHit

        public final AtomicInteger cacheHit
        Number of cache hits (of all the total queries.)
      • weakRefLost

        public final AtomicInteger weakRefLost
        Among cache misses, number of times when we had SoftReference but lost its value due to GC. totalQuery-cacheHit-weakRefLost means cache miss.
      • loadFailure

        public final AtomicInteger loadFailure
        Number of failures in loading data.
    • Constructor Detail

      • KeyedDataStorage

        public KeyedDataStorage()
    • Method Detail

      • getOrCreate

        @NonNull
        public T getOrCreate​(String key,
                             P createParams)
                      throws IOException
        Atomically gets the existing data object if any, or if it doesn't exist create it and return it.
        Parameters:
        createParams - Additional parameters needed to create a new data object. Can be null.
        Returns:
        Item with the specified key.
        Throws:
        IOException - Loading error
      • get

        @CheckForNull
        public T get​(String key)
              throws IOException
        Finds the data object that matches the given key if available, or null if not found.
        Returns:
        Item with the specified key
        Throws:
        IOException - Loading error
      • get

        @CheckForNull
        protected T get​(@NonNull
                        String key,
                        boolean createIfNotExist,
                        P createParams)
                 throws IOException
        Implementation of get/getOrCreate.
        Returns:
        Item with the specified key
        Throws:
        IOException - Loading error
      • load

        @CheckForNull
        protected abstract T load​(String key)
                           throws IOException
        Attempts to load an existing data object from disk.

        KeyedDataStorage class serializes the requests so that no two threads call the load(String) method with the same parameter concurrently. This ensures that there's only up to one data object for any key.

        Returns:
        null if no such data exists.
        Throws:
        IOException - if load operation fails. This exception will be propagated to the caller.
      • create

        @NonNull
        protected abstract T create​(@NonNull
                                    String key,
                                    @NonNull
                                    P createParams)
                             throws IOException
        Creates a new data object.

        This method is called by getOrCreate(String,Object) if the data that matches the specified key does not exist.

        Because of concurrency, another thread might call get(String) as soon as a new data object is created, so it's important that this method returns a properly initialized "valid" object.

        Returns:
        Created item. If construction fails, abort with an exception.
        Throws:
        IOException - if the method fails to create a new data object, it can throw IOException (or any other exception) and that will be propagated to the caller.
      • resetPerformanceStats

        public void resetPerformanceStats()
      • getPerformanceStats

        public String getPerformanceStats()
        Gets the short summary of performance statistics.