code: private void shrink() {
          /* If the size of the topmost array is at its minimum, don't do
           * anything.  This doesn't change the asymptotic memory usage because
           * we only do this for small arrays.
           */
          if (mArrays.length == kMinArraySize) return;
  
          /* Otherwise, we currently have 2^(2n) / 8 = 2^(2n - 3) elements.
           * We're about to shrink into a grid of 2^(2n - 2) elements, and so
           * we'll fill in half of the elements.
           */
          T[][] newArrays = (T[][]) new Object[mArrays.length / 2][];
  
          /* Copy everything over.  We'll need half as many arrays as before. */
          for (int i = 0; i < newArrays.length / 2; ++i) {
              /* Create the arrays. */
              newArrays[i] = (T[]) new Object[newArrays.length];
  
              /* Move everything into it.  If this is an odd array, it comes
               * from the upper half of the old array; otherwise it comes from
               * the lower half.
               */
              System.arraycopy(mArrays[i / 2], (i % 2 == 0) ? 0 : newArrays.length,
                      newArrays[i], 0, newArrays.length);
  
              /* Play nice with the GC.  If this is an odd-numbered array, we
               * just copied over everything we needed and can clear out the
               * old array.
               */
              if (i % 2 == 1)
                  mArrays[i / 2] = null;
          }
  
          /* Copy the arrays over. */
          mArrays = newArrays;
  
          /* Drop the lg2 of the size. */
          --mLgSize;
      }
docs: Decreases the size of the HAT by shrinking into a better fit.