Index: lucene/facet/src/java/org/apache/lucene/util/encoding/PackedEncoder.java
===================================================================
--- lucene/facet/src/java/org/apache/lucene/util/encoding/PackedEncoder.java	(revision 0)
+++ lucene/facet/src/java/org/apache/lucene/util/encoding/PackedEncoder.java	(working copy)
@@ -0,0 +1,130 @@
+package org.apache.lucene.util.encoding;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.lucene.store.InputStreamDataInput;
+import org.apache.lucene.store.OutputStreamDataOutput;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.packed.PackedInts;
+import org.apache.lucene.util.packed.PackedInts.Reader;
+import org.apache.lucene.util.packed.PackedInts.Writer;
+
+/*
+ * 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.
+ */
+
+/** Encoder based on {@link PackedInts} */
+public class PackedEncoder extends IntEncoder {
+  
+  private int[] values = new int[16];
+  private int count = 0;
+  private int maxValue = Integer.MIN_VALUE;
+  private final float acceptableOverheadRatio;
+  
+  public PackedEncoder() {
+    this(0f);
+  }
+  
+  /**
+   * @param acceptableOverheadRatio
+   *          an acceptable overhead ratio per value
+   */
+  public PackedEncoder(float acceptableOverheadRatio) {
+    this.acceptableOverheadRatio = acceptableOverheadRatio;
+  }
+  
+  @Override
+  public void encode(int value) throws IOException {
+    if (values.length == count) {
+      values = ArrayUtil.grow(values);
+    }
+    values[count++] = value;
+    maxValue = Math.max(maxValue, value);
+  }
+  
+  @Override
+  public void reInit(OutputStream out) {
+    super.reInit(out);
+    maxValue = Integer.MIN_VALUE;
+    count = 0;
+  }
+ 
+  @Override
+  public void close() throws IOException {
+    int bitsPerValue = 1;
+    
+    if (count > 0) {
+      while ((maxValue >>= 1) != 0) {
+        ++bitsPerValue;
+      }
+    }
+    
+    final OutputStreamDataOutput osdo = new OutputStreamDataOutput(out);
+    final Writer w = PackedInts.getWriter(osdo, count, bitsPerValue,
+        acceptableOverheadRatio);
+    
+    for (int i = 0; i < count; ++i) {
+      w.add(values[i]);
+    }
+    
+    w.finish();
+    osdo.close();
+    super.close();
+  };
+  
+  @Override
+  public String toString() {
+    return "Packed";
+  }
+  
+  @Override
+  public IntDecoder createMatchingDecoder() {
+    return new PackedDecoder();
+  }
+  
+  private static final class PackedDecoder extends IntDecoder {
+    private Reader r;
+    private int size;
+    private int nextIdx = 0;
+    
+    @Override
+    public void reInit(InputStream in) {
+      super.reInit(in);
+      try {
+        r = PackedInts.getReader(new InputStreamDataInput(in));
+      } catch (IOException e) {
+        throw new RuntimeException("Cannot decode - corrupted stream?", e);
+      }
+      size = r.size();
+      nextIdx = 0;
+    }
+    
+    @Override
+    public long decode() throws IOException {
+      if (nextIdx < size) {
+        return r.get(nextIdx++);
+      }
+      return EOS;
+    }
+    
+    @Override
+    public String toString() {
+      return "Packed";
+    }
+  }
+}
Index: lucene/facet/src/java/org/apache/lucene/util/encoding/SortingIntEncoder.java
===================================================================
--- lucene/facet/src/java/org/apache/lucene/util/encoding/SortingIntEncoder.java	(revision 1423966)
+++ lucene/facet/src/java/org/apache/lucene/util/encoding/SortingIntEncoder.java	(working copy)
@@ -4,6 +4,8 @@
 import java.io.OutputStream;
 import java.util.Arrays;
 
