harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sjanu...@apache.org
Subject svn commit: r784030 - in /harmony/enhanced/classlib/trunk/modules/pack200/src: main/java/org/apache/harmony/pack200/ main/java/org/apache/harmony/unpack200/ test/java/org/apache/harmony/pack200/tests/ test/java/org/apache/harmony/unpack200/tests/
Date Fri, 12 Jun 2009 08:35:09 GMT
Author: sjanuary
Date: Fri Jun 12 08:35:08 2009
New Revision: 784030

URL: http://svn.apache.org/viewvc?rev=784030&view=rev
Log:
Pack200 - support for -E option (different effort compression algorithms)

Added:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/BandSet.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/SegmentHeader.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ClassBandsTest.java

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BHSDCodec.java Fri Jun 12 08:35:08 2009
@@ -204,14 +204,14 @@
         return cardinality;
     }
 
-    public long decode(InputStream in) throws IOException, Pack200Exception {
+    public int decode(InputStream in) throws IOException, Pack200Exception {
         if (d != 0)
             throw new Pack200Exception(
                     "Delta encoding used without passing in last value; this is a coding error");
         return decode(in, 0);
     }
 
-    public long decode(InputStream in, long last) throws IOException,
+    public int decode(InputStream in, long last) throws IOException,
             Pack200Exception {
         int n = 0;
         long z = 0;
@@ -219,6 +219,7 @@
 
         do {
             x = in.read();
+            lastBandLength ++;
             z += x * powers[n];
             n++;
         } while (x >= l && n < b);
@@ -252,7 +253,39 @@
         // }
         if (isDelta())
             z += last;
-        return z;
+        return (int)z;
+    }
+
+    public int[] decodeInts(int n, InputStream in) throws IOException,
+            Pack200Exception {
+        int[] band = super.decodeInts(n, in);
+        if (isDelta()) {
+            for (int i = 0; i < band.length; i++) {
+                while (band[i] > largest) {
+                    band[i] -= cardinality;
+                }
+                while (band[i] < smallest) {
+                    band[i] += cardinality;
+                }
+            }
+        }
+        return band;
+    }
+
+    public int[] decodeInts(int n, InputStream in, int firstValue)
+            throws IOException, Pack200Exception {
+        int[] band =  super.decodeInts(n, in, firstValue);
+        if (isDelta()) {
+            for (int i = 0; i < band.length; i++) {
+                while (band[i] > largest) {
+                    band[i] -= cardinality;
+                }
+                while (band[i] < smallest) {
+                    band[i] += cardinality;
+                }
+            }
+        }
+        return band;
     }
 
     // private long cast32(long u) {
@@ -269,19 +302,19 @@
      * @return <code>true</code> if the encoding can encode this value
      */
     public boolean encodes(long value) {
-        return (value >= smallest && value <= largest);
+        return value >= smallest && value <= largest;
     }
 
-    public byte[] encode(long value, long last) throws Pack200Exception {
-        if (isDelta()) {
-            value -= last;
+    public byte[] encode(int value, int last) throws Pack200Exception {
+        if(!encodes(value)) {
+            throw new Pack200Exception("The codec " + toString()
+                  + " does not encode the value " + value);
         }
-        // TODO: Do we need this?  this implementation isn't right because of integer overflow...
-//        if (!encodes(value)) {
-//            throw new Pack200Exception("The codec " + toString()
-//                   + " does not encode the value " + value);
-//        }
+
         long z = value;
+        if (isDelta()) {
+            z -= last;
+        }
         if (isSigned()) {
             if(z < Integer.MIN_VALUE) {
                 z += 4294967296L;
@@ -301,12 +334,16 @@
             if (z < 0) {
                 // Need to use integer overflow here to represent negatives.
                 if(cardinality < 4294967296L) {
-                    z+= cardinality;
+                    z += cardinality;
                 } else {
                     z += 4294967296L; // this value is equal to (1 << 32).
                 }
             }
         }
+        if (z < 0) {
+            throw new Pack200Exception("unable to encode");
+        }
+
         List byteList = new ArrayList();
         for (int n = 0; n < b; n++) {
             long byteN;
@@ -331,7 +368,7 @@
         return bytes;
     }
 
-    public byte[] encode(long value) throws Pack200Exception {
+    public byte[] encode(int value) throws Pack200Exception {
         return encode(value, 0);
     }
 
@@ -393,19 +430,16 @@
 
     private long calculateSmallest() {
         long result;
-        if (d == 1) {
-            BHSDCodec bh0 = new BHSDCodec(b, h);
-            return bh0.smallest();
-        } else if (isSigned()) {
-            result = -cardinality() / (1 << s);
-        } else {
-            if (cardinality > Integer.MAX_VALUE) {
+        if (d == 1 || !isSigned()) {
+            if (cardinality >= 4294967296L) { // 2^32
                 result = Integer.MIN_VALUE;
             } else {
                 result = 0;
             }
+        } else {
+            result = Math.max(Integer.MIN_VALUE, -cardinality() / (1 << s));
         }
-        return Math.max(Integer.MIN_VALUE, result);
+        return result;
     }
 
     /**

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Fri Jun 12 08:35:08 2009
@@ -18,13 +18,26 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 
 public abstract class BandSet {
 
-    private final int effort;
     protected final SegmentHeader segmentHeader;
+    private final int effort;
+
+    // Minimum size of band for each effort level where we consider alternative codecs
+    // Note: these values have been tuned - please test carefully if changing them
+    private final int[] effortThresholds = new int[] {0, 0, 1000, 500, 100, 100, 100, 100, 100, 0};
+
+    private long[] canonicalLargest;
+    private long[] canonicalSmallest;
 
     public BandSet(int effort, SegmentHeader header) {
         this.effort = effort;
@@ -42,25 +55,36 @@
     }
 
     public byte[] encodeBandInt(String name, int[] ints, BHSDCodec defaultCodec) throws Pack200Exception {
-        if(effort > 1 && (ints.length > 99 || effort == 9)) {
-            Codec betterCodec = lookForBetterCodec(name, ints, defaultCodec);
+        byte[] encodedBand = null;
+        if(effort > 1 && (ints.length >= effortThresholds[effort])) {
+            BandAnalysisResults results = analyseBand(name, ints, defaultCodec);
+            Codec betterCodec = results.betterCodec;
+            encodedBand = results.encodedBand;
             if(betterCodec != null) {
                 if(betterCodec instanceof BHSDCodec) {
                     int[] specifierBand = CodecEncoding.getSpecifier(betterCodec, defaultCodec);
                     int specifier = specifierBand[0];
-                    if(specifierBand.length > 0) {
+                    if(specifierBand.length > 1) {
                         for (int i = 1; i < specifierBand.length; i++) {
                             segmentHeader.appendBandCodingSpecifier(specifierBand[i]);
                         }
                     }
+                    if(defaultCodec.isSigned()) {
+                        specifier = -1 -specifier;
+                    } else {
+                        specifier = specifier + defaultCodec.getL();
+                    }
                     byte[] specifierEncoded = defaultCodec.encode(new int[] {specifier});
-                    byte[] rest = betterCodec.encode(ints);
-                    byte[] band = new byte[specifierEncoded.length + rest.length];
+                    byte[] band = new byte[specifierEncoded.length + encodedBand.length];
                     System.arraycopy(specifierEncoded, 0, band, 0, specifierEncoded.length);
-                    System.arraycopy(rest, 0, band, specifierEncoded.length, rest.length);
+                    System.arraycopy(encodedBand, 0, band, specifierEncoded.length, encodedBand.length);
                     return band;
                 } else if (betterCodec instanceof PopulationCodec) {
-
+                    int[] extraSpecifierInfo = results.extraMetadata;
+                    for (int i = 0; i < extraSpecifierInfo.length; i++) {
+                        segmentHeader.appendBandCodingSpecifier(extraSpecifierInfo[i]);
+                    }
+                    return encodedBand;
                 } else if (betterCodec instanceof RunCodec) {
 
                 }
@@ -69,37 +93,201 @@
 
         // If we get here then we've decided to use the default codec.
         if(ints.length > 0) {
-//            System.out.println("encoding " + name + ", size = " + ints.length);
+            if(encodedBand == null) {
+                encodedBand = defaultCodec.encode(ints);
+            }
             int first = ints[0];
             if(defaultCodec.getB() != 1) {
                 if (defaultCodec.isSigned() && first >= -256 && first <= -1) {
                     int specifier = -1 - CodecEncoding.getSpecifierForDefaultCodec(defaultCodec);
                     byte[] specifierEncoded = defaultCodec.encode(new int[] {specifier});
-                    byte[] rest = defaultCodec.encode(ints);
-                    byte[] band = new byte[specifierEncoded.length + rest.length];
+                    byte[] band = new byte[specifierEncoded.length + encodedBand.length];
                     System.arraycopy(specifierEncoded, 0, band, 0, specifierEncoded.length);
-                    System.arraycopy(rest, 0, band, specifierEncoded.length, rest.length);
+                    System.arraycopy(encodedBand, 0, band, specifierEncoded.length, encodedBand.length);
                     return band;
                 } else if (!defaultCodec.isSigned() && first >= defaultCodec.getL()
                         && first <= defaultCodec.getL() + 255) {
                     int specifier = CodecEncoding.getSpecifierForDefaultCodec(defaultCodec) + defaultCodec.getL();
                     byte[] specifierEncoded = defaultCodec.encode(new int[] {specifier});
-                    byte[] rest = defaultCodec.encode(ints);
-                    byte[] band = new byte[specifierEncoded.length + rest.length];
+                    byte[] band = new byte[specifierEncoded.length + encodedBand.length];
                     System.arraycopy(specifierEncoded, 0, band, 0, specifierEncoded.length);
-                    System.arraycopy(rest, 0, band, specifierEncoded.length, rest.length);
+                    System.arraycopy(encodedBand, 0, band, specifierEncoded.length, encodedBand.length);
                     return band;
                 }
             }
-            return defaultCodec.encode(ints);
+            return encodedBand;
         }
         return new byte[0];
     }
 
-    private Codec lookForBetterCodec(String name, int[] ints,
-            BHSDCodec defaultCodec) {
-        // TODO Auto-generated method stub
-        return null;
+    private BandAnalysisResults analyseBand(String name, int[] band,
+            BHSDCodec defaultCodec) throws Pack200Exception {
+
+        BandAnalysisResults results = new BandAnalysisResults();
+
+        if(canonicalLargest == null) {
+            canonicalLargest = new long[116];
+            canonicalSmallest = new long[116];
+            for (int i = 1; i < canonicalLargest.length; i++) {
+                canonicalLargest[i] = CodecEncoding.getCanonicalCodec(i).largest();
+                canonicalSmallest[i] = CodecEncoding.getCanonicalCodec(i).smallest();
+            }
+        }
+        BandData bandData = new BandData(band);
+
+        // Check that there is a reasonable saving to be made
+        byte[] encoded = defaultCodec.encode(band);
+        results.encodedBand = encoded;
+
+        // Note: these values have been tuned - please test carefully if changing them
+        if(encoded.length <= band.length + 23 - 2*effort) { // TODO: tweak
+            return results;
+        }
+
+        // Check if we can use BYTE1 as that's a 1:1 mapping if we can
+        if(!bandData.anyNegatives() && bandData.largest <= Codec.BYTE1.largest()) {
+              results.encodedBand = Codec.BYTE1.encode(band)  ;
+              results.betterCodec = Codec.BYTE1;
+              return results;
+        }
+
+        // Consider a population codec (but can't be nested)
+        if(effort > 3 && !name.equals("POPULATION")) {
+            int numDistinctValues = bandData.numDistinctValues();
+            float distinctValuesAsProportion = (float)numDistinctValues / (float)band.length;
+
+            // Note: these values have been tuned - please test carefully if changing them
+            if(numDistinctValues < 100 || distinctValuesAsProportion < 0.02 ||  (effort > 6 && distinctValuesAsProportion < 0.04)) { // TODO: tweak
+                encodeWithPopulationCodec(name, band, defaultCodec, bandData, results);
+                if(timeToStop(results)) {
+                    return results;
+                }
+            }
+        }
+
+        List codecFamiliesToTry = new ArrayList();
+
+        // See if the deltas are mainly small increments
+        if(bandData.mainlyPositiveDeltas() && bandData.mainlySmallDeltas()) {
+            codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs2);
+        }
+
+        if (bandData.wellCorrelated()) { // Try delta encodings
+            if (bandData.mainlyPositiveDeltas()) {
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs3);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs4);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs5);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs3);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs4);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs5);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs2);
+            } else {
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs3);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs2);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs4);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs5);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaSignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaSignedCodecs2);
+            }
+        } else {
+            if (bandData.anyNegatives()) {
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaSignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaSignedCodecs2);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs2);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs3);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs4);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaSignedCodecs5);
+            } else {
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs3);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs4);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs5);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.nonDeltaUnsignedCodecs2);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs1);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs3);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs4);
+                codecFamiliesToTry.add(CanonicalCodecFamilies.deltaUnsignedCodecs5);
+            }
+        }
+        if(name.equalsIgnoreCase("cpint")) {
+            System.out.print("");
+        }
+
+        for (Iterator iterator = codecFamiliesToTry.iterator(); iterator
+                .hasNext();) {
+            BHSDCodec[] family = (BHSDCodec[]) iterator.next();
+            tryCodecs(name, band, defaultCodec, bandData, results, encoded,
+                    family);
+            if (timeToStop(results)) {
+                break;
+            }
+        }
+
+        return results;
+    }
+
+
+    private boolean timeToStop(BandAnalysisResults results) {
+        // if tried more than effort number of codecs for this band then return
+        // Note: these values have been tuned - please test carefully if changing them
+        if(effort > 6) {
+            return results.numCodecsTried >= effort * 2;
+        }
+        return results.numCodecsTried >= effort;
+        // May want to also check how much we've saved if performance needs improving, e.g. saved more than effort*2 %
+        // || (float)results.saved/(float)results.encodedBand.length > (float)effort * 2/100;
+    }
+
+    private void tryCodecs(String name, int[] band, BHSDCodec defaultCodec, BandData bandData,
+            BandAnalysisResults results, byte[] encoded,
+            BHSDCodec[] potentialCodecs) throws Pack200Exception {
+        for (int i = 0; i < potentialCodecs.length; i++) {
+            BHSDCodec potential = potentialCodecs[i];
+            if(potential.equals(defaultCodec)) {
+                return; // don't try codecs with greater cardinality in the same 'family' as the default codec as there won't be any savings
+            }
+            if (potential.isDelta()) {
+                if (potential.largest() >= bandData.largestDelta
+                        && potential.smallest() <= bandData.smallestDelta
+                        && potential.largest() >= bandData.largest
+                        && potential.smallest() <= bandData.smallest) {
+                    // TODO: can represent some negative deltas with overflow
+                    byte[] encoded2 = potential.encode(band);
+                    results.numCodecsTried++;
+                    results.codecsTried.add(potential);
+                    byte[] specifierEncoded = defaultCodec.encode(CodecEncoding
+                            .getSpecifier(potential, null));
+                    int saved = encoded.length - encoded2.length
+                            - specifierEncoded.length;
+                    if (saved > results.saved) {
+                        results.betterCodec = potential;
+                        results.encodedBand = encoded2;
+                        results.saved = saved;
+                    }
+                }
+            } else if (potential.largest() >= bandData.largest
+                    && potential.smallest() <= bandData.smallest) {
+                byte[] encoded2 = potential.encode(band);
+                results.numCodecsTried++;
+                results.codecsTried.add(potential);
+                byte[] specifierEncoded = defaultCodec.encode(CodecEncoding
+                        .getSpecifier(potential, null));
+                int saved = encoded.length - encoded2.length
+                        - specifierEncoded.length;
+                if (saved > results.saved) {
+                    results.betterCodec = potential;
+                    results.encodedBand = encoded2;
+                    results.saved = saved;
+                }
+            }
+            if(timeToStop(results)) {
+                return;
+            }
+        }
     }
 
     public boolean isPredictableSourceFileName(String className, String sourceFileName) {
@@ -113,6 +301,201 @@
         return className.equals(sourceFileName);
     }
 
+// This could be useful if further enhancements are done but is not currently used
+//
+//    private void encodeWithRunCodec(String name, int[] band, int index,
+//            BHSDCodec defaultCodec, BandData bandData,
+//            BandAnalysisResults results) throws Pack200Exception {
+//        int[] firstBand = new int[index];
+//        int[] secondBand = new int[band.length - index];
+//        System.arraycopy(band, 0, firstBand, 0, index);
+//        System.arraycopy(band, index, secondBand, 0, secondBand.length);
+//        BandAnalysisResults firstResults = analyseBand(name + "A", firstBand, defaultCodec);
+//        BandAnalysisResults secondResults = analyseBand(name + "B", secondBand, defaultCodec);
+//        int specifier = 117;
+//        byte[] specifierEncoded = defaultCodec.encode(new int[] {specifier});
+//        int totalLength = firstResults.encodedBand.length + secondResults.encodedBand.length + specifierEncoded.length + 4; // TODO actual
+//        if(totalLength < results.encodedBand.length) {
+//            System.out.println("using run codec");
+//            results.saved += results.encodedBand.length - totalLength;
+//            byte[] encodedBand = new byte[specifierEncoded.length + firstResults.encodedBand.length + secondResults.encodedBand.length];
+//            System.arraycopy(specifierEncoded, 0, encodedBand, 0, specifierEncoded.length);
+//            System.arraycopy(firstResults.encodedBand, 0, encodedBand, specifierEncoded.length, firstResults.encodedBand.length);
+//            System.arraycopy(secondResults.encodedBand, 0, encodedBand, specifierEncoded.length + firstResults.encodedBand.length, secondResults.encodedBand.length);
+//            results.encodedBand = encodedBand;
+//            results.betterCodec = new RunCodec(index, firstResults.betterCodec, secondResults.betterCodec);
+//        }
+//    }
+
+    private void encodeWithPopulationCodec(String name, int[] band,
+            BHSDCodec defaultCodec, BandData bandData, BandAnalysisResults results) throws Pack200Exception {
+        results.numCodecsTried += 3; // quite a bit more effort to try this codec
+        final Map distinctValues = bandData.distinctValues;
+
+        List favoured = new ArrayList();
+        for (Iterator iterator = distinctValues.keySet().iterator(); iterator
+                .hasNext();) {
+            Integer value = (Integer) iterator.next();
+            Integer count = (Integer) distinctValues.get(value);
+            if(count.intValue() > 2 || distinctValues.size() < 256) { // TODO: tweak
+                favoured.add(value);
+            }
+        }
+
+        // Sort the favoured list with the most commonly occurring first
+        if(distinctValues.size() > 255) {
+            Collections.sort(favoured, new Comparator() {
+                public int compare(Object arg0, Object arg1) {
+                    return ((Integer)distinctValues.get(arg1)).compareTo((Integer)distinctValues.get(arg0));
+                }
+            });
+        }
+
+        IntList unfavoured = new IntList();
+        Map favouredToIndex = new HashMap();
+        for (int i = 0; i < favoured.size(); i++) {
+            Integer value = (Integer) favoured.get(i);
+            favouredToIndex.put(value, new Integer(i));
+        }
+
+        int[] tokens = new int[band.length];
+        for (int i = 0; i < band.length; i++) {
+            Integer favouredIndex = (Integer)favouredToIndex.get(new Integer(band[i]));
+            if(favouredIndex == null) {
+                tokens[i] = 0;
+                unfavoured.add(band[i]);
+            } else {
+                tokens[i] = favouredIndex.intValue() + 1;
+            }
+        }
+        favoured.add(favoured.get(favoured.size() - 1)); // repeat last value
+        int[] favouredBand = listToArray(favoured);
+        int[] unfavouredBand = unfavoured.toArray();
+
+        // Analyse the three bands to get the best codec
+        BandAnalysisResults favouredResults = analyseBand("POPULATION", favouredBand, defaultCodec);
+        BandAnalysisResults unfavouredResults = analyseBand("POPULATION", unfavouredBand, defaultCodec);
+
+        int tdefL = 0;
+        int l = 0;
+        Codec tokenCodec = null;
+        byte[] tokensEncoded;
+        int k = favoured.size() - 1;
+        if(k < 256) {
+            tdefL = 1;
+            tokensEncoded = Codec.BYTE1.encode(tokens);
+        } else {
+            BandAnalysisResults tokenResults = analyseBand("POPULATION", tokens, defaultCodec);
+            tokenCodec = tokenResults.betterCodec;
+            tokensEncoded = tokenResults.encodedBand;
+            if(tokenCodec == null) {
+                tokenCodec = defaultCodec;
+            }
+            l = ((BHSDCodec) tokenCodec).getL();
+            int h = ((BHSDCodec) tokenCodec).getH();
+            int s = ((BHSDCodec) tokenCodec).getS();
+            int b = ((BHSDCodec) tokenCodec).getB();
+            int d = ((BHSDCodec) tokenCodec).isDelta() ? 1 : 0;
+            if(s == 0 && d == 0) {
+                boolean canUseTDefL = true;
+                if(b > 1) {
+                    BHSDCodec oneLowerB = new BHSDCodec(b-1, h);
+                    if(oneLowerB.largest() >= k) {
+                        canUseTDefL = false;
+                    }
+                }
+                if(canUseTDefL) {
+                    switch (l) {
+                    case 4:
+                        tdefL = 1;
+                        break;
+                    case 8:
+                        tdefL = 2;
+                        break;
+                    case 16:
+                        tdefL = 3;
+                        break;
+                    case 32:
+                        tdefL = 4;
+                        break;
+                    case 64:
+                        tdefL = 5;
+                        break;
+                    case 128:
+                        tdefL = 6;
+                        break;
+                    case 192:
+                        tdefL = 7;
+                        break;
+                    case 224:
+                        tdefL = 8;
+                        break;
+                    case 240:
+                        tdefL = 9;
+                        break;
+                    case 248:
+                        tdefL = 10;
+                        break;
+                    case 252:
+                        tdefL = 11;
+                        break;
+                    }
+                }
+            }
+        }
+
+        byte[] favouredEncoded = favouredResults.encodedBand;
+        byte[] unfavouredEncoded = unfavouredResults.encodedBand;
+        Codec favouredCodec = favouredResults.betterCodec;
+        Codec unfavouredCodec = unfavouredResults.betterCodec;
+
+        int specifier = 141 + (favouredCodec == null ? 1 : 0) + (4 * tdefL) + (unfavouredCodec == null ? 2 : 0);
+        IntList extraBandMetadata = new IntList(3);
+        if(favouredCodec != null) {
+            int[] specifiers = CodecEncoding.getSpecifier(favouredCodec, null);
+            for (int i = 0; i < specifiers.length; i++) {
+                extraBandMetadata.add(specifiers[i]);
+            }
+        }
+        if(tdefL == 0) {
+            int[] specifiers = CodecEncoding.getSpecifier(tokenCodec, null);
+            for (int i = 0; i < specifiers.length; i++) {
+                extraBandMetadata.add(specifiers[i]);
+            }
+        }
+        if(unfavouredCodec != null) {
+            int[] specifiers = CodecEncoding.getSpecifier(unfavouredCodec, null);
+            for (int i = 0; i < specifiers.length; i++) {
+                extraBandMetadata.add(specifiers[i]);
+            }
+        }
+        int[] extraMetadata = extraBandMetadata.toArray();
+        byte[] extraMetadataEncoded = Codec.UNSIGNED5.encode(extraMetadata);
+        if(defaultCodec.isSigned()) {
+            specifier = -1 -specifier;
+        } else {
+            specifier = specifier + defaultCodec.getL();
+        }
+        byte[] firstValueEncoded = defaultCodec.encode(new int[] {specifier});
+        int totalBandLength = firstValueEncoded.length + favouredEncoded.length + tokensEncoded.length + unfavouredEncoded.length;
+
+        if(totalBandLength + extraMetadataEncoded.length < results.encodedBand.length) {
+            results.saved += results.encodedBand.length - (totalBandLength + extraMetadataEncoded.length);
+            byte[] encodedBand = new byte[totalBandLength];
+            System.arraycopy(firstValueEncoded, 0, encodedBand, 0, firstValueEncoded.length);
+            System.arraycopy(favouredEncoded, 0, encodedBand, firstValueEncoded.length, favouredEncoded.length);
+            System.arraycopy(tokensEncoded, 0, encodedBand, firstValueEncoded.length + favouredEncoded.length, tokensEncoded.length);
+            System.arraycopy(unfavouredEncoded, 0, encodedBand, firstValueEncoded.length + favouredEncoded.length + tokensEncoded.length, unfavouredEncoded.length);
+            results.encodedBand = encodedBand;
+            results.extraMetadata = extraMetadata;
+            if(l != 0) {
+                results.betterCodec = new PopulationCodec(favouredCodec, l, unfavouredCodec);
+            } else {
+                results.betterCodec = new PopulationCodec(favouredCodec, tokenCodec, unfavouredCodec);
+            }
+        }
+    }
+
     protected byte[] encodeFlags(String name, long[] flags, BHSDCodec loCodec, BHSDCodec hiCodec,
             boolean haveHiFlags) throws Pack200Exception {
         if(!haveHiFlags) {
@@ -199,4 +582,112 @@
         return flatArray;
     }
 
+    /**
+     * BandData represents information about a band, e.g. largest value etc
+     * and is used in the heuristics that calculate whether an alternative
+     * Codec could make the encoded band smaller.
+     */
+    public class BandData {
+
+        private final int[] band;
+        private int smallest = Integer.MAX_VALUE;
+        private int largest = Integer.MIN_VALUE;
+        private int smallestDelta;
+        private int largestDelta;
+
+        private int deltaIsAscending = 0;
+        private int smallDeltaCount = 0;
+
+        private double averageAbsoluteDelta = 0;
+        private double averageAbsoluteValue = 0;
+
+        private Map distinctValues;
+
+        public BandData(int[] band) {
+            this.band = band;
+            Integer one = new Integer(1);
+            for (int i = 0; i < band.length; i++) {
+                if(band[i] < smallest) {
+                    smallest = band[i];
+                }
+                if(band[i] > largest) {
+                    largest = band[i];
+                }
+                if(i != 0) {
+                    int delta = band[i] - band[i - 1];
+                    if(delta < smallestDelta) {
+                        smallestDelta = delta;
+                    }
+                    if(delta > largestDelta) {
+                        largestDelta = delta;
+                    }
+                    if(delta >= 0) {
+                        deltaIsAscending++;
+                    }
+                    averageAbsoluteDelta += (double)Math.abs(delta)/(double)(band.length - 1);
+                    if(Math.abs(delta) < 256) {
+                        smallDeltaCount++;
+                    }
+                } else {
+                    smallestDelta = band[0];
+                    largestDelta = band[0];
+                }
+                averageAbsoluteValue += (double)Math.abs(band[i])/(double)band.length;
+                if(effort > 3) { // do calculations needed to consider population codec
+                    if(distinctValues == null) {
+                        distinctValues = new HashMap();
+                    }
+                    Integer value = new Integer(band[i]);
+                    Integer count = (Integer) distinctValues.get(value);
+                    if(count == null) {
+                        count = one;
+                    } else {
+                        count = new Integer(count.intValue() + 1);
+                    }
+                    distinctValues.put(value, count);
+                }
+            }
+        }
+
+        public boolean mainlySmallDeltas() {
+            // Note: the value below has been tuned - please test carefully if changing it
+            return (float)smallDeltaCount/(float)band.length > 0.7F;
+        }
+        public boolean wellCorrelated() {
+            // Note: the value below has been tuned - please test carefully if changing it
+            return averageAbsoluteDelta * 3.1 < averageAbsoluteValue;
+        }
+
+        public boolean mainlyPositiveDeltas() {
+            // Note: the value below has been tuned - please test carefully if changing it
+            return (float)deltaIsAscending/(float)band.length > 0.95F;
+        }
+
+        public boolean anyNegatives() {
+            return smallest < 0;
+        }
+
+        public int numDistinctValues() {
+            if(distinctValues == null) {
+                return band.length;
+            }
+            return distinctValues.size();
+        }
+
+    }
+
+    public class BandAnalysisResults {
+
+        private final List codecsTried = new ArrayList(effort);
+
+        private int numCodecsTried = 0;
+        private int saved = 0;
+
+        private int[] extraMetadata;
+
+        private byte[] encodedBand;
+        private Codec betterCodec;
+
+    }
+
 }

Added: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java?rev=784030&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java (added)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java Fri Jun 12 08:35:08 2009
@@ -0,0 +1,210 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.harmony.pack200;
+
+/**
+ * Sets of codecs that share characteristics. Mainly used for different effort
+ * compression heuristics in BandSet.
+ */
+public class CanonicalCodecFamilies {
+
+    // Families of codecs for bands of positive integers that do not correlate
+    // well (i.e. would not benefit from delta encoding)
+
+    public static BHSDCodec[] nonDeltaUnsignedCodecs1 = new BHSDCodec[] {
+     // (1,256) is a special case and is considered separately so shouldn't be included here
+//        CodecEncoding.getCanonicalCodec(1), // (1,256)
+        CodecEncoding.getCanonicalCodec(5), // (2,256)
+        CodecEncoding.getCanonicalCodec(9), // (3,256)
+        CodecEncoding.getCanonicalCodec(13) // (4,256)
+    };
+
+    public static BHSDCodec[] nonDeltaUnsignedCodecs2 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(17), // (5,4)
+        CodecEncoding.getCanonicalCodec(20), // (5,16)
+        CodecEncoding.getCanonicalCodec(23), // (5,32)
+        CodecEncoding.getCanonicalCodec(26), // (5,64)
+        CodecEncoding.getCanonicalCodec(29) // (5,128)
+    };
+
+    public static BHSDCodec[] nonDeltaUnsignedCodecs3 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(47), // (2,192)
+        CodecEncoding.getCanonicalCodec(48), // (2,224)
+        CodecEncoding.getCanonicalCodec(49), // (2,240)
+        CodecEncoding.getCanonicalCodec(50), // (2,248)
+        CodecEncoding.getCanonicalCodec(51) // (2,252)
+    };
+
+    public static BHSDCodec[] nonDeltaUnsignedCodecs4 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(70), // (3,192)
+        CodecEncoding.getCanonicalCodec(71), // (3,224)
+        CodecEncoding.getCanonicalCodec(72), // (3,240)
+        CodecEncoding.getCanonicalCodec(73), // (3,248)
+        CodecEncoding.getCanonicalCodec(74) // (3,252)
+    };
+
+    public static BHSDCodec[] nonDeltaUnsignedCodecs5 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(93), // (4,192)
+        CodecEncoding.getCanonicalCodec(94), // (4,224)
+        CodecEncoding.getCanonicalCodec(95), // (4,240)
+        CodecEncoding.getCanonicalCodec(96), // (4,248)
+        CodecEncoding.getCanonicalCodec(97) // (4,252)
+    };
+
+    // Families of codecs for bands of positive integers that do correlate well
+    // and would benefit from delta encoding
+
+    public static BHSDCodec[] deltaUnsignedCodecs1 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(3), // (1,256,0,1)
+        CodecEncoding.getCanonicalCodec(7), // (2,256,0,1)
+        CodecEncoding.getCanonicalCodec(11), // (3,256,0,1)
+        CodecEncoding.getCanonicalCodec(15) // (4,256,0,1)
+    };
+
+    public static BHSDCodec[] deltaUnsignedCodecs2 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(32), // (5,4,0,1)
+        CodecEncoding.getCanonicalCodec(35), // (5,16,0,1)
+        CodecEncoding.getCanonicalCodec(38), // (5,32,0,1)
+        CodecEncoding.getCanonicalCodec(41), // (5,64,0,1)
+        CodecEncoding.getCanonicalCodec(44) // (5,128,0,1)
+    };
+
+    public static BHSDCodec[] deltaUnsignedCodecs3 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(52), // (2,8,0,1)
+        CodecEncoding.getCanonicalCodec(54), // (2,16,0,1)
+        CodecEncoding.getCanonicalCodec(56), // (2,32,0,1)
+        CodecEncoding.getCanonicalCodec(58), // (2,64,0,1)
+        CodecEncoding.getCanonicalCodec(60), // (2,128,0,1)
+        CodecEncoding.getCanonicalCodec(62), // (2,192,0,1)
+        CodecEncoding.getCanonicalCodec(64), // (2,224,0,1)
+        CodecEncoding.getCanonicalCodec(66), // (2,240,0,1)
+        CodecEncoding.getCanonicalCodec(68) // (2,248,0,1)
+    };
+
+    public static BHSDCodec[] deltaUnsignedCodecs4 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(75), // (3,8,0,1)
+        CodecEncoding.getCanonicalCodec(77), // (3,16,0,1)
+        CodecEncoding.getCanonicalCodec(79), // (3,32,0,1)
+        CodecEncoding.getCanonicalCodec(81), // (3,64,0,1)
+        CodecEncoding.getCanonicalCodec(83), // (3,128,0,1)
+        CodecEncoding.getCanonicalCodec(85), // (3,192,0,1)
+        CodecEncoding.getCanonicalCodec(87), // (3,224,0,1)
+        CodecEncoding.getCanonicalCodec(89), // (3,240,0,1)
+        CodecEncoding.getCanonicalCodec(91) // (3,248,0,1)
+    };
+
+    public static BHSDCodec[] deltaUnsignedCodecs5 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(98), // (4,8,0,1)
+        CodecEncoding.getCanonicalCodec(100), // (4,16,0,1)
+        CodecEncoding.getCanonicalCodec(102), // (4,32,0,1)
+        CodecEncoding.getCanonicalCodec(104), // (4,64,0,1)
+        CodecEncoding.getCanonicalCodec(106), // (4,128,0,1)
+        CodecEncoding.getCanonicalCodec(108), // (4,192,0,1)
+        CodecEncoding.getCanonicalCodec(110), // (4,224,0,1)
+        CodecEncoding.getCanonicalCodec(112), // (4,240,0,1)
+        CodecEncoding.getCanonicalCodec(114) // (4,248,0,1)
+    };
+
+    // Families of codecs for bands containing positive and negative integers
+    // that do correlate well (i.e. delta encoding is used)
+
+    public static BHSDCodec[] deltaSignedCodecs1 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(4), // (1,256,1,1)
+        CodecEncoding.getCanonicalCodec(8), // (2,256,1,1)
+        CodecEncoding.getCanonicalCodec(12), // (3,256,1,1)
+        CodecEncoding.getCanonicalCodec(16) // (4,256,1,1)
+    };
+
+    public static BHSDCodec[] deltaSignedCodecs2 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(33), // (5,4,1,1)
+        CodecEncoding.getCanonicalCodec(36), // (5,16,1,1)
+        CodecEncoding.getCanonicalCodec(39), // (5,32,1,1)
+        CodecEncoding.getCanonicalCodec(42), // (5,64,1,1)
+        CodecEncoding.getCanonicalCodec(45) // (5,128,1,1)
+    };
+
+    public static BHSDCodec[] deltaSignedCodecs3 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(53), // (2,8,1,1)
+        CodecEncoding.getCanonicalCodec(55), // (2,16,1,1)
+        CodecEncoding.getCanonicalCodec(57), // (2,32,1,1)
+        CodecEncoding.getCanonicalCodec(59), // (2,64,1,1)
+        CodecEncoding.getCanonicalCodec(61), // (2,128,1,1)
+        CodecEncoding.getCanonicalCodec(63), // (2,192,1,1)
+        CodecEncoding.getCanonicalCodec(65), // (2,224,1,1)
+        CodecEncoding.getCanonicalCodec(67), // (2,240,1,1)
+        CodecEncoding.getCanonicalCodec(69) // (2,248,1,1)
+    };
+
+    public static BHSDCodec[] deltaSignedCodecs4 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(76), // (3,8,1,1)
+        CodecEncoding.getCanonicalCodec(78), // (3,16,1,1)
+        CodecEncoding.getCanonicalCodec(80), // (3,32,1,1)
+        CodecEncoding.getCanonicalCodec(82), // (3,64,1,1)
+        CodecEncoding.getCanonicalCodec(84), // (3,128,1,1)
+        CodecEncoding.getCanonicalCodec(86), // (3,192,1,1)
+        CodecEncoding.getCanonicalCodec(88), // (3,224,1,1)
+        CodecEncoding.getCanonicalCodec(90), // (3,240,1,1)
+        CodecEncoding.getCanonicalCodec(92) // (3,248,1,1)
+    };
+
+    public static BHSDCodec[] deltaSignedCodecs5 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(99), // (4,8,1,1)
+        CodecEncoding.getCanonicalCodec(101), // (4,16,1,1)
+        CodecEncoding.getCanonicalCodec(103), // (4,32,1,1)
+        CodecEncoding.getCanonicalCodec(105), // (4,64,1,1)
+        CodecEncoding.getCanonicalCodec(107), // (4,128,1,1)
+        CodecEncoding.getCanonicalCodec(109), // (4,192,1,1)
+        CodecEncoding.getCanonicalCodec(111), // (4,224,1,1)
+        CodecEncoding.getCanonicalCodec(113), // (4,240,1,1)
+        CodecEncoding.getCanonicalCodec(115) // (4,248,1,1)
+    };
+
+    public static BHSDCodec[] deltaDoubleSignedCodecs1 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(34), // (5,4,2,1)
+        CodecEncoding.getCanonicalCodec(37), // (5,16,2,1)
+        CodecEncoding.getCanonicalCodec(40), // (5,32,2,1)
+        CodecEncoding.getCanonicalCodec(43), // (5,64,2,1)
+        CodecEncoding.getCanonicalCodec(46) // (5,128,2,1)
+    };
+
+    // Families of codecs for bands containing positive and negative values that
+    // do not correlate well (i.e. delta encoding is not used)
+
+    public static BHSDCodec[] nonDeltaSignedCodecs1 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(2), // (1,256,1)
+        CodecEncoding.getCanonicalCodec(6), // (2,256,1)
+        CodecEncoding.getCanonicalCodec(10), // (3,256,1)
+        CodecEncoding.getCanonicalCodec(14) // (4,256,1)
+    };
+
+    public static BHSDCodec[] nonDeltaSignedCodecs2 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(18), // (5,4,1)
+        CodecEncoding.getCanonicalCodec(21), // (5,16,1)
+        CodecEncoding.getCanonicalCodec(24), // (5,32,1)
+        CodecEncoding.getCanonicalCodec(27), // (5,64,1)
+        CodecEncoding.getCanonicalCodec(30) // (5,128,1)
+    };
+
+    public static BHSDCodec[] nonDeltaDoubleSignedCodecs1 = new BHSDCodec[] {
+        CodecEncoding.getCanonicalCodec(19), // (5,4,2)
+        CodecEncoding.getCanonicalCodec(22), // (5,16,2)
+        CodecEncoding.getCanonicalCodec(25), // (5,32,2)
+        CodecEncoding.getCanonicalCodec(28), // (5,64,2)
+        CodecEncoding.getCanonicalCodec(31) // (5,128,2)
+    };
+
+}

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CanonicalCodecFamilies.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Codec.java Fri Jun 12 08:35:08 2009
@@ -85,6 +85,8 @@
      */
     public static final BHSDCodec UNSIGNED5 = new BHSDCodec(5, 64);
 
