private int invert(int startOff, int level, int prefix, IntArrayList values, IntArrayList valueSizes) { int tableEnd = startOff + 256; values.fill(startOff, tableEnd, -1); valueSizes.fill(startOff, tableEnd, 0); int prefLen = level << 3; for (int i = 0; i < codeSizes.length; i++) { if ((codeSizes[i] <= prefLen) || (level > 0 && (codes[i] >>> (32 - prefLen)) != prefix)) continue; int pref = codes[i] >>> (32 - prefLen - 8); int code = pref & 0xff; int len = codeSizes[i] - prefLen; if (len <= 8) { for (int k = 0; k < (1 << (8 - len)); k++) { values.set(startOff + code + k, i); valueSizes.set(startOff + code + k, len); } } else { if (values.get(startOff + code) == -1) { values.set(startOff + code, tableEnd); tableEnd = invert(tableEnd, level + 1, pref, values, valueSizes); } } } return tableEnd; }