content: package com.alibaba.fastjson.util;
  
  import java.lang.ref.SoftReference;
  import java.nio.charset.CharsetDecoder;
  
  public class ThreadLocalCache {
  
      public final static int                                 CHARS_CACH_INIT_SIZE = 1024;                                    // 1k;
      public final static int                                 CHARS_CACH_MAX_SIZE  = 1024 * 128;                              // 1k;
      private final static ThreadLocal<SoftReference<char[]>> charsBufLocal        = new ThreadLocal<SoftReference<char[]>>();
  
      private final static ThreadLocal<CharsetDecoder>        decoderLocal         = new ThreadLocal<CharsetDecoder>();
  
      public static CharsetDecoder getUTF8Decoder() {
          CharsetDecoder decoder = decoderLocal.get();
          if (decoder == null) {
              decoder = new UTF8Decoder();
              decoderLocal.set(decoder);
          }
          return decoder;
      }
  
      public static void clearChars() {
          charsBufLocal.set(null);
      }
  
      public static char[] getChars(int length) {
          SoftReference<char[]> ref = charsBufLocal.get();
  
          if (ref == null) {
              return allocate(length);
          }
  
          char[] chars = ref.get();
  
          if (chars == null) {
              return allocate(length);
          }
  
          if (chars.length < length) {
              chars = allocate(length);
          }
  
          return chars;
      }
  
      private static char[] allocate(int length) {
          int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length);
  
          if (allocateLength <= CHARS_CACH_MAX_SIZE) {
              char[] chars = new char[allocateLength];
              charsBufLocal.set(new SoftReference<char[]>(chars));
              return chars;
          }
  
          return new char[length];
      }
  
      private static int getAllocateLength(int init, int max, int length) {
          int value = init;
          for (;;) {
              if (value >= length) {
                  return value;
              }
  
              value *= 2;
  
              if (value > max) {
                  break;
              }
          }
  
          return length;
      }
  
      // /////////
      public final static int                                 BYTES_CACH_INIT_SIZE = 1024;                                    // 1k;
      public final static int                                 BYTeS_CACH_MAX_SIZE  = 1024 * 128;                              // 1k;
      private final static ThreadLocal<SoftReference<byte[]>> bytesBufLocal        = new ThreadLocal<SoftReference<byte[]>>();
  
      public static void clearBytes() {
          bytesBufLocal.set(null);
      }
  
      public static byte[] getBytes(int length) {
          SoftReference<byte[]> ref = bytesBufLocal.get();
  
          if (ref == null) {
              return allocateBytes(length);
          }
  
          byte[] bytes = ref.get();
  
          if (bytes == null) {
              return allocateBytes(length);
          }
  
          if (bytes.length < length) {
              bytes = allocateBytes(length);
          }
  
          return bytes;
      }
  
      private static byte[] allocateBytes(int length) {
          int allocateLength = getAllocateLength(CHARS_CACH_INIT_SIZE, CHARS_CACH_MAX_SIZE, length);
  
          if (allocateLength <= CHARS_CACH_MAX_SIZE) {
              byte[] chars = new byte[allocateLength];
              bytesBufLocal.set(new SoftReference<byte[]>(chars));
              return chars;
          }
  
          return new byte[length];
      }
  
  }
  