• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
StringBuilderPool()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 
getStringBuilder(final int initialSize)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 
recycle(final StringBuilder garbage)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 
ensureCapacity(final int capacity, final int initialSize)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 
getSize()67     public static int getSize() {
68         return sInstance.mPool.size();
69     }
70 }
71