1 package com.ctc.wstx.util;
2
3 import java.util.LinkedHashMap;
4 import java.util.Map;
5
6 /**
7 * Singleton class that implements "fast intern" functionality, essentially
8 * adding a layer that caches Strings that have been previously intern()ed,
9 * but that probably shouldn't be added to symbol tables.
10 * This is usually used by improving intern()ing of things like namespace
11 * URIs.
12 *<p>
13 * Note: that this class extends {@link LinkedHashMap} is an implementation
14 * detail -- no code should ever directly call Map methods.
15 */
16 @SuppressWarnings("serial")
17 public final class InternCache extends LinkedHashMap<String,String>
18 {
19 /**
20 * Let's create cache big enough to usually have enough space for
21 * all entries... (assuming NS URIs only)
22 */
23 private final static int DEFAULT_SIZE = 64;
24
25 /**
26 * Let's limit to hash area size of 1024.
27 */
28 private final static int MAX_SIZE = 660;
29
30 private final static InternCache sInstance = new InternCache();
31
32 private InternCache() {
33 /* Let's also try to seriously minimize collisions... since
34 * collisions are likely to be more costly here, with longer
35 * Strings; so let's use 2/3 ratio (67%) instead of default
36 * (75%)
37 */
38 super(DEFAULT_SIZE, 0.6666f, false);
39 }
40
41 public static InternCache getInstance() {
42 return sInstance;
43 }
44
45 public String intern(String input)
46 {
47 String result;
48
49 /* Let's split sync block to help in edge cases like
50 * [WSTX-220]
51 */
52 synchronized (this) {
53 result = get(input);
54 }
55 if (result == null) {
56 result = input.intern();
57 synchronized (this) {
58 put(result, result);
59 }
60 }
61 return result;
62 }
63
64 // We will force maximum size here (for [WSTX-237])
65 @Override protected boolean removeEldestEntry(Map.Entry<String,String> eldest)
66 {
67 return size() > MAX_SIZE;
68 }
69 }
70
71