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

io.setl.json.primitive.cache.CacheManager Maven / Gradle / Ivy

Go to download

An implementation of the Canonical JSON format with support for javax.json and Jackson

The newest version!
package io.setl.json.primitive.cache;

import static io.setl.json.primitive.cache.CacheType.KEYS;
import static io.setl.json.primitive.cache.CacheType.NUMBERS;
import static io.setl.json.primitive.cache.CacheType.STRINGS;
import static io.setl.json.primitive.cache.CacheType.VALUES;

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;

import io.setl.json.primitive.CJString;
import io.setl.json.primitive.numbers.CJNumber;

/**
 * Caching of common immutable values. This limits the number of objects created as similar JSON documents are parsed as shared keys and values are reused.
 *
 * @author Simon Greatrix on 05/02/2020.
 */
public class CacheManager {

  private static ICache myKeyCache;

  private static ICache myNumberCache;

  private static ICache myStringCache;

  private static ICache myValueCache;


  private static  ICache createCache(CacheType name) {
    int maxSize = Integer.getInteger(CacheManager.class.getPackageName() + "." + name.getPropertyName() + ".maxSize", 1_000);
    String cacheFactory = System.getProperty(
        CacheManager.class.getPackageName() + "." + name + ".factory",
        SimpleLruCacheFactory.class.getName()
    );

    if (maxSize <= 0) {
      return new NoCache<>();
    }

    ICacheFactory factory = new SimpleLruCacheFactory();
    try {
      Class cl = Class.forName(cacheFactory);
      Class cl2 = cl.asSubclass(ICacheFactory.class);
      Constructor constructor = cl2.getConstructor();
      factory = constructor.newInstance();
    } catch (ClassNotFoundException | ClassCastException | NoSuchMethodException
        | InstantiationException | IllegalAccessException | InvocationTargetException e) {
      Logger logger = System.getLogger(CacheManager.class.getName());
      logger.log(Level.ERROR, "Cannot create a cache factory from " + cacheFactory, e);
    }
    ICache cache = factory.create(name, maxSize);
    return (cache != null) ? cache : new NoCache<>();
  }


  /**
   * Cache of object keys to their primary representation. This prevents the creation of duplicate strings for fields.
   *
   * @return the cache
   */
  public static ICache keyCache() {
    return myKeyCache;
  }


  /**
   * Cache of JSON input to the corresponding numeric canonical.
   *
   * @return the cache.
   */
  public static ICache numberCache() {
    return myNumberCache;
  }


  /**
   * Set the cache that maps object keys to a fixed representation.
   *
   * @param newCache the new cache (or null for no caching)
   */
  public static void setKeyCache(ICache newCache) {
    myKeyCache = Objects.requireNonNullElseGet(newCache, NoCache::new);
  }


  /**
   * Set the cache that maps the textual representation of numerical values to a fixed representation.
   *
   * @param newNumberCache the new cache (or null for no caching)
   */
  public static void setNumberCache(ICache newNumberCache) {
    myNumberCache = Objects.requireNonNullElseGet(newNumberCache, NoCache::new);
  }


  /**
   * Set the cache that maps string values to a fixed representation.
   *
   * @param newCache the new cache (or null for no caching)
   */
  public static void setStringCache(ICache newCache) {
    myStringCache = Objects.requireNonNullElseGet(newCache, NoCache::new);
  }


  /**
   * Set the cache that maps numeric values to a fixed representation.
   *
   * @param newCache the new cache (or null for no caching)
   */
  public static void setValueCache(ICache newCache) {
    myValueCache = Objects.requireNonNullElseGet(newCache, NoCache::new);
  }


  /**
   * Cache of JSON input to the corresponding text canonical.
   *
   * @return the cache.
   */
  public static ICache stringCache() {
    return myStringCache;
  }


  /**
   * Cache of numbers to their encapsulated JSON representation. A representation is almost always a CJNumber, but it could be a CJString for a non-finite
   * value.
   *
   * @return the cache.
   */
  public static ICache valueCache() {
    return myValueCache;
  }

  static {
    myNumberCache = createCache(NUMBERS);
    myKeyCache = createCache(KEYS);
    myStringCache = createCache(STRINGS);
    myValueCache = createCache(VALUES);
  }


  private CacheManager() {
    // do nothing
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy