1 57 58 package org.enhydra.apache.xerces.utils; 59 60 64 public final class SymbolCache { 65 public static final int CHAR_OFFSET = 0; 69 public static final int INDEX_OFFSET = 1; 70 public static final int NEXT_OFFSET = 2; 71 public static final int CACHE_RECORD_SIZE = 3; 72 73 public static final int INITIAL_CACHE_RECORD_COUNT = 4; 75 76 public static final int HEAD_INITIAL_CACHE_RECORD_COUNT = 85; 78 public char[] fSymbolChars = new char[8192]; 80 public int fSymbolCharsOffset = 0; 81 public int[][] fCacheLines = new int[256][]; 82 public int fCacheLineCount = 0; 83 84 115 116 140 141 public SymbolCache() { 142 fCacheLines[fCacheLineCount++] = 143 new int[1+(HEAD_INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)]; 144 } 145 public void reset() { 147 fSymbolCharsOffset = 0; 148 fCacheLineCount = 0; 149 fCacheLines[fCacheLineCount++] = 150 new int[1+(HEAD_INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)]; 151 } 152 public char[] getSymbolChars() { 156 return fSymbolChars; 157 } 158 public String createSymbol(int symbolHandle, int startOffset, int entry, 162 int[] entries, int offset) { 163 int slen = fSymbolCharsOffset - startOffset; 164 String str = new String (fSymbolChars, startOffset, slen); 165 try { 166 entries[offset + SymbolCache.INDEX_OFFSET] = symbolHandle; 167 } catch (ArrayIndexOutOfBoundsException ex) { 168 throw new RuntimeException ("UTL001 untested"); 169 } 170 return str; 171 } 172 public int addSymbolToCache(String str, int slen, int symbolHandle) { 173 int charsOffset = fSymbolCharsOffset; 174 if (slen == 0) return charsOffset; 176 int strIndex = 0; 177 char ch = str.charAt(strIndex++); 178 try { 179 fSymbolChars[fSymbolCharsOffset] = ch; 180 } catch (ArrayIndexOutOfBoundsException ex) { 181 char[] newChars = new char[fSymbolChars.length * 2]; 182 System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length); 183 fSymbolChars = newChars; 184 fSymbolChars[fSymbolCharsOffset] = ch; 185 } 186 fSymbolCharsOffset++; 187 int entry = 0; 188 int[] entries = fCacheLines[entry]; 189 int count = entries[0]; 190 int i = 0; 191 int offset = 1; 192 while (true) { 193 if (i == count) 194 break; 195 if (entries[offset + CHAR_OFFSET] != ch) { 196 i++; 197 offset += CACHE_RECORD_SIZE; 198 continue; 199 } 200 if (strIndex == slen) { 201 if (entries[offset + INDEX_OFFSET] != -1) { 202 throw new RuntimeException ("addSymbolToCache"); 204 } 205 entries[offset + INDEX_OFFSET] = symbolHandle; 206 return charsOffset; 207 } 208 ch = str.charAt(strIndex++); 209 try { 210 fSymbolChars[fSymbolCharsOffset] = ch; 211 } catch (ArrayIndexOutOfBoundsException ex) { 212 char[] newChars = new char[fSymbolChars.length * 2]; 213 System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length); 214 fSymbolChars = newChars; 215 fSymbolChars[fSymbolCharsOffset] = ch; 216 } 217 fSymbolCharsOffset++; 218 entry = entries[offset + NEXT_OFFSET]; 219 try { 220 entries = fCacheLines[entry]; 221 } catch (ArrayIndexOutOfBoundsException ex) { 222 if (entry == -1) { 223 entry = fCacheLineCount++; 224 entries[offset + NEXT_OFFSET] = entry; 225 entries = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)]; 226 try { 227 fCacheLines[entry] = entries; 228 } catch (ArrayIndexOutOfBoundsException ex2) { 229 int[][] newCache = new int[entry * 2][]; 230 System.arraycopy(fCacheLines, 0, newCache, 0, entry); 231 fCacheLines = newCache; 232 fCacheLines[entry] = entries; 233 } 234 } else { 235 entries = fCacheLines[entry]; 236 throw new RuntimeException ("UTL001 untested"); 237 } 238 } 239 count = entries[0]; 240 i = 0; 241 offset = 1; 242 } 243 while (true) { 244 entries[0]++; 245 try { 246 entries[offset + CHAR_OFFSET] = ch; 247 } catch (ArrayIndexOutOfBoundsException ex) { 248 int newSize = 1 + ((offset - 1) * 2); 249 int[] newEntries = new int[newSize]; 250 System.arraycopy(entries, 0, newEntries, 0, offset); 251 fCacheLines[entry] = entries = newEntries; 252 entries[offset + CHAR_OFFSET] = ch; 253 } 254 if (strIndex == slen) { 255 entries[offset + INDEX_OFFSET] = symbolHandle; 256 entries[offset + NEXT_OFFSET] = -1; 257 break; 258 } 259 entry = fCacheLineCount++; 260 entries[offset + INDEX_OFFSET] = -1; 261 entries[offset + NEXT_OFFSET] = entry; 262 entries = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)]; 263 try { 264 fCacheLines[entry] = entries; 265 } catch (ArrayIndexOutOfBoundsException ex) { 266 int[][] newCache = new int[entry * 2][]; 267 System.arraycopy(fCacheLines, 0, newCache, 0, entry); 268 fCacheLines = newCache; 269 fCacheLines[entry] = entries; 270 } 271 offset = 1; 272 ch = str.charAt(strIndex++); 273 try { 274 fSymbolChars[fSymbolCharsOffset] = ch; 275 } catch (ArrayIndexOutOfBoundsException ex) { 276 char[] newChars = new char[fSymbolChars.length * 2]; 277 System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length); 278 fSymbolChars = newChars; 279 fSymbolChars[fSymbolCharsOffset] = ch; 280 } 281 fSymbolCharsOffset++; 282 } 283 return charsOffset; 284 } 285 public void updateCacheLine(int charsOffset, int totalMisses, int length) { 286 int entry = 0; 288 int[] entries = fCacheLines[0]; 289 int ch = fSymbolChars[charsOffset++]; 290 int count = entries[0]; 291 int offset = 1 + ((count - 1) * CACHE_RECORD_SIZE); 292 int misses = 0; 293 while (true) { 294 if (ch != entries[offset + CHAR_OFFSET]) { 295 offset -= CACHE_RECORD_SIZE; 296 misses++; 297 continue; 298 } 299 if (misses > 4) { 300 int symIndex = entries[offset + INDEX_OFFSET]; 301 int nextIndex = entries[offset + NEXT_OFFSET]; 302 System.arraycopy(entries, offset + CACHE_RECORD_SIZE, entries, offset, misses * CACHE_RECORD_SIZE); 303 offset = 1 + ((count - 1) * CACHE_RECORD_SIZE); 304 entries[offset + CHAR_OFFSET] = ch; 305 entries[offset + INDEX_OFFSET] = symIndex; 306 entries[offset + NEXT_OFFSET] = nextIndex; 307 } 308 if (--length == 0) 309 break; 310 entry = entries[offset + NEXT_OFFSET]; 311 entries = fCacheLines[entry]; 312 ch = fSymbolChars[charsOffset++]; 313 count = entries[0]; 314 offset = 1 + ((count - 1) * CACHE_RECORD_SIZE); 315 misses = 0; 316 } 317 } 318 } 319 | Popular Tags |