Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.android.inputmethod.latin;
     18 
     19 import java.util.ArrayList;
     20 import java.util.Collections;
     21 import java.util.List;
     22 
     23 /**
     24  * A pool of string builders to be used from anywhere.
     25  */
     26 public class StringBuilderPool {
     27     // Singleton
     28     private static final StringBuilderPool sInstance = new StringBuilderPool();
     29     private static final boolean DEBUG = false;
     30     private StringBuilderPool() {}
     31     // TODO: Make this a normal array with a size of 20, or a ConcurrentQueue
     32     private final List<StringBuilder> mPool =
     33             Collections.synchronizedList(new ArrayList<StringBuilder>());
     34 
     35     public static StringBuilder getStringBuilder(final int initialSize) {
     36         // TODO: although the pool is synchronized, the following is not thread-safe.
     37         // Two threads entering this at the same time could take the same size of the pool and the
     38         // second to attempt removing this index from the pool would crash with an
     39         // IndexOutOfBoundsException.
     40         // At the moment this pool is only used in Suggest.java and only in one thread so it's
     41         // okay. The simplest thing to do here is probably to replace the ArrayList with a
     42         // ConcurrentQueue.
     43         final int poolSize = sInstance.mPool.size();
     44         final StringBuilder sb = poolSize > 0 ? (StringBuilder) sInstance.mPool.remove(poolSize - 1)
     45                 : new StringBuilder(initialSize);
     46         sb.setLength(0);
     47         return sb;
     48     }
     49 
     50     public static void recycle(final StringBuilder garbage) {
     51         if (DEBUG) {
     52             final int gid = garbage.hashCode();
     53             for (final StringBuilder q : sInstance.mPool) {
     54                 if (gid == q.hashCode()) throw new RuntimeException("Duplicate id " + gid);
     55             }
     56         }
     57         sInstance.mPool.add(garbage);
     58     }
     59 
     60     public static void ensureCapacity(final int capacity, final int initialSize) {
     61         for (int i = sInstance.mPool.size(); i < capacity; ++i) {
     62             final StringBuilder sb = new StringBuilder(initialSize);
     63             sInstance.mPool.add(sb);
     64         }
     65     }
     66 
     67     public static int getSize() {
     68         return sInstance.mPool.size();
     69     }
     70 }
     71