+    public int lastBandLength;
+
     /**
      * Decode a sequence of bytes from the given input stream, returning the
      * value as a long. Note that this method can only be applied for non-delta
@@ -99,7 +101,7 @@
      * @throws Pack200Exception
      *             if the encoding is a delta encoding
      */
-    public abstract long decode(InputStream in) throws IOException,
+    public abstract int decode(InputStream in) throws IOException,
             Pack200Exception;
 
     /**
@@ -112,7 +114,7 @@
      * @return the encoded bytes
      * @throws Pack200Exception
      */
-    public abstract byte[] encode(long value, long last)
+    public abstract byte[] encode(int value, int last)
             throws Pack200Exception;
 
     /**
@@ -124,7 +126,7 @@
      * @return the encoded bytes
      * @throws Pack200Exception
      */
-    public abstract byte[] encode(long value) throws Pack200Exception;
+    public abstract byte[] encode(int value) throws Pack200Exception;
 
     /**
      * Decode a sequence of bytes from the given input stream, returning the
@@ -154,7 +156,7 @@
      *             if there is a problem decoding the value or that the value is
      *             invalid
      */
-    public abstract long decode(InputStream in, long last) throws IOException,
+    public abstract int decode(InputStream in, long last) throws IOException,
             Pack200Exception;
 
     /**
@@ -168,36 +170,6 @@
      *            the number of values to decode
      * @param in
      *            the input stream to read from
-     * @return an array of <code>long</code> values corresponding to values
-     *         decoded
-     * @throws IOException
-     *             if there is a problem reading from the underlying input
-     *             stream
-     * @throws Pack200Exception
-     *             if there is a problem decoding the value or that the value is
-     *             invalid
-     */
-    public long[] decode(int n, InputStream in) throws IOException,
-            Pack200Exception {
-        long result[] = new long[n];
-        long last = 0;
-        for (int i = 0; i < n; i++) {
-            result[i] = last = decode(in, last);
-        }
-        return result;
-    }
-
-    /**
-     * Decodes a sequence of <code>n</code> values from <code>in</code>.
-     * This should probably be used in most cases, since some codecs (such as
-     *
-     * @{link PopCodec}) only work when the number of values to be read is
-     *        known.
-     *
-     * @param n
-     *            the number of values to decode
-     * @param in
-     *            the input stream to read from
      * @return an array of <code>int</code> values corresponding to values
      *         decoded
      * @throws IOException
@@ -209,38 +181,10 @@
      */
     public int[] decodeInts(int n, InputStream in) throws IOException,
             Pack200Exception {
+        lastBandLength = 0;
         int result[] = new int[n];
         int last = 0;
         for (int i = 0; i < n; i++) {
-            result[i] = last = (int) decode(in, last);
-        }
-        return result;
-    }
-
-    /**
-     * Decodes a sequence of <code>n</code> values from <code>in</code>.
-     *
-     * @param n
-     *            the number of values to decode
-     * @param in
-     *            the input stream to read from
-     * @param firstValue
-     *            the first value in the band if it has already been read
-     * @return an array of <code>long</code> values corresponding to values
-     *         decoded, with firstValue as the first value in the array.
-     * @throws IOException
-     *             if there is a problem reading from the underlying input
-     *             stream
-     * @throws Pack200Exception
-     *             if there is a problem decoding the value or that the value is
-     *             invalid
-     */
-    public long[] decode(int n, InputStream in, long firstValue)
-            throws IOException, Pack200Exception {
-        long result[] = new long[n + 1];
-        result[0] = firstValue;
-        long last = firstValue;
-        for (int i = 1; i < n + 1; i++) {
             result[i] = last = decode(in, last);
         }
         return result;
@@ -270,7 +214,7 @@
         result[0] = firstValue;
         int last = firstValue;
         for (int i = 1; i < n + 1; i++) {
-            result[i] = last = (int) decode(in, last);
+            result[i] = last = decode(in, last);
         }
         return result;
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CodecEncoding.java Fri Jun 12 08:35:08 2009
@@ -34,7 +34,7 @@
      * one of the standard encodings. The following values are defined in the
      * Pack200 specification, and this array cannot be changed.
      */
-    private static final Codec[] canonicalCodec = { null,
+    private static final BHSDCodec[] canonicalCodec = { null,
             new BHSDCodec(1, 256), new BHSDCodec(1, 256, 1),
             new BHSDCodec(1, 256, 0, 1), new BHSDCodec(1, 256, 1, 1),
             new BHSDCodec(2, 256), new BHSDCodec(2, 256, 1),
@@ -292,7 +292,7 @@
             int fDef = favouredCodec.equals(defaultForBand) ? 1 : 0;
             int uDef = unfavouredCodec.equals(defaultForBand) ? 1 : 0;
             int tDefL = 0;
-            long[] favoured = populationCodec.getFavoured();
+            int[] favoured = populationCodec.getFavoured();
             if(favoured != null) {
                 int k = favoured.length;
                 if(tokenCodec == Codec.BYTE1) {
@@ -334,4 +334,8 @@
 
         return null;
     }
+
+    public static BHSDCodec getCanonicalCodec(int i) {
+        return canonicalCodec[i];
+    }
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java Fri Jun 12 08:35:08 2009
@@ -93,9 +93,9 @@
         writeCpClass(out);
         writeCpSignature(out);
         writeCpDescr(out);
-        writeCpMethodOrField(cp_Field, out);
-        writeCpMethodOrField(cp_Method, out);
-        writeCpMethodOrField(cp_Imethod, out);
+        writeCpMethodOrField(cp_Field, out, "cp_Field");
+        writeCpMethodOrField(cp_Method, out, "cp_Method");
+        writeCpMethodOrField(cp_Imethod, out, "cp_Imethod");
     }
 
     private void writeCpUtf8(OutputStream out) throws IOException,
@@ -175,7 +175,7 @@
             cpInt[i] = integer.getInt();
             i++;
         }
-        out.write(encodeBandInt("cpInt", cpInt, Codec.UDELTA5));
+        out.write(encodeBandInt("cp_Int", cpInt, Codec.UDELTA5));
     }
 
     private void writeCpFloat(OutputStream out) throws IOException,
@@ -187,7 +187,7 @@
             cpFloat[i] = Float.floatToIntBits(fl.getFloat());
             i++;
         }
