001package Torello.JavaDoc.SyntaxHiLite;
002
003import Torello.Java.UnreachableError;
004import java.io.File;
005
006/** A 64-Bit Java-{@code Integer} implementation of a File-System Cache. */
007public class HLC64 extends AbstractHashCodeHLC<Long>
008{
009    /**
010     * Initializes a 63-Bit (java.lang.Long) Cache in the specified directory.
011     * <!-- Content below this line was block copied from class 'AbstractHashCodeHLC' -->
012     * 
013     * This will load the hashCodes table to memory from the file-system directory identified
014     * by {@code String}-Parameter {@code 'cacheSaveDirectory'}.  An exception shall be thrown
015     * if this file is not found, or the specified directory doesn't exist.
016     *
017     * @param cacheSaveDirectory This constructor presumes that this cache has been used and
018     * visited before.  This directory name should point to your local-cache of the
019     * {@code HiLite.ME} Server Code hilite past-operations.
020     *
021     * @throws CacheError This error will throw if the cache has not been instantiated, or
022     * is corrupted.  If the specified directory does not exist, then this {@code Error} shall
023     * also throw.  The chain-cause {@code Throwable} should be visible, and is included as the 
024     * {@code Throwable.getCause()}.
025     */
026    public HLC64(String cacheSaveDirectory)
027    { super(cacheSaveDirectory, Long.class); }
028
029    public Long computeCacheKey(
030            final String    codeTypeParam,
031            final boolean   includeLineNumbers,
032            final byte      styleNum,
033            final String    sourceCodeAsString
034        )
035    {
036        final long FNV_PRIME = 0x100000001b3L;
037        long hash = 0xcbf29ce484222325L;
038    
039        // Mix in codeTypeParam
040        for (int i = 0; i < codeTypeParam.length(); i++) {
041            hash ^= codeTypeParam.charAt(i);
042            hash *= FNV_PRIME;
043        }
044    
045        // Mix in includeLineNumbers
046        hash ^= (includeLineNumbers ? 1 : 0);
047        hash *= FNV_PRIME;
048    
049        // Mix in styleNum
050        hash ^= styleNum;
051        hash *= FNV_PRIME;
052    
053        // Mix in sourceCodeAsString
054        for (int i = 0; i < sourceCodeAsString.length(); i++) {
055            hash ^= sourceCodeAsString.charAt(i);
056            hash *= FNV_PRIME;
057        }
058    
059        return hash;
060    }
061
062
063    // Implementation of abstract-parent method.
064    // All it does is convert a Hash-Code into a Directory name.
065    // NOTE: This method is package private
066
067    String getSubDirName(Long hashCode)
068    {
069        final long absVal = (hashCode.longValue() < 0)
070            ? -hashCode.longValue()
071            : hashCode.longValue();
072
073        return
074            this.cacheSaveDirectory + 
075            zeroPad10e4(absVal % AbstractHashCodeHLC.NUM_DIRS) + File.separator;
076    }
077
078    private static String zeroPad10e4(final long l)
079    {
080        if (l < 10)     return "000"    + l;
081        if (l < 100)    return "00"     + l;
082        if (l < 1000)   return "0"      + l;
083        if (l < 10000)  return ""       + l;
084
085        throw new UnreachableError();
086    }
087}