1a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson/* 2a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * Copyright (C) 2010 The Android Open Source Project 3a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * 4a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * you may not use this file except in compliance with the License. 6a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * You may obtain a copy of the License at 7a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * 8a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * 10a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * Unless required by applicable law or agreed to in writing, software 11a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * See the License for the specific language governing permissions and 14a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * limitations under the License. 15a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson */ 16a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 17a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilsonpackage libcore.internal; 18a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 19a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson/** 20a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * A pool of string instances. Unlike the {@link String#intern() VM's 21a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * interned strings}, this pool provides no guarantee of reference equality. 22a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * It is intended only to save allocations. This class is not thread safe. 23a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson */ 24a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilsonpublic final class StringPool { 25a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 26a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson private final String[] pool = new String[512]; 27a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 28892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne private static boolean contentEquals(String s, char[] chars, int start, int length) { 29892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne if (s.length() != length) { 30892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne return false; 31892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne } 32892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne for (int i = 0; i < length; i++) { 33892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne if (chars[start + i] != s.charAt(i)) { 34892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne return false; 35892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne } 36892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne } 37892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne return true; 38892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne } 39892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne 40a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson /** 41a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson * Returns a string equal to {@code new String(array, start, length)}. 42a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson */ 43a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson public String get(char[] array, int start, int length) { 44a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson // Compute an arbitrary hash of the content 45a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson int hashCode = 0; 46a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson for (int i = start; i < start + length; i++) { 47a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson hashCode = (hashCode * 31) + array[i]; 48a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson } 49a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 50a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson // Pick a bucket using Doug Lea's supplemental secondaryHash function (from HashMap) 51a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12); 52a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson hashCode ^= (hashCode >>> 7) ^ (hashCode >>> 4); 53a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson int index = hashCode & (pool.length - 1); 54a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 55a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson String pooled = pool[index]; 56892c36b1c1eee25ad46bac6fffdf129219a5e98dPhilip Milne if (pooled != null && contentEquals(pooled, array, start, length)) { 57a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson return pooled; 58a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson } 59a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson 60a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson String result = new String(array, start, length); 61a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson pool[index] = result; 62a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson return result; 63a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson } 64a78c2aac2a73f001aa00971adfae90af4d6726fbJesse Wilson} 65