You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by si...@apache.org on 2009/11/20 04:33:18 UTC

svn commit: r882400 - in /labs/magma/trunk: foundation-basics/src/main/java/org/apache/magma/basics/context/ foundation-basics/src/main/java/org/apache/magma/settings/ foundation-basics/src/test/java/org/apache/magma/settings/ foundation-i18n/src/main/...

Author: simoneg
Date: Fri Nov 20 03:33:15 2009
New Revision: 882400

URL: http://svn.apache.org/viewvc?rev=882400&view=rev
Log:
LABS-365 LABS-494 : moved context based settings to foundation-basice

Added:
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java
    labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/
    labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java
    labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java
Removed:
    labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/ContextMatrix.java
    labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nContextElement.java
    labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nContextElementsInstall.aj
    labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nMultiSegmentContextElement.java
    labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/I18nSingleSegmentContextElement.java
    labs/magma/trunk/foundation-i18n/src/test/java/org/apache/magma/i18n/LocaleHolderTest.java
    labs/magma/trunk/foundation-i18n/src/test/java/org/apache/magma/i18n/MatchingTest.java
Modified:
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java
    labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java
    labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java

Modified: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java (original)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/ClassContextElement.java Fri Nov 20 03:33:15 2009
@@ -21,9 +21,10 @@
  *
  * @author Simone Gianni <si...@apache.org>
  */
