/* (C) 2012 Pragmatic Software
   This Source Code Form is subject to the terms of the Mozilla Public
   License, v. 2.0. If a copy of the MPL was not distributed with this
   file, You can obtain one at http://mozilla.org/MPL/2.0/
 */

package com.googlecode.networklog;

import java.util.concurrent.ConcurrentHashMap;

public class StringPool {
  final static int maxPoolSize = 1024;
  final public static ConcurrentHashMap<String, String> pool = new ConcurrentHashMap<String, String>(maxPoolSize);
  final public static ConcurrentHashMap<String, String> lowercasePool = new ConcurrentHashMap<String, String>(maxPoolSize);
  final public static CharArrayStringAATree charPool = new CharArrayStringAATree();
  static int poolSize = 0;
  static int lowercasePoolSize = 0;
  static CharArray charBuffer = new CharArray(256);

  public static void clearCharPool() {
    charPool.clear();
  }

  public static String get(CharArray chars) {
    return get(chars.getData(), 0, chars.getPos());
  }

  public static String get(char[] chars, int pos, int length) {
    charBuffer.reset();
    charBuffer.append(chars, pos, length);

    if (charPool.size + 1 >= maxPoolSize) {
      // clear pool to free memory and allow pool to rebuild
      MyLog.d("[StringPool] Clearing charPool");
      charPool.clear();
    }

    return charPool.insert(charBuffer);
  }

  public static String get(String string) {
    if(string == null) {
      return "";
    }

    String result = pool.get(string);

    if(result == null) {
      String newString = new String(string); // decouple string from substring(), etc
      
      pool.put(newString, newString);
      poolSize++;

      if(MyLog.enabled) {
        MyLog.d("[StringPool] new addition [" + newString + "]; pool size: " + poolSize);
      }

      if (poolSize >= maxPoolSize) {
        // clear pool to free memory and allow pool to rebuild
        MyLog.d("[StringPool] Clearing pool");
        pool.clear();
        poolSize = 0;
      }

      return newString;
    } else {
      return result;
    }
  }

  public static String getLowerCase(String string) {
    if(string == null) {
      return "";
    }

    String result = lowercasePool.get(string);

    if(result == null) {
      String newString = new String(string.toLowerCase());

      lowercasePool.put(string, newString);
      lowercasePoolSize++;

      if(MyLog.enabled) {
        MyLog.d("[StringPool] new lowercase addition [" + newString + "]; pool size: " + lowercasePoolSize);
      }

      if (lowercasePoolSize >= maxPoolSize) {
        // clear pool to free memory and allow pool to rebuild
        MyLog.d("[StringPool] Clearing lowercase pool");
        lowercasePool.clear();
        lowercasePoolSize = 0;
      }

      return newString;
    } else {
      return result;
    }
  }
}

@@ -610,32 +610,156 @@
 %3E(maxPoolSize);%0A
+  final public static ConcurrentHashMap%3CInteger, String%3E integerPool = new ConcurrentHashMap%3CInteger, String%3E(maxPoolSize);%0A
   final public s
@@ -826,16 +826,16 @@
 Tree();%0A
-
   static
@@ -881,32 +881,66 @@
 sePoolSize = 0;%0A
+  static int integerPoolSize = 0;%0A
   static CharArr
@@ -1137,32 +1137,32 @@
 getPos());%0A  %7D%0A%0A
-
   public static 
@@ -1205,24 +1205,68 @@
 t length) %7B%0A
+    /* FIXME: remove need for charBuffer */%0A
     charBuff
@@ -2932,32 +2932,758 @@
 e = 0;%0A      %7D%0A%0A
+      return newString;%0A    %7D else %7B%0A      return result;%0A    %7D%0A  %7D%0A%0A  public static String get(Integer integer) %7B%0A    if(integer == null) %7B%0A      return %22%22;%0A    %7D%0A%0A    String result = integerPool.get(integer);%0A%0A    if(result == null) %7B%0A      String newString = String.valueOf(integer);%0A%0A      integerPool.put(integer, newString);%0A      integerPoolSize++;%0A%0A      if(MyLog.enabled) %7B%0A        MyLog.d(%22%5BStringPool%5D new integer addition %5B%22 + newString + %22%5D; pool size: %22 + integerPoolSize);%0A      %7D%0A%0A      if (integerPoolSize %3E= maxPoolSize) %7B%0A        // clear pool to free memory and allow pool to rebuild%0A        MyLog.d(%22%5BStringPool%5D Clearing integer pool%22);%0A        integerPool.clear();%0A        integerPoolSize = 0;%0A      %7D%0A%0A
       return new

Add Integer->String map to StringPool to optimize Integer->String parsing