Methods Summary |
---|
protected static final int | compare(ByteChunk name, byte[] compareTo)Compare given byte chunk with byte array.
Return -1, 0 or +1 if inferior, equal, or superior to the String.
int result = 0;
byte[] b = name.getBuffer();
int start = name.getStart();
int end = name.getEnd();
int len = compareTo.length;
if ((end - start) < len) {
len = end - start;
}
for (int i = 0; (i < len) && (result == 0); i++) {
if (b[i + start] > compareTo[i]) {
result = 1;
} else if (b[i + start] < compareTo[i]) {
result = -1;
}
}
if (result == 0) {
if (compareTo.length > (end - start)) {
result = -1;
} else if (compareTo.length < (end - start)) {
result = 1;
}
}
return result;
|
protected static final int | compare(CharChunk name, char[] compareTo)Compare given char chunk with char array.
Return -1, 0 or +1 if inferior, equal, or superior to the String.
int result = 0;
char[] c = name.getBuffer();
int start = name.getStart();
int end = name.getEnd();
int len = compareTo.length;
if ((end - start) < len) {
len = end - start;
}
for (int i = 0; (i < len) && (result == 0); i++) {
if (c[i + start] > compareTo[i]) {
result = 1;
} else if (c[i + start] < compareTo[i]) {
result = -1;
}
}
if (result == 0) {
if (compareTo.length > (end - start)) {
result = -1;
} else if (compareTo.length < (end - start)) {
result = 1;
}
}
return result;
|
protected static final java.lang.String | find(ByteChunk name)Find an entry given its name in the cache and return the associated String.
int pos = findClosest(name, bcCache, bcCache.length);
if ((pos < 0) || (compare(name, bcCache[pos].name) != 0)
|| !(name.getEncoding().equals(bcCache[pos].enc))) {
return null;
} else {
return bcCache[pos].value;
}
|
protected static final java.lang.String | find(CharChunk name)Find an entry given its name in the cache and return the associated String.
int pos = findClosest(name, ccCache, ccCache.length);
if ((pos < 0) || (compare(name, ccCache[pos].name) != 0)) {
return null;
} else {
return ccCache[pos].value;
}
|
protected static final int | findClosest(ByteChunk name, org.apache.tomcat.util.buf.StringCache$ByteEntry[] array, int len)Find an entry given its name in a sorted array of map elements.
This will return the index for the closest inferior or equal item in the
given array.
int a = 0;
int b = len - 1;
// Special cases: -1 and 0
if (b == -1) {
return -1;
}
if (compare(name, array[0].name) < 0) {
return -1;
}
if (b == 0) {
return 0;
}
int i = 0;
while (true) {
i = (b + a) / 2;
int result = compare(name, array[i].name);
if (result == 1) {
a = i;
} else if (result == 0) {
return i;
} else {
b = i;
}
if ((b - a) == 1) {
int result2 = compare(name, array[b].name);
if (result2 < 0) {
return a;
} else {
return b;
}
}
}
|
protected static final int | findClosest(CharChunk name, org.apache.tomcat.util.buf.StringCache$CharEntry[] array, int len)Find an entry given its name in a sorted array of map elements.
This will return the index for the closest inferior or equal item in the
given array.
int a = 0;
int b = len - 1;
// Special cases: -1 and 0
if (b == -1) {
return -1;
}
if (compare(name, array[0].name) < 0 ) {
return -1;
}
if (b == 0) {
return 0;
}
int i = 0;
while (true) {
i = (b + a) / 2;
int result = compare(name, array[i].name);
if (result == 1) {
a = i;
} else if (result == 0) {
return i;
} else {
b = i;
}
if ((b - a) == 1) {
int result2 = compare(name, array[b].name);
if (result2 < 0) {
return a;
} else {
return b;
}
}
}
|
public int | getAccessCount()
return accessCount;
|
public boolean | getByteEnabled()
return byteEnabled;
|
public int | getCacheSize()
// ------------------------------------------------------------ Properties
return cacheSize;
|
public boolean | getCharEnabled()
return charEnabled;
|
public int | getHitCount()
return hitCount;
|
public int | getTrainThreshold()
return trainThreshold;
|
public void | reset()
hitCount = 0;
accessCount = 0;
synchronized (bcStats) {
bcCache = null;
bcCount = 0;
}
synchronized (ccStats) {
ccCache = null;
ccCount = 0;
}
|
public void | setByteEnabled(boolean byteEnabled)
StringCache.byteEnabled = byteEnabled;
|
public void | setCacheSize(int cacheSize)
StringCache.cacheSize = cacheSize;
|
public void | setCharEnabled(boolean charEnabled)
StringCache.charEnabled = charEnabled;
|
public void | setTrainThreshold(int trainThreshold)
StringCache.trainThreshold = trainThreshold;
|
public static java.lang.String | toString(ByteChunk bc)
// If the cache is null, then either caching is disabled, or we're
// still training
if (bcCache == null) {
String value = bc.toStringInternal();
if (byteEnabled && (value.length() < maxStringSize)) {
// If training, everything is synced
synchronized (bcStats) {
// If the cache has been generated on a previous invocation
// while waiting fot the lock, just return the toString value
// we just calculated
if (bcCache != null) {
return value;
}
// Two cases: either we just exceeded the train count, in which
// case the cache must be created, or we just update the count for
// the string
if (bcCount > trainThreshold) {
long t1 = System.currentTimeMillis();
// Sort the entries according to occurrence
TreeMap tempMap = new TreeMap();
Iterator entries = bcStats.keySet().iterator();
while (entries.hasNext()) {
ByteEntry entry = (ByteEntry) entries.next();
int[] countA = (int[]) bcStats.get(entry);
Integer count = new Integer(countA[0]);
// Add to the list for that count
ArrayList list = (ArrayList) tempMap.get(count);
if (list == null) {
// Create list
list = new ArrayList();
tempMap.put(count, list);
}
list.add(entry);
}
// Allocate array of the right size
int size = bcStats.size();
if (size > cacheSize) {
size = cacheSize;
}
ByteEntry[] tempbcCache = new ByteEntry[size];
// Fill it up using an alphabetical order
// and a dumb insert sort
ByteChunk tempChunk = new ByteChunk();
int n = 0;
while (n < size) {
Object key = tempMap.lastKey();
ArrayList list = (ArrayList) tempMap.get(key);
ByteEntry[] list2 =
(ByteEntry[]) list.toArray(new ByteEntry[list.size()]);
for (int i = 0; i < list.size() && n < size; i++) {
ByteEntry entry = (ByteEntry) list.get(i);
tempChunk.setBytes(entry.name, 0, entry.name.length);
int insertPos = findClosest(tempChunk, tempbcCache, n);
if (insertPos == n) {
tempbcCache[n + 1] = entry;
} else {
System.arraycopy(tempbcCache, insertPos + 1, tempbcCache,
insertPos + 2, n - insertPos - 1);
tempbcCache[insertPos + 1] = entry;
}
n++;
}
tempMap.remove(key);
}
bcCount = 0;
bcStats.clear();
bcCache = tempbcCache;
if (log.isDebugEnabled()) {
long t2 = System.currentTimeMillis();
log.debug("ByteCache generation time: " + (t2 - t1) + "ms");
}
} else {
bcCount++;
// Allocate new ByteEntry for the lookup
ByteEntry entry = new ByteEntry();
entry.value = value;
int[] count = (int[]) bcStats.get(entry);
if (count == null) {
int end = bc.getEnd();
int start = bc.getStart();
// Create byte array and copy bytes
entry.name = new byte[bc.getLength()];
System.arraycopy(bc.getBuffer(), start, entry.name, 0, end - start);
// Set encoding
entry.enc = bc.getEncoding();
// Initialize occurrence count to one
count = new int[1];
count[0] = 1;
// Set in the stats hash map
bcStats.put(entry, count);
} else {
count[0] = count[0] + 1;
}
}
}
}
return value;
} else {
accessCount++;
// Find the corresponding String
String result = find(bc);
if (result == null) {
return bc.toStringInternal();
}
// Note: We don't care about safety for the stats
hitCount++;
return result;
}
|
public static java.lang.String | toString(CharChunk cc)
// If the cache is null, then either caching is disabled, or we're
// still training
if (ccCache == null) {
String value = cc.toStringInternal();
if (charEnabled && (value.length() < maxStringSize)) {
// If training, everything is synced
synchronized (ccStats) {
// If the cache has been generated on a previous invocation
// while waiting fot the lock, just return the toString value
// we just calculated
if (ccCache != null) {
return value;
}
// Two cases: either we just exceeded the train count, in which
// case the cache must be created, or we just update the count for
// the string
if (ccCount > trainThreshold) {
long t1 = System.currentTimeMillis();
// Sort the entries according to occurrence
TreeMap tempMap = new TreeMap();
Iterator entries = ccStats.keySet().iterator();
while (entries.hasNext()) {
CharEntry entry = (CharEntry) entries.next();
int[] countA = (int[]) ccStats.get(entry);
Integer count = new Integer(countA[0]);
// Add to the list for that count
ArrayList list = (ArrayList) tempMap.get(count);
if (list == null) {
// Create list
list = new ArrayList();
tempMap.put(count, list);
}
list.add(entry);
}
// Allocate array of the right size
int size = ccStats.size();
if (size > cacheSize) {
size = cacheSize;
}
CharEntry[] tempccCache = new CharEntry[size];
// Fill it up using an alphabetical order
// and a dumb insert sort
CharChunk tempChunk = new CharChunk();
int n = 0;
while (n < size) {
Object key = tempMap.lastKey();
ArrayList list = (ArrayList) tempMap.get(key);
CharEntry[] list2 =
(CharEntry[]) list.toArray(new CharEntry[list.size()]);
for (int i = 0; i < list.size() && n < size; i++) {
CharEntry entry = (CharEntry) list.get(i);
tempChunk.setChars(entry.name, 0, entry.name.length);
int insertPos = findClosest(tempChunk, tempccCache, n);
if (insertPos == n) {
tempccCache[n + 1] = entry;
} else {
System.arraycopy(tempccCache, insertPos + 1, tempccCache,
insertPos + 2, n - insertPos - 1);
tempccCache[insertPos + 1] = entry;
}
n++;
}
tempMap.remove(key);
}
ccCount = 0;
ccStats.clear();
ccCache = tempccCache;
if (log.isDebugEnabled()) {
long t2 = System.currentTimeMillis();
log.debug("CharCache generation time: " + (t2 - t1) + "ms");
}
} else {
ccCount++;
// Allocate new CharEntry for the lookup
CharEntry entry = new CharEntry();
entry.value = value;
int[] count = (int[]) ccStats.get(entry);
if (count == null) {
int end = cc.getEnd();
int start = cc.getStart();
// Create char array and copy chars
entry.name = new char[cc.getLength()];
System.arraycopy(cc.getBuffer(), start, entry.name, 0, end - start);
// Initialize occurrence count to one
count = new int[1];
count[0] = 1;
// Set in the stats hash map
ccStats.put(entry, count);
} else {
count[0] = count[0] + 1;
}
}
}
}
return value;
} else {
accessCount++;
// Find the corresponding String
String result = find(cc);
if (result == null) {
return cc.toStringInternal();
}
// Note: We don't care about safety for the stats
hitCount++;
return result;
}
|