/* (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 ConcurrentHashMap<Integer, String> integerPool = new ConcurrentHashMap<Integer, String>(maxPoolSize);
  final public static CharArrayStringAATree charPool = new CharArrayStringAATree();
  static int poolSize = 0;
  static int lowercasePoolSize = 0;
  static int integerPoolSize = 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) {
    /* FIXME: remove need for charBuffer */
    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;
    }
  }

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

    String result = integerPool.get(integer);

    if(result == null) {
      String newString = String.valueOf(integer);

      integerPool.put(integer, newString);
      integerPoolSize++;

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

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

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

@@ -973,11 +973,8 @@
 ray(
-256
 );%0A%0A
@@ -1113,17 +1113,34 @@
 .get
-Data(), 0
+Value(), chars.getOffset()
 , ch
@@ -1150,11 +1150,14 @@
 .get
-Pos
+Length
 ());
@@ -1207,19 +1207,22 @@
 rs, int 
-pos
+offset
 , int le
@@ -1237,34 +1237,21 @@
     
-/* FIXME: remove need for 
+synchronized(
 char
@@ -1256,20 +1256,22 @@
 arBuffer
- */%0A
+) %7B%0A  
     char
@@ -1281,46 +1281,24 @@
 fer.
-re
 set
-();%0A    charBuffer.append
+Value
 (chars, 
 pos,
@@ -1297,11 +1297,14 @@
 rs, 
-pos
+offset
 , le
@@ -1307,24 +1307,26 @@
 , length);%0A%0A
+  
     if (char
@@ -1359,24 +1359,26 @@
 ze) %7B%0A      
+ 
+ 
 // clear poo
@@ -1422,24 +1422,26 @@
 build%0A      
+  
 MyLog.d(%22%5BSt
@@ -1473,24 +1473,26 @@
 ol%22);%0A      
+ 
+ 
 charPool.cle
@@ -1501,23 +1501,27 @@
 ();%0A    
+  
 %7D%0A%0A    
+ 
+ 
 return c
@@ -1548,16 +1548,22 @@
 uffer);%0A
+    %7D%0A
   %7D%0A%0A  p

Optimize away need to copy char[] value into CharArray by using new CharArray.setValue() semantics Synchronize access to charBuffer