+import org.apache.lucene.util.ArrayUtil;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -31,7 +33,6 @@
  */
 public class SortingIntEncoder extends IntEncoderFilter {
 
-  private float grow = 2.0f;
   private int index = 0;
   private int[] set = new int[1024];
 
@@ -42,26 +43,19 @@
 
   @Override
   public void close() throws IOException {
-    if (index == 0) {
-      return;
+    if (index > 0) {
+      Arrays.sort(set, 0, index);
+      for (int i = 0; i < index; i++) {
+        encoder.encode(set[i]);
+      }
     }
-
-    Arrays.sort(set, 0, index);
-    for (int i = 0; i < index; i++) {
-      encoder.encode(set[i]);
-    }
-    encoder.close();
-    index = 0;
-
     super.close();
   }
 
   @Override
   public void encode(int value) throws IOException {
-    if (index == set.length) {
-      int[] newSet = new int[(int) (set.length * grow)];
-      System.arraycopy(set, 0, newSet, 0, set.length);
-      set = newSet;
+    if (index >= set.length) {
+      set = ArrayUtil.grow(set);
     }
     set[index++] = value;
   }
@@ -81,5 +75,4 @@
   public String toString() {
     return "Sorting (" + encoder.toString() + ")";
   }
-  
 }
Index: lucene/facet/src/test/org/apache/lucene/util/encoding/EncodingSpeed.java
===================================================================
--- lucene/facet/src/test/org/apache/lucene/util/encoding/EncodingSpeed.java	(revision 1423966)
+++ lucene/facet/src/test/org/apache/lucene/util/encoding/EncodingSpeed.java	(working copy)
@@ -40,10 +40,10 @@
   private static int[] data9910 = null;
   private static int[] data501871 = null;
   private static int[] data10k = null;
-  private static String resultsFormat = "%-20s %10s %20d %26s %20d %26s";
-  private static String headerFormat = "%-20s %10s %20s %26s %20s %26s";
+  private static String resultsFormat = "%-60s %10s %20d %26s %20d %26s";
+  private static String headerFormat = "%-60s %10s %20s %26s %20s %26s";
   private static int integers = 100000000;
-
+  
   private static NumberFormat nf;
 
   public static void main(String[] args) throws IOException {
@@ -78,12 +78,15 @@
     System.out.println(separator);
 
     encoderTest(new VInt8IntEncoder(), facetIDs, loopFactor);
+    encoderTest(new PackedEncoder(), facetIDs, loopFactor);
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new VInt8IntEncoder())), facetIDs, loopFactor);
+    encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new PackedEncoder())), facetIDs, loopFactor);
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new VInt8IntEncoder()))), facetIDs, loopFactor);
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new EightFlagsIntEncoder()))), facetIDs, loopFactor);
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new FourFlagsIntEncoder()))), facetIDs, loopFactor);
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new NOnesIntEncoder(3)))), facetIDs, loopFactor);
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new NOnesIntEncoder(4)))), facetIDs, loopFactor);
+    encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new PackedEncoder()))), facetIDs, loopFactor);
 
     System.out.println();
   }
@@ -120,26 +123,20 @@
 
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
     IntDecoder decoder = encoder.createMatchingDecoder();
-    decoder.reInit(bais);
     
     // -- Looping 100 times as a warm up --------------------------
     for (int i = 100; i != 0; --i) {
-      bais.mark(baos.size());
-      while (decoder.decode() != IntDecoder.EOS) {
-      }
       bais.reset();
       decoder.reInit(bais);
+      while (decoder.decode() != IntDecoder.EOS);
     }
     // -----------------------------------------------------------
 
-    decoder.reInit(bais);
     startTime = System.currentTimeMillis();
     for (int i = loopFactor; i > 0; --i) {
-      bais.mark(baos.size());
-      while (decoder.decode() != IntDecoder.EOS) {
-      }
       bais.reset();
       decoder.reInit(bais);
+      while (decoder.decode() != IntDecoder.EOS);
     }
 
     endTime = System.currentTimeMillis();
Index: lucene/facet/src/test/org/apache/lucene/util/encoding/EncodingTest.java
===================================================================
--- lucene/facet/src/test/org/apache/lucene/util/encoding/EncodingTest.java	(revision 1423966)
+++ lucene/facet/src/test/org/apache/lucene/util/encoding/EncodingTest.java	(working copy)
@@ -86,6 +86,16 @@
     encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new NOnesIntEncoder(3)))));
   }
 
+  @Test
+  public void testPackedInts() {
+    encoderTest(new PackedEncoder());
+  }
+  
+  @Test
+  public void testSortingUniqueDgapPackedInts() {
+    encoderTest(new SortingIntEncoder(new UniqueValuesIntEncoder(new DGapIntEncoder(new PackedEncoder()))));
+  }
+ 
   private static void encoderTest(IntEncoder encoder) {
 
     // ensure toString is implemented