-public class ClassContextElement implements ContextElement {
+public class ClassContextElement implements ContextElement, SingleSegmentContextElement {
 
-	public Class<?> myclass = null;
+	protected Class<?> myclass = null;
+	protected String mytos = null;
 	
 	public ClassContextElement(Class<?> myclass) {
 		this.myclass = myclass;
@@ -31,7 +32,9 @@
 	
 	@Override
 	public String toString() {
-		return myclass.getSimpleName();
+		if (mytos == null)
+			mytos = myclass.getSimpleName();
+		return mytos;
 	}
 	
 	@Override
@@ -39,4 +42,8 @@
 		if (!(obj instanceof ClassContextElement)) return false;
 		return ((ClassContextElement)obj).myclass == myclass;
 	}
+
+	public String getSegment() {
+		return toString();
+	}
 }

Modified: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java (original)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MethodContextElement.java Fri Nov 20 03:33:15 2009
@@ -24,10 +24,11 @@
  *
  * @author Simone Gianni <si...@apache.org>
  */
-public class MethodContextElement implements ContextElement {
+public class MethodContextElement implements ContextElement, MultipleSegmentContextElement {
 
-	private Method method = null;
-	private Object[] args = null;
+	protected Method method = null;
+	protected Object[] args = null;
+	protected String[] mytos = null; 
 	
 	public MethodContextElement(Method method, Object[] args) {
 		this.method = method;
@@ -56,5 +57,11 @@
 	public Object[] getArgs() {
 		return args;
 	}
+
+	public String[] getSegments() {
+		if (mytos == null) 
+			mytos = new String[] { method.getDeclaringClass().getSimpleName() , method.getName() };			
+		return mytos;
+	}
 	
 }

Added: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java?rev=882400&view=auto
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java (added)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/MultipleSegmentContextElement.java Fri Nov 20 03:33:15 2009
@@ -0,0 +1,7 @@
+package org.apache.magma.basics.context;
+
+public interface MultipleSegmentContextElement extends ContextElement {
+
+	public String[] getSegments();
+	
+}

Added: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java?rev=882400&view=auto
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java (added)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/SingleSegmentContextElement.java Fri Nov 20 03:33:15 2009
@@ -0,0 +1,7 @@
+package org.apache.magma.basics.context;
+
+public interface SingleSegmentContextElement extends ContextElement {
+	
+	public String getSegment();
+ 
+}

Modified: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java (original)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/basics/context/StringContextElement.java Fri Nov 20 03:33:15 2009
@@ -21,7 +21,7 @@
  *
  * @author Simone Gianni <si...@apache.org>
  */
-public class StringContextElement implements ContextElement {
+public class StringContextElement implements ContextElement, SingleSegmentContextElement {
 
 	public CharSequence mystring = null;
 	
@@ -39,5 +39,9 @@
 		if (!(obj instanceof StringContextElement)) return false;
 		return ((StringContextElement)obj).mystring.equals(mystring);
 	}
+
+	public String getSegment() {
+		return toString();
+	}
 	
 }

Added: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java?rev=882400&view=auto
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java (added)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/ContextSettingsHolder.java Fri Nov 20 03:33:15 2009
@@ -0,0 +1,184 @@
+package org.apache.magma.settings;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.magma.basics.context.ContextElement;
+import org.apache.magma.basics.context.MultipleSegmentContextElement;
+import org.apache.magma.basics.context.RunningContext;
+import org.apache.magma.basics.context.SingleSegmentContextElement;
+import org.apache.magma.basics.context.SubRunningContext;
+
+/**
+ * Settings holder that fetch settings based on the current context.
+ * 
+ * <p>
+ * Each context is reduced to a collection of strings, using
+ * {@link SingleSegmentContextElement#getSegment()} or
+ * {@link MultipleSegmentContextElement#getSegments()}.
+ * </p>
+ * 
+ * <p>
+ * So for example, in a typical web application, we have a context
+ * like "html RootWebHandler handleSomething doSomething Form BeanName".
+ * </p>
+ * 
+ * <p>
+ * Each settings is expected to be composed of a number of segments,
+ * separated by a dot. Like for example :
+ * <pre>
+ * Form.style=something
+ * Form.BeanName.style=something else
+ * </pre>
+ * </p>
+ * 
+ * <p>
+ * The last segment is the real property name. So, when the property "style"
+ * is evaluated in a context containing "Form", it will evaluate so "something", while
+ * if the context contains "Form" followed (immediately or not) by "BeanName" then
+ * it will evaluate to "something else".
+ * </p>
+ * 
+ * @author Simone Gianni <si...@apache.org>
+ */
+public class ContextSettingsHolder extends SettingsHolder {
+
+	protected static final String CACHE_NONE = "___NONE___";
+		
+	protected Map<String, String> cache = new HashMap<String, String>();
+	protected Map<String, List<String[]>> firstLookup = new HashMap<String, List<String[]>>();
+	
+	@Override
+	public synchronized void inited() {
+		buildMatrix();
+		super.inited();
+	}
+	
+	/**
+	 * Builds an inverted lookup table to speed up key resolution.
+	 */
+	protected void buildMatrix() {
+		for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+			String[] parts = tokenize((String)entry.getKey(), (String)entry.getValue());
+			String discriminator = parts[parts.length - 2];
+			List<String[]> list = firstLookup.get(discriminator);
+			if (list == null) {
+				list = new ArrayList<String[]>();
+				firstLookup.put(discriminator, list);
+			}
+			list.add(parts);
+		}
+	}
+	
+	protected static String[] tokenize(String key, String value) {
+		String[] parts = key.split("\\.");
+		parts = Arrays.copyOf(parts, parts.length + 1);
+		parts[parts.length - 1] = value;
+		return parts;
+	}
+	
+	@Override
+	public String get(String name) {
+		return get(RunningContext.get(), name);
+	}
+	
+	/**
+	 * Gets the translation for the given string and the given context. 
+	 * 
+	 * The context is usually a {@link SubRunningContext} instance.
+	 * 
+	 * @param ct A stack of elements representing the context.
+	 * @param original The original string to translate.
+	 * @return The translation or the original string if no translation found.
+	 */
+	public String get(Stack<ContextElement> ct, String property) {
+		List<String[]> list = firstLookup.get(property);
+		// Fast not found case
+		if (list == null || list.size() == 0) return null;
+		
+		// Fast found xxxx=yyyyy case
+		if (list.size() == 1) {
+			if (list.get(0).length == 2) {
+				return list.get(0)[1];
+			}
+		}
+		
+		String[] strings = stringify(ct);
+		StringBuilder keysb = new StringBuilder();
+		for (String string : strings) {
+			keysb.append(string);
+			keysb.append('.');
+		}
+		String key = keysb.toString();
+		String winner = cache.get(key);
+		if (winner == CACHE_NONE) return null;
+		if (winner == null) {
+			int topscore = -1;
+			for (String[] cm : list) {
+				int score = getScore(cm, strings);
+				if (score > topscore) {
+					topscore = score;
+					winner = cm[cm.length - 1];
+				}
+			}
+			//ct.pop();
+			if (winner == null) {
+				cache.put(key, CACHE_NONE);
+				return null;
+			} else {
+				cache.put(key, winner);
+			}
+		}
+		return winner;
+	}
+	
+	/**
+	 * Checks the score of two string arrays.
+	 * @param parts The keys in the property file
+	 * @param mc The keys of the context
+	 * @return -1 for no match, 0 for one step match (x=y), increasingly higher score for more in depth match
+	 */
+	protected static int getScore(String[] parts, String[] mc) {
+		if (parts.length == 2) return 0;
+		int total = -1;
+		int upto = 0;
+		int pos = 1;
+		for (String seg : mc) {
+			pos++;
+			if (parts[upto].equalsIgnoreCase(seg)) {
+				upto++;
+				total += pos;
+				if (upto == parts.length - 2) return total;
+			}
+		}
+		return -1;		
+	}
+
+	/**
+	 * Converts a stack of context elements to an array of strings.
+	 * @param ct The stack of the current context
+	 * @return A string array, interpreting {@link I18nMultiSegmentContextElement} with correct elements
+	 */
+	protected static String[] stringify(Stack<ContextElement> ct) {
+		String[] ret = new String[ct.size() * 2];
+		int i = 0;
+		for (ContextElement ele : ct) {
+			if (ele instanceof SingleSegmentContextElement) {
+				String seg = ((SingleSegmentContextElement)ele).getSegment();
+				ret[i++] = seg;
+			} else if (ele instanceof MultipleSegmentContextElement) {
+				String[] segs = ((MultipleSegmentContextElement)ele).getSegments();
+				for (String seg : segs) {
+					ret[i++] = seg;
+				}
+			}
+		}
+		ret = Arrays.copyOf(ret, i);
+		return ret;
+	}
+	
+}

Modified: labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java (original)
+++ labs/magma/trunk/foundation-basics/src/main/java/org/apache/magma/settings/SettingsHolder.java Fri Nov 20 03:33:15 2009
@@ -40,9 +40,9 @@
  */
 public class SettingsHolder {
 
-	private Properties properties = new Properties();
-	private volatile boolean initing = false;
-	private volatile boolean inited = false;
+	protected Properties properties = new Properties();
+	protected volatile boolean initing = false;
+	protected volatile boolean inited = false;
 	
 	public synchronized boolean isInited() {
 		return inited;
@@ -54,6 +54,8 @@
 				wait(1000);
 			} catch (InterruptedException e) {
 			}
+		} else {
+			initing = true;
 		}
 	}
 	

Added: labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java?rev=882400&view=auto
==============================================================================
--- labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java (added)
+++ labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/ContextSettingsHolderTest.java Fri Nov 20 03:33:15 2009
@@ -0,0 +1,109 @@
+package org.apache.magma.settings;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.apache.magma.settings.ContextSettingsHolder.stringify;
+import static org.apache.magma.settings.ContextSettingsHolder.tokenize;
+import static org.apache.magma.settings.ContextSettingsHolder.getScore;
+
+import java.lang.reflect.Method;
+import java.util.Stack;
+
+import org.apache.magma.basics.context.ContextElement;
+import org.apache.magma.basics.context.MethodContextElement;
+import org.apache.magma.basics.context.RunningContext;
+import org.apache.magma.basics.context.StringContextElement;
+import org.apache.magma.basics.context.SubRunningContext;
+import org.junit.After;
+import org.junit.Test;
+
+
+public class ContextSettingsHolderTest {
+
+	@Test
+	public void stringifyTest() throws Exception {
+		Stack<ContextElement> elements = new Stack<ContextElement>();
+		elements.push(new StringContextElement("text"));
+		Method m = ContextSettingsHolderTest.class.getMethod("stringifyTest");
+		elements.push(new MethodContextElement(m, new Object[0]));
+		
+		String[] strings = stringify(elements);
+		assertThat(strings[0], equalTo("text"));
+		assertThat(strings[1], equalTo(ContextSettingsHolderTest.class.getSimpleName()));
+		assertThat(strings[2], equalTo("stringifyTest"));
+	}	
+	
+	@SuppressWarnings("deprecation")
+	@After
+	public void cleanupRunningContext() {
+		RunningContext.cleanup();
+	}
+	
+	
+	@Test
+	public void simpleCompleteMatching() throws Exception {
+		SubRunningContext mc = RunningContext.get();
+		mc.push(getClass());
+		
+		int score = getScore(tokenize(getClass().getSimpleName() + ".test", "test"), stringify(mc));
+		assertThat(score, equalTo(1));
+	}
+
+	@Test
+	public void simplePartialMatching() throws Exception {
+		SubRunningContext mc = RunningContext.get();
+		mc.push(getClass());
+		
+		int score = getScore(tokenize("test", "test"),stringify(mc));
+		assertTrue("Expected a match", score > -1);		
+	}
+	
+	@Test
+	public void simpleNotMatching() throws Exception {
+		SubRunningContext mc = RunningContext.get();
+		int score = getScore(tokenize(getClass().getSimpleName() + ".test", "test"),stringify(mc));
+		assertThat(score, equalTo(-1));		
+	}
+	
+	@Test
+	public void simpleJumpingMatch() throws Exception {
+		SubRunningContext mc = RunningContext.get();
+		mc.push("testingthejump");
+		mc.push(getClass());
+		
+		int score = getScore(tokenize("testingthejump.test", "test"),stringify(mc));
+		assertTrue("Expected a match", score > -1);		
+	}
+	
+	@Test
+	public void betterMatch() throws Exception {
+		SubRunningContext mc = RunningContext.get();
+		mc.push("testingthejump");
+		mc.push(getClass());
+		
+		int score1 = getScore(tokenize("testingthejump.test", "test"),stringify(mc));
+		int score2 = getScore(tokenize("test", "test"),stringify(mc));
+		assertTrue(score1 + " is not > than " + score2, score1 > score2);		
+	}
+	
+	@Test
+	public void betterMatchAsPerBug184() throws Exception {
+		SubRunningContext mc = RunningContext.get();
+		mc.push("BahHtmlProducer");
+		mc.push("BeanFormProducer");
+		mc.push("UserBean");
+		mc.push("BeanFormProducer");
+		mc.push("UserBean");
+		mc.push("field1");
+		mc.push("field1");
+		mc.push("field2");
+		mc.push("field2");
+		mc.push("field2");
+		
+		int score1 = getScore(tokenize("UserBean.field2.key", "key"), stringify(mc));
+		int score2 = getScore(tokenize("UserBean.field1.key", "key"), stringify(mc));
+		assertTrue(score1 + " is not > than " + score2, score1 > score2);		
+	}
+	
+}

Added: labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java?rev=882400&view=auto
==============================================================================
--- labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java (added)
+++ labs/magma/trunk/foundation-basics/src/test/java/org/apache/magma/settings/PerformanceTest.java Fri Nov 20 03:33:15 2009
@@ -0,0 +1,170 @@
+package org.apache.magma.settings;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Stack;
+
+import org.apache.magma.basics.context.ClassContextElement;
+import org.apache.magma.basics.context.ContextElement;
+import org.apache.magma.basics.context.MethodContextElement;
+import org.apache.magma.basics.context.StringContextElement;
+import org.apache.magma.settings.SettingsHolder;
+import org.junit.Test;
+
+import static junit.framework.Assert.*;
+
+
+public class PerformanceTest {
+
+	
+	@Test
+	public void globalTest() throws Exception {
+		// Fill with a big number of possible permutations
+		ContextSettingsHolder lh = new ContextSettingsHolder();
+		
+		String[] elements = new String[] { "ajax", "String", "charAt", "ContextSettingsHolder", "inited", "Stack" };
+		for (int i = 4; i <= 255; i++) {
+			String ele = "";
+			for (int k = 0; k < elements.length; k++) {
+				boolean add = (i & (1 << (k + 2))) != 0;
+				if (add) 
+					ele += elements[k] + ".";
+			}
+			if ((i & 1) != 0) {
+				ele += "notfound.";
+			}
+			if ((i & 2) != 0) {
+				ele += "correct";
+			} else {
+				ele += "incorrect";
+			}
+			lh.override(ele, "ele " + i);
+		}
+		lh.inited();
+	
+		List<Stack<ContextElement>> contexts = generateContexts();
+		
+		// Time checking contexts agains the matrix
+		NanoTimer nt = new NanoTimer();
+		String ret = null;
+		int positives = 0;
+		int negatives = 0;
+		for (int i = 0; i < 1000000; i++) {
+			Stack<ContextElement> stack = contexts.get(i % contexts.size());
+			nt.start();
+			ret = lh.get(stack, "correct");
+			nt.stop(1);
+			if (ret == null) {
+				negatives++;
+			} else {
+				positives++;
+			}
+			if (i == 10000) {
+				// ramp up
+				//System.out.println(nt.status());
+				//System.out.println("Ramped up");
+				nt = new NanoTimer();
+			} else if (i > 10000 && i % 1000 == 0) {
+				//System.out.println(nt.status());
+				nt.reset();
+			}
+			if (i > 10000 && i % 2000 == 0) {
+				//System.out.println("Regenerating");
+				contexts = generateContexts();
+			}
+		}
+		System.out.println(nt.totals());
+		System.out.println("Positives : " + positives + "   Negatives : " + negatives);
+		System.out.println("Cache size : " + lh.cache.size());
+		assertEquals(600001, positives);
+		assertEquals(399999, negatives);
+		assertTrue("Poor performances", nt.totalIterationsPerSecond() > 150000d);
+	}
+	
+	
+	static class NanoTimer {
+		private static double nanosInSecond = Math.pow(10, 9);
+		private long accumulated;
+		private long iterations;
+		
+		private long totalacc;
+		private long totaliter;
+		
+		private long start;
+		
+		public void start() {
+			start = System.nanoTime();
+		}
+		public void stop(int iterations) {
+			long elaps = System.nanoTime() - start;
+			accumulated += elaps; 
+			this.iterations += iterations;
+			totaliter += iterations;
+			totalacc += elaps;
+		}
+		public void reset() {
+			accumulated = 0;
+			iterations = 0;
+		}
+		public double nanosPerIteration() {
+			return (double)accumulated / (double)iterations;
+		}
+		public double iterationsPerSecond() {
+			return nanosInSecond / nanosPerIteration();
+		}
+		public String status() {
+			return "Avg : " + nanosPerIteration() + " n/i = " + iterationsPerSecond() + " ips";
+		}
+		public double totalIterationsPerSecond() {
+			double npi = (double)totalacc / (double)totaliter;
+			return nanosInSecond / npi;
+		}
+		
+		public String totals() {
+			double npi = (double)totalacc / (double)totaliter;
+			double ips = nanosInSecond / npi;
+			return "Total : " + npi + " n/i = " + ips + " ips   " + npi + "," + ips;
+		}
+	}
+	
+	private List<Stack<ContextElement>> generateContexts() throws Exception {
+		List<ContextElement> ce = new ArrayList<ContextElement>();
+		ce.add(new StringContextElement("ajax"));
+		Method m = String.class.getMethod("charAt", Integer.TYPE);
+		ce.add(new MethodContextElement(m, new Object[] { 1 }));
+		m = ContextSettingsHolder.class.getMethod("inited");
+		ce.add(new MethodContextElement(m, new Object[] {}));
+		ce.add(new ClassContextElement(Stack.class));
+		
+		List<Stack<ContextElement>> contexts = new ArrayList<Stack<ContextElement>>(15);
+		for (int i = 1; i <= 15; i++) {
+			Stack<ContextElement> ctx = new Stack<ContextElement>();
+			for (int k = 0; k < ce.size(); k++) {
+				boolean add = (i & (1 << k)) != 0;
+				if (add) 
+					ctx.push(ce.get(k));
+			}
+			contexts.add(ctx);
+		}
+		
+		ce = new ArrayList<ContextElement>();
+		ce.add(new StringContextElement("web"));
+		m = Integer.class.getMethod("compareTo", Integer.class);
+		ce.add(new MethodContextElement(m, new Object[] { 1 }));
+		m = SettingsHolder.class.getMethod("initing");
+		ce.add(new MethodContextElement(m, new Object[] {}));
+		ce.add(new ClassContextElement(Stack.class));		
+		for (int i = 1; i <= 50; i++) {
+			Stack<ContextElement> ctx = new Stack<ContextElement>();
+			for (int k = 0; k < ce.size(); k++) {
+				boolean add = (i & (1 << k)) != 0;
+				if (add) 
+					ctx.push(ce.get(k));
+			}
+			contexts.add(ctx);			
+		}
+		return contexts;
+	}
+}

Modified: labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java
URL: http://svn.apache.org/viewvc/labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java?rev=882400&r1=882399&r2=882400&view=diff
==============================================================================
--- labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java (original)
+++ labs/magma/trunk/foundation-i18n/src/main/java/org/apache/magma/i18n/LocaleHolder.java Fri Nov 20 03:33:15 2009
@@ -31,6 +31,7 @@
 
 import org.apache.magma.basics.context.ContextElement;
 import org.apache.magma.basics.context.SubRunningContext;
+import org.apache.magma.settings.ContextSettingsHolder;
 import org.apache.magma.settings.SettingsHolder;
 
 /**
@@ -43,14 +44,8 @@
  */
 public class LocaleHolder {
 
-	protected static final String CACHE_NONE = "___NONE___";
-	
 	protected Locale locale;
-	protected SettingsHolder messages = new SettingsHolder();
-	protected Map<String, String> cache = new HashMap<String, String>();
-	
-	
-	protected Map<String, List<String[]>> firstLookup = new HashMap<String, List<String[]>>();
+	protected ContextSettingsHolder messages = new ContextSettingsHolder();
 	
 	/**
 	 * Creates an instance
@@ -59,7 +54,6 @@
 	public LocaleHolder(Locale locale) {
 		this.locale = locale;		    
 	    initMessages();
-	    buildMatrix();
 	}
 
 	/**
@@ -114,25 +108,6 @@
 	}
 	
 	/**
-	 * Builds an inverted lookup table to speed up key resolution.
-	 */
-	public void buildMatrix() {
-		Map<String, String> all = messages.getAll();
-		for (Map.Entry<String, String> entry : all.entrySet()) {
-			String[] parts = entry.getKey().split("\\.");
-			parts = Arrays.copyOf(parts, parts.length + 1);
-			parts[parts.length - 1] = entry.getValue();
-			String discriminator = parts[parts.length - 2];
-			List<String[]> list = firstLookup.get(discriminator);
-			if (list == null) {
-				list = new ArrayList<String[]>();
-				firstLookup.put(discriminator, list);
-			}
-			list.add(parts);
-		}
-	}
-	
-	/**
 	 * Gets the translation for the given string and the given context. 
 	 * 
 	 * The context is usually a {@link SubRunningContext} instance.
@@ -143,93 +118,12 @@
 	 */
 	public String getMessage(Stack<ContextElement> ct, String original) {
 		String deh = normalize(original);
-		List<String[]> list = firstLookup.get(deh);
-		// Fast not found case
-		if (list == null || list.size() == 0) return original;
-		
-		// Fast found xxxx=yyyyy case
-		if (list.size() == 1) {
-			if (list.get(0).length == 2) {
-				return list.get(0)[1];
-			}
-		}
-		
-		String[] strings = stringify(ct);
-		StringBuilder keysb = new StringBuilder();
-		for (String string : strings) {
-			keysb.append(string);
-			keysb.append('.');
-		}
-		String key = keysb.toString();
-		String winner = cache.get(key);
-		if (winner == CACHE_NONE) return original;
-		if (winner == null) {
-			int topscore = -1;
-			for (String[] cm : list) {
-				int score = getScore(cm, strings);
-				if (score > topscore) {
-					topscore = score;
-					winner = cm[cm.length - 1];
-				}
-			}
-			//ct.pop();
-			if (winner == null) {
-				cache.put(key, CACHE_NONE);
-				return original;
-			} else {
-				cache.put(key, winner);
-			}
-		}
-		return winner;
-	}
-	
-	/**
-	 * Checks the score of two string arrays.
-	 * @param parts The keys in the property file
-	 * @param mc The keys of the context
-	 * @return -1 for no match, 0 for one step match (x=y), increasingly higher score for more in depth match
-	 */
-	protected static int getScore(String[] parts, String[] mc) {
-		if (parts.length == 1) return 0;
-		int total = -1;
-		int upto = 0;
-		int pos = 1;
-		for (String seg : mc) {
-			pos++;
-			if (parts[upto].equalsIgnoreCase(seg)) {
-				upto++;
-				total += pos;
-				if (upto == parts.length - 2) return total;
-			}
-		}
-		return -1;		
-	}
-
-	/**
-	 * Converts a stack of context elements to an array of strings.
-	 * @param ct The stack of the current context
-	 * @return A string array, interpreting {@link I18nMultiSegmentContextElement} with correct elements
-	 */
-	protected static String[] stringify(Stack<ContextElement> ct) {
-		String[] ret = new String[ct.size() * 2];
-		int i = 0;
-		for (ContextElement ele : ct) {
-			if (ele instanceof I18nContextElement) {
-				if (ele instanceof I18nSingleSegmentContextElement) {
-					String seg = ((I18nSingleSegmentContextElement)ele).getI18nSegment();
-					ret[i++] = seg;
-				} else {
-					String[] segs = ((I18nMultiSegmentContextElement)ele).getI18nSegments();
-					for (String seg : segs) {
-						ret[i++] = seg;
-					}
-				}
-			}
-		}
-		ret = Arrays.copyOf(ret, i);
+		String ret = messages.get(ct, deh);
+		if (ret == null) return original;
 		return ret;
 	}
 	
+	
 	/**
 	 * Transforms a string into a key.
 	 * 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org