1 52 53 package com.go.trove.io; 54 55 import java.io.*; 56 import java.util.*; 57 import com.go.trove.util.IdentityMap; 58 59 69 public class InternedCharToByteBuffer 70 implements CharToByteBuffer, Serializable 71 { 72 private static final int CACHES_PER_ENCODING = 11; 73 private static final int MIN_LENGTH = 4; 74 75 private static final Object MARKER = new Object (); 76 77 private static Map cEncodings = new HashMap(7); 78 79 private static Random cLastRandom = new Random(); 80 81 87 private static Map[] getConvertedCaches(String encoding) { 88 synchronized (cEncodings) { 89 Map[] caches = (Map[])cEncodings.get(encoding); 90 if (caches == null) { 91 caches = new Map[CACHES_PER_ENCODING]; 92 for (int i=0; i<CACHES_PER_ENCODING; i++) { 93 caches[i] = Collections.synchronizedMap(new IdentityMap()); 94 } 95 cEncodings.put(encoding, caches); 96 } 97 return caches; 98 } 99 } 100 101 private static Random getRandom() { 102 synchronized (cLastRandom) { 103 return cLastRandom = new Random(cLastRandom.nextLong()); 104 } 105 } 106 107 private CharToByteBuffer mBuffer; 108 private Random mRandom; 109 private transient Map[] mConvertedCaches; 110 111 public InternedCharToByteBuffer(CharToByteBuffer buffer) 112 throws IOException 113 { 114 mBuffer = buffer; 115 mConvertedCaches = getConvertedCaches(buffer.getEncoding()); 116 } 117 118 public void setEncoding(String enc) throws IOException { 119 mBuffer.setEncoding(enc); 120 mConvertedCaches = getConvertedCaches(mBuffer.getEncoding()); 121 } 122 123 public String getEncoding() throws IOException { 124 return mBuffer.getEncoding(); 125 } 126 127 public long getBaseByteCount() throws IOException { 128 return mBuffer.getBaseByteCount(); 129 } 130 131 public long getByteCount() throws IOException { 132 return mBuffer.getByteCount(); 133 } 134 135 public void writeTo(OutputStream out) throws IOException { 136 mBuffer.writeTo(out); 137 } 138 139 public void append(byte b) throws IOException { 140 mBuffer.append(b); 141 } 142 143 public void append(byte[] bytes) throws IOException { 144 mBuffer.append(bytes); 145 } 146 147 public void append(byte[] bytes, int offset, int length) 148 throws IOException { 149 150 mBuffer.append(bytes, offset, length); 151 } 152 153 public void appendSurrogate(ByteData s) throws IOException { 154 mBuffer.appendSurrogate(s); 155 } 156 157 public void addCaptureBuffer(ByteBuffer buffer) throws IOException { 158 mBuffer.addCaptureBuffer(buffer); 159 } 160 161 public void removeCaptureBuffer(ByteBuffer buffer) throws IOException { 162 mBuffer.removeCaptureBuffer(buffer); 163 } 164 165 public void append(char c) throws IOException { 166 mBuffer.append(c); 167 } 168 169 public void append(char[] chars) throws IOException { 170 mBuffer.append(chars); 171 } 172 173 public void append(char[] chars, int offset, int length) 174 throws IOException { 175 176 mBuffer.append(chars, offset, length); 177 } 178 179 public void append(String str) throws IOException { 180 Map cache; 181 if ((cache = getConvertedCache(str)) == null) { 182 mBuffer.append(str); 183 return; 184 } 185 186 190 Object value; 191 192 if ((value = cache.get(str)) != null) { 193 byte[] bytes; 194 if (value != MARKER) { 195 bytes = (byte[])value; 196 } 197 else { 198 String enc = getEncoding(); 201 if (enc != null) { 202 bytes = str.getBytes(enc); 203 } 204 else { 205 bytes = str.getBytes(); 207 } 208 cache.put(str, bytes); 209 } 210 211 mBuffer.append(bytes); 212 } 213 else { 214 if (mRandom == null) { 217 mRandom = getRandom(); 218 } 219 if ((mRandom.nextInt() % 20) == 0) { 220 cache.put(str, MARKER); 228 } 229 mBuffer.append(str); 230 } 231 } 232 233 public void append(String str, int offset, int length) throws IOException { 234 mBuffer.append(str, offset, length); 235 } 236 237 public void reset() throws IOException { 238 mBuffer.reset(); 239 } 240 241 public void drain() throws IOException { 242 mBuffer.drain(); 243 } 244 245 private Map getConvertedCache(String str) { 246 if (str.length() < MIN_LENGTH) { 247 return null; 248 } 249 return mConvertedCaches[str.charAt(1) % CACHES_PER_ENCODING]; 250 } 251 252 private void readObject(ObjectInputStream in) 253 throws IOException, ClassNotFoundException 254 { 255 in.defaultReadObject(); 256 mConvertedCaches = getConvertedCaches(mBuffer.getEncoding()); 257 } 258 } 259 | Popular Tags |