/******************************************************************************* * Copyright (c) 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.xml.core.internal.document; import java.util.LinkedHashMap; /** * Organizes a pool of frequently used Strings as character arrays. * */ final class CharacterStringPool { static private LinkedHashMap fPool = new LimitedHashMap(); static private class LimitedHashMap extends LinkedHashMap { private static final long serialVersionUID = 1L; private static final int MAX = 500; public LimitedHashMap() { super(MAX / 10, .75f, true); } protected boolean removeEldestEntry(java.util.Map.Entry eldest) { return size() > MAX; } } static private class CharArray { char[] fArray; /** * Answers a hashcode for the array. Algorithm from org.eclipse.jdt.core.compiler.CharOperation * * @param array the array for which a hashcode is required * @return the hashcode * @throws NullPointerException if array is null */ public int hashCode() { int length = fArray.length; int hash = length == 0 ? 31 : fArray[0]; if (length < 8) { for (int i = length; --i > 0;) hash = (hash * 31) + fArray[i]; } else { // 8 characters is enough to compute a decent hash code, don't waste time examining every character for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2) hash = (hash * 31) + fArray[i]; } return hash & 0x7FFFFFFF; } public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof CharArray)) return false; CharArray other = (CharArray) obj; if (fArray.length != other.fArray.length) return false; for (int i = 0; i < fArray.length; i++) { if (fArray[i] != other.fArray[i]) return false; } return true; } } private CharacterStringPool() { } /** * Returns the character array for <code>string</code>. If * the character array is already in the pool for character arrays, * the array is reused. * * @param string the string to retrieve the character array for * @return a pooled instance of the character array */ public static char[] getCharString(String string) { CharArray array = new CharArray(); array.fArray = string.toCharArray(); Object obj = null; synchronized (fPool) { obj = fPool.get(array); if (obj == null) { obj = array; fPool.put(obj, obj); } } return ((CharArray) obj).fArray; } }