-        out.write(encodeBandInt("cpFloat", cpFloat, Codec.UDELTA5));
+        out.write(encodeBandInt("cp_Float", cpFloat, Codec.UDELTA5));
     }
 
     private void writeCpLong(OutputStream out) throws IOException,
@@ -278,11 +278,11 @@
             cpDescrType[i] = nameAndType.getTypeIndex();
             i++;
         }
-        out.write(encodeBandInt("cpDescrName", cpDescrName, Codec.DELTA5));
-        out.write(encodeBandInt("cpDescrType", cpDescrType, Codec.UDELTA5));
+        out.write(encodeBandInt("cp_Descr_Name", cpDescrName, Codec.DELTA5));
+        out.write(encodeBandInt("cp_Descr_Type", cpDescrType, Codec.UDELTA5));
     }
 
-    private void writeCpMethodOrField(Set cp, OutputStream out)
+    private void writeCpMethodOrField(Set cp, OutputStream out, String name)
             throws IOException, Pack200Exception {
         int[] cp_methodOrField_class = new int[cp.size()];
         int[] cp_methodOrField_desc = new int[cp.size()];
@@ -293,9 +293,9 @@
             cp_methodOrField_desc[i] = mOrF.getDescIndex();
             i++;
         }
-        out.write(encodeBandInt("cp_methodOrField_class",
+        out.write(encodeBandInt(name + "_class",
                 cp_methodOrField_class, Codec.DELTA5));
-        out.write(encodeBandInt("cp_methodOrField_desc", cp_methodOrField_desc,
+        out.write(encodeBandInt(name + "_desc", cp_methodOrField_desc,
                 Codec.UDELTA5));
     }
 

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java Fri Jun 12 08:35:08 2009
@@ -104,7 +104,7 @@
         int index = 0;
         for (int i = 0; i < bytes.length; i++) {
             for (int j = 0; j < bytes[i].length; j++) {
-                band[index++] = bytes[i][j];
+                band[index++] = bytes[i][j] & 0xFF;
             }
         }
         return band;

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/PopulationCodec.java Fri Jun 12 08:35:08 2009
@@ -22,7 +22,7 @@
 
 /**
  * A PopulationCodec is a Codec that is well suited to encoding data that shows
- * statistical or repetetive patterns, containign for example a few numbers
+ * statistical or repetitive patterns, containing for example a few numbers
  * which are repeated a lot throughout the set, but not necessarily
  * sequentially.
  */
@@ -32,12 +32,12 @@
     private Codec tokenCodec;
     private final Codec unvafouredCodec;
     private int l;
-    private long[] favoured;
+    private int[] favoured;
 
-    public PopulationCodec(Codec favouredCodec, Codec tableCodec,
+    public PopulationCodec(Codec favouredCodec, Codec tokenCodec,
             Codec unvafouredCodec) {
         this.favouredCodec = favouredCodec;
-        this.tokenCodec = tableCodec;
+        this.tokenCodec = tokenCodec;
         this.unvafouredCodec = unvafouredCodec;
     }
 
@@ -49,26 +49,27 @@
         this.unvafouredCodec = unvafouredCodec;
     }
 
-    public long decode(InputStream in) throws IOException, Pack200Exception {
+    public int decode(InputStream in) throws IOException, Pack200Exception {
         throw new Pack200Exception(
                 "Population encoding does not work unless the number of elements are known");
     }
 
-    public long decode(InputStream in, long last) throws IOException,
+    public int decode(InputStream in, long last) throws IOException,
             Pack200Exception {
         throw new Pack200Exception(
                 "Population encoding does not work unless the number of elements are known");
     }
 
-    public long[] decode(int n, InputStream in) throws IOException,
+    public int[] decodeInts(int n, InputStream in) throws IOException,
             Pack200Exception {
-        favoured = new long[n]; // there must be <= n values, but probably a lot
+        lastBandLength = 0;
+        favoured = new int[n]; // there must be <= n values, but probably a lot
         // less
-        long result[];
+        int result[];
         // read table of favorites first
-        long smallest = Long.MAX_VALUE;
-        long last = 0;
-        long value = 0;
+        int smallest = Integer.MAX_VALUE;
+        int last = 0;
+        int value = 0;
         int k = -1;
         while (true) {
             value = favouredCodec.decode(in, last);
@@ -83,6 +84,7 @@
             }
             last = value;
         }
+        lastBandLength += k;
         // if tokenCodec needs to be derived from the T, L and K values
         if (tokenCodec == null) {
             if (k < 256) {
@@ -102,12 +104,14 @@
             }
         }
         // read favorites
-        result = tokenCodec.decode(n, in);
+        lastBandLength += n;
+        result = tokenCodec.decodeInts(n, in);
         // read unfavorites
         last = 0;
         for (int i = 0; i < n; i++) {
-            int index = (int) result[i];
+            int index = result[i];
             if (index == 0) {
+                lastBandLength++;
                 result[i] = last = unvafouredCodec.decode(in, last);
             } else {
                 result[i] = favoured[index - 1];
@@ -116,17 +120,7 @@
         return result;
     }
 
-    public int[] decodeInts(int n, InputStream in) throws IOException,
-            Pack200Exception {
-        long[] result = decode(n, in);
-        int[] intRes = new int[result.length];
-        for (int i = 0; i < intRes.length; i++) {
-            intRes[i] = (int) result[i];
-        }
-        return intRes;
-    }
-
-    public long[] getFavoured() {
+    public int[] getFavoured() {
         return favoured;
     }
 
@@ -138,14 +132,23 @@
         return unvafouredCodec;
     }
 
-    public byte[] encode(long value, long last) throws Pack200Exception {
-        // TODO Auto-generated method stub
-        return null;
+    public byte[] encode(int value, int last) throws Pack200Exception {
+        throw new Pack200Exception(
+        "Population encoding does not work unless the number of elements are known");
     }
 
-    public byte[] encode(long value) throws Pack200Exception {
-        // TODO Auto-generated method stub
-        return null;
+    public byte[] encode(int value) throws Pack200Exception {
+        throw new Pack200Exception(
+        "Population encoding does not work unless the number of elements are known");
+    }
+
+    public byte[] encode(int[] favoured, int[] tokens, int[] unfavoured) throws Pack200Exception {
+        byte[] favouredEncoded = favouredCodec.encode(favoured);
+        byte[] tokensEncoded = tokenCodec.encode(tokens);
+        byte[] unfavouredEncoded = unvafouredCodec.encode(unfavoured);
+        byte[] band = new byte[favouredEncoded.length + tokensEncoded.length + unfavouredEncoded.length];
+
+        return band;
     }
 
     public Codec getTokenCodec() {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/RunCodec.java Fri Jun 12 08:35:08 2009
@@ -31,7 +31,7 @@
     private int k;
     private final Codec aCodec;
     private final Codec bCodec;
-    private long last;
+    private int last;
 
     public RunCodec(int k, Codec aCodec, Codec bCodec) throws Pack200Exception {
         if (k <= 0)
@@ -44,14 +44,14 @@
         this.bCodec = bCodec;
     }
 
-    public long decode(InputStream in) throws IOException, Pack200Exception {
+    public int decode(InputStream in) throws IOException, Pack200Exception {
         return decode(in, this.last);
     }
 
-    public long decode(InputStream in, long last) throws IOException,
+    public int decode(InputStream in, long last) throws IOException,
             Pack200Exception {
         if (--k >= 0) {
-            long value = aCodec.decode(in, this.last);
+            int value = aCodec.decode(in, this.last);
             this.last = (k == 0 ? 0 : value);
             return normalise(aCodec, value);
         } else {
@@ -60,7 +60,7 @@
         }
     }
 
-    private long normalise(Codec codecUsed, long value) {
+    private int normalise(Codec codecUsed, int value) {
         if (codecUsed instanceof BHSDCodec && ((BHSDCodec) codecUsed).isDelta()) {
             BHSDCodec bhsd = (BHSDCodec) codecUsed;
             long cardinality = bhsd.cardinality();
@@ -83,6 +83,7 @@
         normalise(bValues, bCodec);
         System.arraycopy(aValues, 0, band, 0, k);
         System.arraycopy(bValues, 0, band, k, n - k);
+        lastBandLength = aCodec.lastBandLength + bCodec.lastBandLength;
         return band;
     }
 
@@ -100,7 +101,7 @@
             }
         } else if (codecUsed instanceof PopulationCodec) {
             PopulationCodec popCodec = (PopulationCodec) codecUsed;
-            long[] favoured = (long[]) popCodec.getFavoured().clone();
+            int[] favoured = (int[]) popCodec.getFavoured().clone();
             Arrays.sort(favoured);
             for (int i = 0; i < band.length; i++) {
                 boolean favouredValue = Arrays.binarySearch(favoured, band[i]) > -1;
@@ -126,12 +127,12 @@
                 + "]";
     }
 
-    public byte[] encode(long value, long last) throws Pack200Exception {
+    public byte[] encode(int value, int last) throws Pack200Exception {
         // TODO Auto-generated method stub
         return null;
     }
 
-    public byte[] encode(long value) throws Pack200Exception {
+    public byte[] encode(int value) throws Pack200Exception {
         // TODO Auto-generated method stub
         return null;
     }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java Fri Jun 12 08:35:08 2009
@@ -16,6 +16,7 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -70,13 +71,19 @@
         bcBands.finaliseBands();
         fileBands.finaliseBands();
 
+        // Temporary fix because we have to encode the other bands before
+        // segmentHeader, but probably not very good performance
+        ByteArrayOutputStream tempStream = new ByteArrayOutputStream();
+
+        cpBands.pack(tempStream);
+        attributeDefinitionBands.pack(tempStream);
+        icBands.pack(tempStream);
+        classBands.pack(tempStream);
+        bcBands.pack(tempStream);
+        fileBands.pack(tempStream);
+
         segmentHeader.pack(out);
-        cpBands.pack(out);
-        attributeDefinitionBands.pack(out);
-        icBands.pack(out);
-        classBands.pack(out);
-        bcBands.pack(out);
-        fileBands.pack(out);
+        tempStream.writeTo(out);
     }
 
     private void processClasses(List classes) {
@@ -166,7 +173,7 @@
 
         public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3,
                 Object[] arg4) {
-            // TODO Auto-generated method stub
+            // TODO: Java 6 - implement support for this
 
         }
 

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/BandSet.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/BandSet.java Fri Jun 12 08:35:08 2009
@@ -108,20 +108,14 @@
             // First element should not be discarded
             band = codec.decodeInts(count - 1, in, first);
         }
-        if (codecUsed instanceof BHSDCodec && ((BHSDCodec) codecUsed).isDelta()) {
-            BHSDCodec bhsd = (BHSDCodec) codecUsed;
-            long cardinality = bhsd.cardinality();
-            for (int i = 0; i < band.length; i++) {
-                while (band[i] > bhsd.largest()) {
-                    band[i] -= cardinality;
-                }
-                while (band[i] < bhsd.smallest()) {
-                    band[i] += cardinality;
-                }
-            }
-        } else if (codecUsed instanceof PopulationCodec) {
+        // Useful for debugging -E options:
+        //if(!codecUsed.equals(codec)) {
+        //    int bytes = codecUsed.lastBandLength;
+        //    System.out.println(count + " " + name + " encoded with " + codecUsed + " "  + bytes);
+        //}
+        if (codecUsed instanceof PopulationCodec) {
             PopulationCodec popCodec = (PopulationCodec) codecUsed;
-            long[] favoured = (long[]) popCodec.getFavoured().clone();
+            int[] favoured = (int[]) popCodec.getFavoured().clone();
             Arrays.sort(favoured);
             for (int i = 0; i < band.length; i++) {
                 boolean favouredValue = Arrays.binarySearch(favoured, band[i]) > -1;

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/SegmentHeader.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/SegmentHeader.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/SegmentHeader.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/unpack200/SegmentHeader.java Fri Jun 12 08:35:08 2009
@@ -103,16 +103,16 @@
     public void read(InputStream in) throws IOException, Pack200Exception,
             Error, Pack200Exception {
 
-        long word[] = decodeScalar("archive_magic_word", in, Codec.BYTE1,
+        int word[] = decodeScalar("archive_magic_word", in, Codec.BYTE1,
                 magic.length);
         for (int m = 0; m < magic.length; m++)
             if (word[m] != magic[m])
                 throw new Error("Bad header");
-        setArchiveMinorVersion((int) decodeScalar("archive_minver", in,
+        setArchiveMinorVersion(decodeScalar("archive_minver", in,
                 Codec.UNSIGNED5));
-        setArchiveMajorVersion((int) decodeScalar("archive_majver", in,
+        setArchiveMajorVersion(decodeScalar("archive_majver", in,
                 Codec.UNSIGNED5));
-        options = new SegmentOptions((int) decodeScalar("archive_options", in,
+        options = new SegmentOptions(decodeScalar("archive_options", in,
                 Codec.UNSIGNED5));
         parseArchiveFileCounts(in);
         parseArchiveSpecialCounts(in);
@@ -290,7 +290,7 @@
                     Codec.UNSIGNED5));
             setArchiveModtime(decodeScalar("archive_modtime", in,
                     Codec.UNSIGNED5));
-            numberOfFiles = (int) decodeScalar("file_count", in,
+            numberOfFiles = decodeScalar("file_count", in,
                     Codec.UNSIGNED5);
         }
     }
@@ -298,7 +298,7 @@
     private void parseArchiveSpecialCounts(InputStream in) throws IOException,
             Pack200Exception {
         if (getOptions().hasSpecialFormats()) {
-            bandHeadersSize = (int) decodeScalar("band_headers_size", in,
+            bandHeadersSize = decodeScalar("band_headers_size", in,
                     Codec.UNSIGNED5);
             setAttributeDefinitionCount(decodeScalar("attr_definition_count",
                     in, Codec.UNSIGNED5));
@@ -307,37 +307,37 @@
 
     private void parseClassCounts(InputStream in) throws IOException,
             Pack200Exception {
-        innerClassCount = (int) decodeScalar("ic_count", in, Codec.UNSIGNED5);
-        defaultClassMinorVersion = (int) decodeScalar("default_class_minver",
+        innerClassCount = decodeScalar("ic_count", in, Codec.UNSIGNED5);
+        defaultClassMinorVersion = decodeScalar("default_class_minver",
                 in, Codec.UNSIGNED5);
-        defaultClassMajorVersion = (int) decodeScalar("default_class_majver",
+        defaultClassMajorVersion = decodeScalar("default_class_majver",
                 in, Codec.UNSIGNED5);
-        classCount = (int) decodeScalar("class_count", in, Codec.UNSIGNED5);
+        classCount = decodeScalar("class_count", in, Codec.UNSIGNED5);
     }
 
     private void parseCpCounts(InputStream in) throws IOException,
             Pack200Exception {
-        cpUTF8Count = (int) decodeScalar("cp_Utf8_count", in, Codec.UNSIGNED5);
+        cpUTF8Count = decodeScalar("cp_Utf8_count", in, Codec.UNSIGNED5);
         if (getOptions().hasCPNumberCounts()) {
-            cpIntCount = (int) decodeScalar("cp_Int_count", in, Codec.UNSIGNED5);
-            cpFloatCount = (int) decodeScalar("cp_Float_count", in,
+            cpIntCount = decodeScalar("cp_Int_count", in, Codec.UNSIGNED5);
+            cpFloatCount = decodeScalar("cp_Float_count", in,
                     Codec.UNSIGNED5);
-            cpLongCount = (int) decodeScalar("cp_Long_count", in,
+            cpLongCount = decodeScalar("cp_Long_count", in,
                     Codec.UNSIGNED5);
-            cpDoubleCount = (int) decodeScalar("cp_Double_count", in,
+            cpDoubleCount = decodeScalar("cp_Double_count", in,
                     Codec.UNSIGNED5);
         }
-        cpStringCount = (int) decodeScalar("cp_String_count", in,
+        cpStringCount = decodeScalar("cp_String_count", in,
                 Codec.UNSIGNED5);
-        cpClassCount = (int) decodeScalar("cp_Class_count", in, Codec.UNSIGNED5);
-        cpSignatureCount = (int) decodeScalar("cp_Signature_count", in,
+        cpClassCount = decodeScalar("cp_Class_count", in, Codec.UNSIGNED5);
+        cpSignatureCount = decodeScalar("cp_Signature_count", in,
                 Codec.UNSIGNED5);
-        cpDescriptorCount = (int) decodeScalar("cp_Descr_count", in,
+        cpDescriptorCount = decodeScalar("cp_Descr_count", in,
                 Codec.UNSIGNED5);
-        cpFieldCount = (int) decodeScalar("cp_Field_count", in, Codec.UNSIGNED5);
-        cpMethodCount = (int) decodeScalar("cp_Method_count", in,
+        cpFieldCount = decodeScalar("cp_Field_count", in, Codec.UNSIGNED5);
+        cpMethodCount = decodeScalar("cp_Method_count", in,
                 Codec.UNSIGNED5);
-        cpIMethodCount = (int) decodeScalar("cp_Imethod_count", in,
+        cpIMethodCount = decodeScalar("cp_Imethod_count", in,
                 Codec.UNSIGNED5);
     }
 
@@ -360,11 +360,11 @@
      *             if there is a problem decoding the value or that the value is
      *             invalid
      */
-    private long[] decodeScalar(String name, InputStream in, BHSDCodec codec,
+    private int[] decodeScalar(String name, InputStream in, BHSDCodec codec,
             int n) throws IOException, Pack200Exception {
         segment.log(Segment.LOG_LEVEL_VERBOSE, "Parsed #" + name + " (" + n
                 + ")");
-        return codec.decode(n, in);
+        return codec.decodeInts(n, in);
     }
 
     /**
@@ -386,9 +386,9 @@
      *             if there is a problem decoding the value or that the value is
      *             invalid
      */
-    private long decodeScalar(String name, InputStream in, BHSDCodec codec)
+    private int decodeScalar(String name, InputStream in, BHSDCodec codec)
             throws IOException, Pack200Exception {
-        long ret = codec.decode(in);
+        int ret = codec.decode(in);
         segment
                 .log(Segment.LOG_LEVEL_VERBOSE, "Parsed #" + name + " as "
                         + ret);

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/BHSDCodecTest.java Fri Jun 12 08:35:08 2009
@@ -42,9 +42,13 @@
                 // range of the codec
                 long largest = codec.largest();
                 long smallest = codec.isSigned() ? codec.smallest() : 0;
+                if(smallest < Integer.MIN_VALUE) smallest = Integer.MIN_VALUE;
                 long difference = (largest - smallest) / 4;
                 for (long j = smallest; j <= largest; j += difference) {
-                    byte[] encoded = codec.encode(j, 0);
+                    if(j > Integer.MAX_VALUE) {
+                        break;
+                    }
+                    byte[] encoded = codec.encode((int)j, 0);
                     long decoded = 0;
                     try {
                         decoded = codec.decode(

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java Fri Jun 12 08:35:08 2009
@@ -23,6 +23,7 @@
 import junit.framework.TestCase;
 
 import org.apache.harmony.pack200.BHSDCodec;
+import org.apache.harmony.pack200.CanonicalCodecFamilies;
 import org.apache.harmony.pack200.Codec;
 import org.apache.harmony.pack200.Pack200Exception;
 import org.apache.harmony.pack200.RunCodec;
@@ -203,8 +204,6 @@
                 (byte) 255, (byte) 191 }, 51130559, 0);
         decode(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192,
                 (byte) 192, (byte) 192, 0 }, 51130560, 0);
-        decode(Codec.UNSIGNED5, new byte[] { (byte) 255, (byte) 252,
-                (byte) 252, (byte) 252, (byte) 252 }, 0xFFFFFFFFL, 0);
         decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192 });
         decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192 });
         decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192,
@@ -212,6 +211,27 @@
         decodeFail(Codec.UNSIGNED5, new byte[] { (byte) 192, (byte) 192,
                 (byte) 192, (byte) 192 });
     }
+    public void testCodecFamilies() {
+        checkAscendingCardinalities(CanonicalCodecFamilies.nonDeltaUnsignedCodecs1);
+        checkAscendingCardinalities(CanonicalCodecFamilies.nonDeltaUnsignedCodecs2);
+        checkAscendingCardinalities(CanonicalCodecFamilies.nonDeltaUnsignedCodecs3);
+        checkAscendingCardinalities(CanonicalCodecFamilies.nonDeltaUnsignedCodecs4);
+        checkAscendingCardinalities(CanonicalCodecFamilies.nonDeltaUnsignedCodecs5);
+        checkAscendingCardinalities(CanonicalCodecFamilies.deltaUnsignedCodecs1);
+        checkAscendingCardinalities(CanonicalCodecFamilies.deltaUnsignedCodecs2);
+        checkAscendingCardinalities(CanonicalCodecFamilies.deltaUnsignedCodecs3);
+        checkAscendingCardinalities(CanonicalCodecFamilies.deltaUnsignedCodecs4);
+        checkAscendingCardinalities(CanonicalCodecFamilies.deltaUnsignedCodecs5);
+    }
+
+    private void checkAscendingCardinalities(BHSDCodec[] family) {
+        for (int i = 1; i < family.length; i++) {
+            BHSDCodec previous = family[i-1];
+            BHSDCodec codec = family[i];
+            assertTrue(codec.largest() >= previous.largest());
+            assertTrue(codec.smallest() <= previous.smallest());
+        }
+    }
 
     private void decodeFail(final Codec codec, final byte[] data)
             throws IOException, Pack200Exception {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java Fri Jun 12 08:35:08 2009
@@ -55,7 +55,7 @@
             throws IOException, Pack200Exception {
         InputStream in = new ByteArrayInputStream(data);
 
-        long[] result = new PopulationCodec(codec, codec, codec).decode(
+        int[] result = new PopulationCodec(codec, codec, codec).decodeInts(
                 expectedResult.length, in);
         assertEquals(expectedResult.length, result.length);
         for (int i = 0; i < expectedResult.length; i++) {

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ClassBandsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ClassBandsTest.java?rev=784030&r1=784029&r2=784030&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ClassBandsTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/unpack200/tests/ClassBandsTest.java Fri Jun 12 08:35:08 2009
@@ -92,8 +92,8 @@
         byte[] classThis = Codec.DELTA5.encode(1, 0);
         byte[] classSuper = Codec.DELTA5.encode(2, 0);
         byte[] classInterfaceCount = Codec.DELTA5.encode(2, 0);
-        byte[] classInterfaceRef1 = encodeBandLong(
-                new long[] { 3, 4 }, Codec.DELTA5);
+        byte[] classInterfaceRef1 = encodeBandInt(
+                new int[] { 3, 4 }, Codec.DELTA5);
         byte[] classFieldCount = Codec.DELTA5.encode(0, 0);
         byte[] classMethodCount = Codec.DELTA5.encode(0, 0);
         byte[] classFlags = Codec.UNSIGNED5.encode(0, 0);
@@ -132,10 +132,10 @@
         byte[] classInterfaceCount = Codec.DELTA5.encode(0, 0);
         byte[] classFieldCount = Codec.DELTA5.encode(0, 0);
         byte[] classMethodCount = Codec.DELTA5.encode(3, 0);
-        byte[] methodDescr = encodeBandLong(new long[] { 0, 1, 2 },
+        byte[] methodDescr = encodeBandInt(new int[] { 0, 1, 2 },
                 Codec.MDELTA5);
-        byte[] methodFlagsLo = encodeBandLong(
-                new long[] { 0, 0, 0 }, Codec.UNSIGNED5);
+        byte[] methodFlagsLo = encodeBandInt(
+                new int[] { 0, 0, 0 }, Codec.UNSIGNED5);
         byte[] classFlags = Codec.UNSIGNED5.encode(0, 0);
         byte[][] allArrays = new byte[][] { classThis, classSuper,
                 classInterfaceCount, classFieldCount, classMethodCount,
@@ -166,7 +166,7 @@
         cpDescriptor = null;
     }
 
-    public byte[] encodeBandLong(long[] data, BHSDCodec codec)
+    public byte[] encodeBandInt(int[] data, BHSDCodec codec)
             throws IOException, Pack200Exception {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         for (int i = 0; i < data.length; i++) {



Mime
View raw message