KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xpath > datamodel > xerces > utils > SymbolCache


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.xquark.xpath.datamodel.xerces.utils;
59
60 /**
61  *
62  * @version
63  */

64 public final class SymbolCache {
65     //
66
// Symbol Cache
67
//
68
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; // start with 4 entries per level
74
//
75
public char[] fSymbolChars = new char[8192];
76     public int fSymbolCharsOffset = 0;
77     public int[][] fCacheLines = new int[8][];
78     public int fCacheLineCount = 0;
79     //
80
//
81
//
82
public SymbolCache() {
83         fCacheLines[fCacheLineCount++] = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
84     }
85     public void reset() {
86         fSymbolCharsOffset = 0;
87         fCacheLineCount = 0;
88         fCacheLines[fCacheLineCount++] = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
89     }
90     //
91
//
92
//
93
public char[] getSymbolChars() {
94         return fSymbolChars;
95     }
96     //
97
// Symbol interfaces
98
//
99
public String JavaDoc createSymbol(int symbolHandle, int startOffset, int entry, int[] entries, int offset) {
100         int slen = fSymbolCharsOffset - startOffset;
101         String JavaDoc str = new String JavaDoc(fSymbolChars, startOffset, slen);
102         try {
103             entries[offset + SymbolCache.INDEX_OFFSET] = symbolHandle;
104         } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
105             throw new RuntimeException JavaDoc("UTL001 untested");
106         }
107         return str;
108     }
109     public int addSymbolToCache(String JavaDoc str, int slen, int symbolHandle) {
110         int charsOffset = fSymbolCharsOffset;
111         if (slen == 0) // EMPTY_STRING cannot be a legal "symbol"
112
return charsOffset;
113         int strIndex = 0;
114         char ch = str.charAt(strIndex++);
115         try {
116             fSymbolChars[fSymbolCharsOffset] = ch;
117         } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
118             char[] newChars = new char[fSymbolChars.length * 2];
119             System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length);
120             fSymbolChars = newChars;
121             fSymbolChars[fSymbolCharsOffset] = ch;
122         }
123         fSymbolCharsOffset++;
124         int entry = 0;
125         int[] entries = fCacheLines[entry];
126         int count = entries[0];
127         int i = 0;
128         int offset = 1;
129         while (true) {
130             if (i == count)
131                 break;
132             if (entries[offset + CHAR_OFFSET] != ch) {
133                 i++;
134                 offset += CACHE_RECORD_SIZE;
135                 continue;
136             }
137             if (strIndex == slen) {
138                 if (entries[offset + INDEX_OFFSET] != -1) {
139                     // How did we miss this during lookup ?
140
throw new RuntimeException JavaDoc("addSymbolToCache");
141                 }
142                 entries[offset + INDEX_OFFSET] = symbolHandle;
143                 return charsOffset;
144             }
145             ch = str.charAt(strIndex++);
146             try {
147                 fSymbolChars[fSymbolCharsOffset] = ch;
148             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
149                 char[] newChars = new char[fSymbolChars.length * 2];
150                 System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length);
151                 fSymbolChars = newChars;
152                 fSymbolChars[fSymbolCharsOffset] = ch;
153             }
154             fSymbolCharsOffset++;
155             entry = entries[offset + NEXT_OFFSET];
156             try {
157                 entries = fCacheLines[entry];
158             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
159                 if (entry == -1) {
160                     entry = fCacheLineCount++;
161                     entries[offset + NEXT_OFFSET] = entry;
162                     entries = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
163                     try {
164                         fCacheLines[entry] = entries;
165                     } catch (ArrayIndexOutOfBoundsException JavaDoc ex2) {
166                         int[][] newCache = new int[entry * 2][];
167                         System.arraycopy(fCacheLines, 0, newCache, 0, entry);
168                         fCacheLines = newCache;
169                         fCacheLines[entry] = entries;
170                     }
171                 } else {
172                     entries = fCacheLines[entry];
173                     throw new RuntimeException JavaDoc("UTL001 untested");
174                 }
175             }
176             count = entries[0];
177             i = 0;
178             offset = 1;
179         }
180         while (true) {
181             entries[0]++;
182             try {
183                 entries[offset + CHAR_OFFSET] = ch;
184             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
185                 int newSize = 1 + ((offset - 1) * 2);
186                 int[] newEntries = new int[newSize];
187                 System.arraycopy(entries, 0, newEntries, 0, offset);
188                 fCacheLines[entry] = entries = newEntries;
189                 entries[offset + CHAR_OFFSET] = ch;
190             }
191             if (strIndex == slen) {
192                 entries[offset + INDEX_OFFSET] = symbolHandle;
193                 entries[offset + NEXT_OFFSET] = -1;
194                 break;
195             }
196             entry = fCacheLineCount++;
197             entries[offset + INDEX_OFFSET] = -1;
198             entries[offset + NEXT_OFFSET] = entry;
199             entries = new int[1+(INITIAL_CACHE_RECORD_COUNT*CACHE_RECORD_SIZE)];
200             try {
201                 fCacheLines[entry] = entries;
202             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
203                 int[][] newCache = new int[entry * 2][];
204                 System.arraycopy(fCacheLines, 0, newCache, 0, entry);
205                 fCacheLines = newCache;
206                 fCacheLines[entry] = entries;
207             }
208             offset = 1;
209             ch = str.charAt(strIndex++);
210             try {
211                 fSymbolChars[fSymbolCharsOffset] = ch;
212             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
213                 char[] newChars = new char[fSymbolChars.length * 2];
214                 System.arraycopy(fSymbolChars, 0, newChars, 0, fSymbolChars.length);
215                 fSymbolChars = newChars;
216                 fSymbolChars[fSymbolCharsOffset] = ch;
217             }
218             fSymbolCharsOffset++;
219         }
220         return charsOffset;
221     }
222     public void updateCacheLine(int charsOffset, int totalMisses, int length) {
223 //System.err.println("found symbol " + toString(symbolIndex) + " after " + totalMisses + " total misses (" + (totalMisses/length) + " misses per character).");
224
int entry = 0;
225         int[] entries = fCacheLines[0];
226         int ch = fSymbolChars[charsOffset++];
227         int count = entries[0];
228         int offset = 1 + ((count - 1) * CACHE_RECORD_SIZE);
229         int misses = 0;
230         while (true) {
231             if (ch != entries[offset + CHAR_OFFSET]) {
232                 offset -= CACHE_RECORD_SIZE;
233                 misses++;
234                 continue;
235             }
236             if (misses > 4) {
237                 int symIndex = entries[offset + INDEX_OFFSET];
238                 int nextIndex = entries[offset + NEXT_OFFSET];
239                 System.arraycopy(entries, offset + CACHE_RECORD_SIZE, entries, offset, misses * CACHE_RECORD_SIZE);
240                 offset = 1 + ((count - 1) * CACHE_RECORD_SIZE);
241                 entries[offset + CHAR_OFFSET] = ch;
242                 entries[offset + INDEX_OFFSET] = symIndex;
243                 entries[offset + NEXT_OFFSET] = nextIndex;
244             }
245             if (--length == 0)
246                 break;
247             entry = entries[offset + NEXT_OFFSET];
248             entries = fCacheLines[entry];
249             ch = fSymbolChars[charsOffset++];
250             count = entries[0];
251             offset = 1 + ((count - 1) * CACHE_RECORD_SIZE);
252             misses = 0;
253         }
254     }
255 }
256
Popular Tags