Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * ====================================================================
   * Copyright (c) 2004-2006 TMate Software Ltd.  All rights reserved.
   *
   * This software is licensed as described in the file COPYING, which
   * you should have received as part of this distribution.  The terms
   * are also available at http://svnkit.com/license.html
   * If newer versions of this license are posted there, you may use a
   * newer version instead, at your option.
  * ====================================================================
  */
 package org.tmatesoft.svn.core.internal.delta;
 
 import java.util.Map;

Author(s):
TMate Software Ltd.
Version:
1.1.0
 
 public class SVNXDeltaAlgorithm extends SVNDeltaAlgorithm {
     
     private static final int MATCH_BLOCK_SIZE = 64;
     
     public void computeDelta(byte[] aint aLengthbyte[] bint bLength) {
         if (bLength < ) {
             copyFromNewData(b, 0, bLength);
             return;
         }
         PseudoAdler32 bAdler = new PseudoAdler32();
         Map aMatchesTable = createMatchesTable(aaLengthbAdler);
         bAdler.reset();
         bAdler.add(b, 0, );
 
         int lo = 0;
         int size = bLength;
         Match previousInsertion = null;
         
         while(lo < size) {
             Match match = findMatch(aMatchesTablebAdleraaLengthbbLengthlopreviousInsertion);
             if (match == null) {
                 if (previousInsertion != null && previousInsertion.length > 0) {
                     previousInsertion.length++;
                 } else {
                     previousInsertion = new Match(lo, 1);
                 }
             } else {
                 if (previousInsertion != null && previousInsertion.length > 0) {
                     copyFromNewData(bpreviousInsertion.positionpreviousInsertion.length);
                     previousInsertion = null;
                 }
                 copyFromSource(match.positionmatch.length);                
             }
             int advance = match != null ? match.advance : 1;
             for (int next = lonext < lo + advancenext++) {
                 bAdler.remove(b[next]);
                 if (next +  < bLength) {
                     bAdler.add(b[next + ]);
                 }
             }
             lo += advance;
         }
         if (previousInsertion != null && previousInsertion.length > 0) {
             copyFromNewData(bpreviousInsertion.positionpreviousInsertion.length);
             previousInsertion = null;
         }
     }
     
     private static Match findMatch(Map matchesTablePseudoAdler32 checksumbyte[] aint aLengthbyte[] bint bLengthint bPosMatch previousInsertion) {
         Match existingMatch = (MatchmatchesTable.get(new Integer(checksum.getValue()));
         if (existingMatch == null) {
             return null;
         }
         if (!equals(aaLengthexistingMatch.positionexistingMatch.lengthbbLengthbPos)) {
             return null;
         }
         existingMatch = new Match(existingMatch.positionexistingMatch.length);
         existingMatch.advance = existingMatch.length;
 
         // extend forward 
         while(existingMatch.position + existingMatch.length < aLength &&
                 bPos + existingMatch.advance < bLength &&
                 a[existingMatch.position + existingMatch.length] == b[bPos + existingMatch.advance]) {
             existingMatch.length++;
             existingMatch.advance++;
         }
         // extend backward
         if (previousInsertion != null) {
             while(existingMatch.position > 0 && bPos > 0 &&
                     a[existingMatch.position - 1] == b[bPos -1] &&
                     previousInsertion.length != 0) {
                 previousInsertion.length--;
                 bPos--;
                 existingMatch.position--;
                 existingMatch.length++;
             }
         }
         return existingMatch;
     }
    
    private static Map createMatchesTable(byte[] dataint dataLengthint blockLengthPseudoAdler32 adler32) {
        Map matchesTable = new HashMap();
        for(int i = 0; i < dataLengthi+= blockLength) {
            int length = i + blockLength >= dataLength ? dataLength - i : blockLength;
            adler32.add(datailength);
            Integer checksum = new Integer(adler32.getValue());
            if (!matchesTable.containsKey(checksum)) {
                matchesTable.put(checksumnew Match(ilength));
            }
            adler32.reset();
        }
        return matchesTable;
    }
    
    private static boolean equals(byte[] aint aLengthint aPosint lengthbyte[] bint bLengthint bPos) {
        if (aPos + length - 1 > aLength || bPos + length > bLength) {
            return false;
        }
        for(int i = 0; i < lengthi++) {
            if (a[aPos + i] != b[bPos + i]) {
                return false;
            }
        }
        return true;
    }
    
    private static class Match {
        
        public Match(int pint l) {
             = p;
             = l;
        }
        
        public int position;
        public int length;
        public int advance;
    }
    private static int ADLER32_MASK = 0x0000FFFF;
    private static class PseudoAdler32 {        
        
        private int myS1;
        private int myS2;
        private int myLength;
        
        public PseudoAdler32() {
            reset();
        }
        
        public void add(byte b) {
            int z = b & 0x000000FF;
             =  + z;
             =  & ;
             =  + ;
             =  & ;
            ++;
        }
        
        public void remove(byte b) {
            int z = b & 0x000000FF;
             =  - z;
             =  & ;
             =  - ( * z + 1);
             =  & ;
            --;
        }
        
        public void add(byte[] dataint offsetint length) {
            for (int i = offseti < offset + lengthi++) {
                add(data[i]);
            }
        }
        
        public int getValue() {
            return ( << 16) | ;
        }
        
        public void reset() {
             = 1;
             = 0;
             = 0;
        }
    }
}
 
New to GrepCode? Check out our FAQ X