public static LinkedByteBuffer toByteBuffer(ResultHeap rheap, byte compression) { int size = rheap.size(); int[] docids = new int[size]; double[] scores = new double[size]; rheap.decrSortResults(docids, scores); LinkedByteBuffer buffer = new LinkedByteBuffer(); if (compression == NOCOMPRESSION) { for (int i = 0; i < size; i++) { buffer.putInt(docids[i]); // store docids buffer.putFloat((float) scores[i]); // store scores } } else if (compression == DOCIDSONLY) { NewPForEncoding encoder = new NewPForEncoding(padLimit); int spos; for (spos = 0; spos + 128 < size; spos += 128) { for (int i = 0; i < 128; i++) { buffer.putFloat((float) scores[spos + i]); // store scores } encoder.encodeSingle(buffer, docids, spos, 128); // encode docids } int rest = size - spos; for (int i = 0; i < rest; i++) { buffer.putFloat((float) scores[spos + i]); // store scores } encoder.encodeSingle(buffer, docids, spos, rest); } else if (compression == CROPFLOATS) { int fin[] = new int[128], curbits, bitshift = 23 - mantissaBits, eof = mantissaBits << 2; int fout[] = new int[eof]; double tmp, prev = size > 0 ? scores[0] : 0; NewPForEncoding encoder = new NewPForEncoding(padLimit); int spos; for (spos = 0; spos + 128 < size; spos += 128) { for (int i = 0; i < 128; i++) { tmp = scores[spos + i]; curbits = Float.floatToIntBits((float) (prev - tmp)); // separate scores prev = tmp; buffer.put((byte) (curbits >> 23)); // store exponens fin[i] = (curbits >> bitshift) & PackUtils.masks[mantissaBits]; } PackUtils.cleanArray(fout); // pack mantissas PackUtils.pack(mantissaBits, 128, 0, 0, fin, fout); for (int i = 0; i < eof; i++) { buffer.putInt(fout[i]); // store mantissas } encoder.encodeSingle(buffer, docids, spos, 128); // encode docs } int rest = size - spos; for (int i = 0; i < rest; i++) { tmp = scores[spos + i]; curbits = Float.floatToIntBits((float) (prev - tmp)); // calculate differences, separate scores prev = tmp; buffer.put((byte) (curbits >> 23)); fin[i] = (curbits >> bitshift) & PackUtils.masks[mantissaBits]; } for (int i = rest; i < 128; i++) fin[i] = 0; // for the last group we pad zeros. PackUtils.cleanArray(fout); PackUtils.pack(mantissaBits, 128, 0, 0, fin, fout); for (int i = 0; i < eof; i++) { buffer.putInt(fout[i]); } encoder.encodeSingle(buffer, docids, spos, rest); } else if (compression == MAXCOMPRESSION) { // PForCompress dgaps // PForCompress exponents // PForCompress mantissas NewPForEncoding encoder = new NewPForEncoding(padLimit); int spos; int e[] = new int[128], m[] = new int[128], bits, bitshift = 23 - mantissaBits; double tmp, prev = size > 0 ? scores[0] : 0; for (spos = 0; spos + 128 < size; spos += 128) { for (int i = 0; i < 128; i++) { tmp = scores[spos + i]; bits = Float.floatToIntBits((float) (prev - tmp)); // calculate differences, separate scores prev = tmp; e[i] = (bits >> 23) & 0xff; m[i] = (bits >> bitshift) & PackUtils.masks[mantissaBits]; } encoder.encodeSingle(buffer, e, 0, 128); // encode exponents encoder.encodeSingle(buffer, m, 0, 128); // encode mantissas encoder.encodeSingle(buffer, docids, spos, 128); } int rest = size - spos; for (int i = 0; i < rest; i++) { tmp = scores[spos + i]; bits = Float.floatToIntBits((float) (prev - tmp)); // calculate differences, separate scores prev = tmp; e[i] = (bits >> 23) & 0xff; m[i] = ((bits >> bitshift) + 1) & PackUtils.masks[mantissaBits]; } if (rest < padLimit) for (int i = 0; i < rest; i++) m[i]++; encoder.encodeSingle(buffer, e, 0, rest); // encode exponents encoder.encodeSingle(buffer, m, 0, rest); // encode mantissas encoder.encodeSingle(buffer, docids, spos, rest); } return buffer; }
public static QueryResults fromByteBuffer( ByteBuffer buffer, int cnt, int realCnt, byte compression) { int[] docids = new int[cnt]; double[] scores = new double[cnt]; // decompress docids if (compression == NOCOMPRESSION) { for (int i = 0; i < cnt; i++) { docids[i] = buffer.getInt(); scores[i] = buffer.getFloat(); } } else if (compression == DOCIDSONLY) { NewPForDecoding decoder = new NewPForDecoding(padLimit); double drbuffer[] = new double[128]; int spos; for (spos = 0; spos + 128 < cnt; spos += 128) { for (int i = 0; i < 128; i++) scores[spos + i] = buffer.getFloat(); decoder.decodeSingle(buffer, 128, docids, spos); } int rest = cnt - spos; for (int i = 0; i < rest; i++) drbuffer[i] = buffer.getFloat(); decoder.decodeSingle(buffer, rest, docids, spos); } else if (compression == CROPFLOATS) { NewPForDecoding decoder = new NewPForDecoding(padLimit); int spos; int fout[] = new int[128], curbits, bitshift = 23 - mantissaBits, eof = mantissaBits << 2; int fin[] = new int[eof]; byte exponents[] = new byte[128]; double last = 0d, diff; for (spos = 0; spos + 128 < cnt; spos += 128) { // read exponents for (int i = 0; i < 128; i++) { exponents[i] = buffer.get(); } // read mantissas for (int i = 0; i < eof; i++) { fin[i] = buffer.getInt(); } // unpack mantissas PackUtils.unpack(mantissaBits, 128, 0, 0, fin, fout); // decode dgaps decoder.decodeSingle(buffer, 128, docids, spos); // restore docids and scores for (int i = 0; i < 128; i++) { curbits = (exponents[i] << 23) & 0x7FFFFFFF; curbits |= fout[i] << bitshift; diff = Float.intBitsToFloat(curbits); last = scores[spos + i] = (spos > 0 || i > 0) ? last - diff : diff; } } int rest = cnt - spos; // read exponents for (int i = 0; i < rest; i++) { exponents[i] = buffer.get(); // out[i] = buffer.getInt(); } // read mantissas for (int i = 0; i < eof; i++) { fin[i] = buffer.getInt(); } // unpack mantissas PackUtils.unpack(mantissaBits, 128, 0, 0, fin, fout); // decode dgaps decoder.decodeSingle(buffer, rest, docids, spos); // restore floats! for (int i = 0; i < rest; i++) { curbits = (exponents[i] << 23) & 0x7FFFFFFF; curbits |= fout[i] << bitshift; diff = Float.intBitsToFloat(curbits); last = scores[spos + i] = (spos > 0 || i > 0) ? last - diff : diff; } } else if (compression == MAXCOMPRESSION) { // PForDecompress exponents // PForDecompress mantissas NewPForDecoding decoder = new NewPForDecoding(padLimit); int spos, e[] = new int[128], m[] = new int[128], bitshift = 23 - mantissaBits; double diff, last = 0d; for (spos = 0; spos + 128 < cnt; spos += 128) { decoder.decodeSingle(buffer, 128, e, 0); // decode exponents decoder.decodeSingle(buffer, 128, m, 0); // decode mantissas decoder.decodeSingle(buffer, 128, docids, spos); // decode docids for (int i = 0; i < 128; i++) { diff = Float.intBitsToFloat((e[i] << 23) | (m[i] << bitshift)); last = scores[spos + i] = (spos > 0 || i > 0) ? last - diff : diff; } } int rest = cnt - spos; decoder.decodeSingle(buffer, rest, e, 0); // decode exponents decoder.decodeSingle(buffer, rest, m, 0); // decode mantissas decoder.decodeSingle(buffer, rest, docids, spos); // decode docids if (rest < padLimit) for (int i = 0; i < rest; i++) m[i]--; for (int i = 0; i < rest; i++) { diff = Float.intBitsToFloat((e[i] << 23) | (m[i] << bitshift)); last = scores[spos + i] = (spos > 0 || i > 0) ? last - diff : diff; } } return new QueryResults(docids, scores, cnt, realCnt); }