You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2010/05/06 14:24:39 UTC
svn commit: r941693 -
/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/StringCache.java
Author: thomasm
Date: Thu May 6 12:24:39 2010
New Revision: 941693
URL: http://svn.apache.org/viewvc?rev=941693&view=rev
Log:
A string cache (may or may not be used)
Added:
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/StringCache.java
Added: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/StringCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/StringCache.java?rev=941693&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/StringCache.java (added)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/StringCache.java Thu May 6 12:24:39 2010
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.j3.util;
+
+import java.lang.ref.SoftReference;
+
+/**
+ * A few String utility functions.
+ */
+public class StringCache {
+
+ public static final boolean OBJECT_CACHE = getBooleanSetting("j3.objectCache", true);
+ public static final int OBJECT_CACHE_SIZE = nextPowerOf2(getIntSetting("j3.objectCacheSize", 1024));
+
+ private static SoftReference<String[]> softCache = new SoftReference<String[]>(null);
+
+ private StringCache() {
+ // utility class
+ }
+
+ private static int nextPowerOf2(int x) {
+ long i = 1;
+ while (i < x && i < (Integer.MAX_VALUE / 2)) {
+ i += i;
+ }
+ return (int) i;
+ }
+
+ private static boolean getBooleanSetting(String name, boolean defaultValue) {
+ String s = getProperty(name);
+ if (s != null) {
+ try {
+ return Boolean.valueOf(s).booleanValue();
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return defaultValue;
+ }
+
+ private static int getIntSetting(String name, int defaultValue) {
+ String s = getProperty(name);
+ if (s != null) {
+ try {
+ return Integer.decode(s).intValue();
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ return defaultValue;
+ }
+
+ private static String getProperty(String name) {
+ try {
+ return System.getProperty(name);
+ } catch (Exception e) {
+ // SecurityException
+ // applets may not do that - ignore
+ return null;
+ }
+ }
+
+ private static String[] getCache() {
+ String[] cache;
+ // softCache can be null due to a Tomcat problem
+ // a workaround is disable the system property org.apache.
+ // catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES
+ if (softCache != null) {
+ cache = softCache.get();
+ if (cache != null) {
+ return cache;
+ }
+ }
+ try {
+ cache = new String[OBJECT_CACHE_SIZE];
+ } catch (OutOfMemoryError e) {
+ return null;
+ }
+ softCache = new SoftReference<String[]>(cache);
+ return cache;
+ }
+
+ /**
+ * Get the string from the cache if possible. If the string has not been
+ * found, it is added to the cache. If there is such a string in the cache,
+ * that one is returned.
+ *
+ * @param s the original string
+ * @return a string with the same content, if possible from the cache
+ */
+ public static String cache(String s) {
+ if (!OBJECT_CACHE) {
+ return s;
+ }
+ if (s == null) {
+ return s;
+ } else if (s.length() == 0) {
+ return "";
+ }
+ int hash = s.hashCode();
+ String[] cache = getCache();
+ if (cache != null) {
+ int index = hash & (OBJECT_CACHE_SIZE - 1);
+ String cached = cache[index];
+ if (cached != null) {
+ if (s.equals(cached)) {
+ return cached;
+ }
+ }
+ cache[index] = s;
+ }
+ return s;
+ }
+
+ /**
+ * Get a string from the cache, and if no such string has been found, create
+ * a new one with only this content. This solves out of memory problems if
+ * the string is a substring of another, large string. In Java, strings are
+ * shared, which could lead to memory problems. This avoid such problems.
+ *
+ * @param s the string
+ * @return a string that is guaranteed not be a substring of a large string
+ */
+ public static String fromCacheOrNew(String s) {
+ if (!OBJECT_CACHE) {
+ return s;
+ }
+ if (s == null) {
+ return s;
+ } else if (s.length() == 0) {
+ return "";
+ }
+ int hash = s.hashCode();
+ String[] cache = getCache();
+ int index = hash & (OBJECT_CACHE_SIZE - 1);
+ if (cache == null) {
+ return s;
+ }
+ String cached = cache[index];
+ if (cached != null) {
+ if (s.equals(cached)) {
+ return cached;
+ }
+ }
+ // create a new object that is not shared
+ // (to avoid out of memory if it is a substring of a big String)
+ // NOPMD
+ s = new String(s);
+ cache[index] = s;
+ return s;
+ }
+
+ /**
+ * Clear the cache. This method is used for testing.
+ */
+ public static void clearCache() {
+ softCache = new SoftReference<String[]>(null);
+ }
+
+}