Beispiel #1
0
 private void updateModel(int index) {
   byte c = buf[index];
   if (index > 0) {
     HashNode hNode = new HashNode();
     byte prevC = buf[index - 1];
     int pos = ((prevC & 0xff) << 8) | (c & 0xff);
     hNode.index = index - 1;
     hNode.next = hashTable[pos];
     hashTable[pos] = hNode;
   }
 }
Beispiel #2
0
 // consider refactoring signature to return PotentialMatch object with fields set...
 int findMatch(int index, int[] distOut, int[] gainOut, int[] costPerByteOut) {
   final int maxCostCacheLength = 32;
   int[] literalCostCache = new int[maxCostCacheLength + 1];
   int maxIndexMinusIndex = buf.length - index;
   int bestLength = 0;
   int bestDist = 0;
   int bestGain = 0;
   int bestCopyCost = 0;
   int maxComputedLength = 0;
   if (maxIndexMinusIndex > 1) {
     int pos = ((buf[index] & 0xff) << 8) | (buf[index + 1] & 0xff);
     HashNode prevNode = null;
     int hNodeCount = 0;
     for (HashNode hNode = hashTable[pos]; hNode != null; prevNode = hNode, hNode = hNode.next) {
       int i = hNode.index;
       int dist = index - i;
       hNodeCount++;
       if (hNodeCount > 256 || dist > maxCopyDist) {
         if (hashTable[pos] == hNode) {
           hashTable[pos] = null;
         } else {
           prevNode.next = null;
         }
         break;
       }
       int maxLen = index - i;
       if (maxIndexMinusIndex < maxLen) {
         maxLen = maxIndexMinusIndex;
       }
       if (maxLen < LEN_MIN) {
         continue;
       }
       i += 2;
       int length = 2;
       for (length = 2; length < maxLen && buf[i] == buf[index + length]; length++) {
         i++;
       }
       if (length < LEN_MIN) {
         continue;
       }
       dist = dist - length + 1;
       if (dist > distMax || (length == 2 && dist >= MAX_2BYTE_DIST)) {
         continue;
       }
       if (length <= bestLength && dist > bestDist) {
         if (length <= bestLength - 2) {
           continue;
         }
         if (dist > (bestDist << DIST_WIDTH)) {
           if (length < bestLength || dist > (bestDist << (DIST_WIDTH + 1))) {
             continue;
           }
         }
       }
       int literalCost = 0;
       if (length > maxComputedLength) {
         int limit = length;
         if (limit > maxCostCacheLength) limit = maxCostCacheLength;
         for (i = maxComputedLength; i < limit; i++) {
           byte c = buf[index + i];
           literalCostCache[i + 1] = literalCostCache[i] + symEncoder.writeSymbolCost(c & 0xff);
         }
         maxComputedLength = limit;
         if (length > maxCostCacheLength) {
           literalCost = literalCostCache[maxCostCacheLength];
           literalCost += literalCost / maxCostCacheLength * (length - maxCostCacheLength);
         } else {
           literalCost = literalCostCache[length];
         }
       } else {
         literalCost = literalCostCache[length];
       }
       if (literalCost > bestGain) {
         int distRanges = getNumDistRanges(dist);
         int copyCost = encodeLengthCost(length, dist, distRanges);
         if (literalCost - copyCost - (distRanges << 16) > bestGain) {
           copyCost += encodeDistance2Cost(dist, distRanges);
           int gain = literalCost - copyCost;
           if (gain > bestGain) {
             bestGain = gain;
             bestLength = length;
             bestDist = dist;
             bestCopyCost = copyCost;
           }
         }
       }
     }
   }
   costPerByteOut[0] = bestLength > 0 ? bestCopyCost / bestLength : 0;
   distOut[0] = bestDist;
   gainOut[0] = bestGain;
   return bestLength;
 }