diff src/org/eclipse/jetty/io/StringCache.java @ 1022:3718afd99988

HttpHeaders uses StringCache
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 01 Nov 2016 01:04:46 -0600
parents 6be43ef1eb96
children 27f3dc761452
line wrap: on
line diff
--- a/src/org/eclipse/jetty/io/StringCache.java	Mon Oct 31 22:49:25 2016 -0600
+++ b/src/org/eclipse/jetty/io/StringCache.java	Tue Nov 01 01:04:46 2016 -0600
@@ -2,18 +2,22 @@
 
 package org.eclipse.jetty.io;
 
+import java.util.Map;
 import java.util.HashMap;
-import java.util.Map;
+import java.util.TreeMap;
 import org.eclipse.jetty.util.StringUtil;
 
 
 public final class StringCache {
 	private final Map<String,Integer> stringToOrdinal = new HashMap<String,Integer>();
 //	private final Map<Integer,String> ordinalToString = new HashMap<Integer,String>();
+	private final TreeMap<String,String> stringMap = new TreeMap<String,String>();
 
 	public byte[] add(String value, int ordinal) {
-		stringToOrdinal.put(value.toLowerCase(), ordinal);
+		String valueLower = value.toLowerCase();
+		stringToOrdinal.put(valueLower, ordinal);
 //		ordinalToString.put(ordinal, value);
+		stringMap.put(valueLower,value);
 		return StringUtil.getBytes(value);
 	}
 
@@ -25,4 +29,29 @@
 	public boolean contains(String value) {
 		return stringToOrdinal.containsKey(value.toLowerCase());
 	}
+
+	public String getBest(String key) {
+		key = key.toLowerCase();
+		String rtn = stringMap.get(key);
+		if( rtn != null )
+			return rtn;
+		Map.Entry<String,String> floor = stringMap.floorEntry(key);
+		Map.Entry<String,String> ceiling = stringMap.ceilingEntry(key);
+		if( floor==null ) {
+			if( ceiling==null )
+				return null;
+			String ceilingKey = ceiling.getKey();
+			return key.charAt(0) == ceilingKey.charAt(0) ? ceiling.getValue() : null;
+		} else {
+			String floorKey = (String)floor.getKey();
+			if( ceiling==null )
+				return key.charAt(0) == floorKey.charAt(0) ? floor.getValue() : null;
+			String ceilingKey = ceiling.getKey();
+			int n = Math.min( key.length(), Math.min( floorKey.length(), ceilingKey.length() ) );
+			int i = 0;
+			while( ++i <= n && key.regionMatches(0,floorKey,0,i) && key.regionMatches(0,ceilingKey,0,i) );
+			return key.regionMatches(0,floorKey,0,i) ? floor.getValue() : key.regionMatches(0,ceilingKey,0,i) || i > 1 ? ceiling.getValue() : null;
+		}
+	}
+
 }