Class AsciiStringInterner


  • final class AsciiStringInterner
    extends java.lang.Object
    Provides the canonicalization/interning of String instances which contain only ascii characters, keyed by the byte[] representation (in ascii).

    The values are stored in SoftReferences, allowing them to be garbage collected if not in use and there is memory pressure.

    NOTE: Instances are safe for concurrent use.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      (package private) java.util.concurrent.ConcurrentMap<AsciiStringInterner.BaseKey,​java.lang.ref.SoftReference<java.lang.String>> cache
      Contains the canonicalized values, keyed by the ascii byte[].
      (package private) java.lang.ref.ReferenceQueue<java.lang.String> refQueue
      Used for Reference as values in cache.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      (package private) static boolean arrayEquals​(byte[] a, int aOffset, int aLength, byte[] b, int bOffset, int bLength)
      Performs equality check between a and b (with corresponding offset/length values).
      private void cleanQueue()
      Process any entries in refQueue to purge from the cache.
      java.lang.String getString​(byte[] bytes, int offset, int length, Encoding encoding)
      Produces a String instance for the given bytes.
      java.lang.String getStringIfPresent​(byte[] bytes, int offset, int length, Encoding encoding)
      Produces a String instance for the given bytes.
      private static int hashKey​(byte[] bytes, int offset, int length)
      Generates a hash value for the relevant entries in bytes as long as all values are ascii (>= 0).
      boolean putString​(java.lang.String val)
      Preemptively populates a value into the cache.
      java.lang.String toString()
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • cache

        final java.util.concurrent.ConcurrentMap<AsciiStringInterner.BaseKey,​java.lang.ref.SoftReference<java.lang.String>> cache
        Contains the canonicalized values, keyed by the ascii byte[].
      • refQueue

        final java.lang.ref.ReferenceQueue<java.lang.String> refQueue
        Used for Reference as values in cache.
    • Constructor Detail

      • AsciiStringInterner

        AsciiStringInterner()
    • Method Detail

      • putString

        public boolean putString​(java.lang.String val)
        Preemptively populates a value into the cache. This is intended to be used with String constants which are frequently used. While this can work with other String values, if val is ever garbage collected, it will not be actively removed from this instance.
        Parameters:
        val - The value to intern. Must not be null.
        Returns:
        Indication if val is an ascii String and placed into cache.
      • getString

        public java.lang.String getString​(byte[] bytes,
                                          int offset,
                                          int length,
                                          Encoding encoding)
                                   throws java.io.IOException
        Produces a String instance for the given bytes. If all are valid ascii (i.e. >= 0) either an existing value will be returned, or the newly created String will be stored before being returned.

        If non-ascii bytes are discovered, the encoding will be used to decode and that value will be returned (but not stored).

        Parameters:
        bytes - The bytes of the String. Must not be null.
        offset - Offset into bytes to start.
        length - The number of bytes in bytes which are relevant.
        encoding - To use if non-ascii bytes seen.
        Returns:
        Decoded String from bytes.
        Throws:
        java.io.IOException - If error decoding from Encoding.
      • getStringIfPresent

        public java.lang.String getStringIfPresent​(byte[] bytes,
                                                   int offset,
                                                   int length,
                                                   Encoding encoding)
                                            throws java.io.IOException
        Produces a String instance for the given bytes.

        If all are valid ascii (i.e. >= 0) and a corresponding String value exists, it will be returned. If no value exists, a String will be created, but not stored.

        If non-ascii bytes are discovered, the encoding will be used to decode and that value will be returned (but not stored).

        Parameters:
        bytes - The bytes of the String. Must not be null.
        offset - Offset into bytes to start.
        length - The number of bytes in bytes which are relevant.
        encoding - To use if non-ascii bytes seen.
        Returns:
        Decoded String from bytes.
        Throws:
        java.io.IOException - If error decoding from Encoding.
      • hashKey

        private static int hashKey​(byte[] bytes,
                                   int offset,
                                   int length)
        Generates a hash value for the relevant entries in bytes as long as all values are ascii (>= 0).
        Returns:
        hash code for relevant bytes, or 0 if non-ascii bytes present.
      • arrayEquals

        static boolean arrayEquals​(byte[] a,
                                   int aOffset,
                                   int aLength,
                                   byte[] b,
                                   int bOffset,
                                   int bLength)
        Performs equality check between a and b (with corresponding offset/length values).

        The static boolean equals(byte[].class, int, int, byte[], int, int method in Arrays is optimized for longer byte[] instances than is expected to be seen here.

      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object