blob: 29b6e6000e27e01d9dec59d1fb9c168b2c25aa18 [file] [log] [blame]
/**
* @project scalability-benchmark
* @author Renaud Delbru [ 14 Dec 2008 ]
* @link http://renaud.delbru.fr/
* @copyright Copyright (C) 2007, All rights reserved.
*/
package org.sindice.index.benchmark.compression.codec;
import gnu.trove.TIntArrayList;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class Simple16Codec
implements Codec {
/* (non-Javadoc)
* @see org.sindice.index.benchmark.scalability.codec.Codec#decode(byte[])
*/
@Override
public int[] decode(final byte[] codes) throws IOException {
final TIntArrayList values = new TIntArrayList();
final ByteArrayInputStream input = new ByteArrayInputStream(codes);
final byte[] reusableByteArray = new byte[4];
int word = 0;
while (input.available() > 0) {
input.read(reusableByteArray);
word = CodecUtils.byteArrayToInt(reusableByteArray);
values.add(this.decode(word));
}
return values.toNativeArray();
}
/* (non-Javadoc)
* @see org.sindice.index.benchmark.scalability.codec.Codec#encode(java.util.List)
*/
@Override
public byte[] encode(final int[] values)
throws IOException {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
int i = 0;
// While we didn't encode all the values, continue
while (i < values.length) {
int word = 0;
// Start iteration over selectors
for (int k = 0; k < 16; k++) {
int j = 0, ncodes = 0;
// Encode selector
word = k << 28;
// How many codes we can fit ?
ncodes = (cnum[k] < values.length - i) ? cnum[k] : values.length - i;
// Start iteration over values
// if a value is > to the allowed code size, break loop and try next selector
for (int shift = 0; (j < ncodes) && values[i +j] < (1 << cbits[k][j]); j++) {
word += values[i +j] << shift;
// Increment shift with code width
shift += cbits[k][j];
}
// if all codes have been fitted, convert the word and return a byte array
if (j == ncodes) {
i = i + ncodes;
// Append word
out.write(CodecUtils.intToByteArray(word));
// Break the for loop
break;
}
}
}
return out.toByteArray();
}
protected int[] decode(final int word) {
int[] values;
int i = 0;
// Unsigned right shift
final int selector = word >>> 28;
switch(selector) {
case 0:
values = new int[28];
values[i] = word & 1; i++;
values[i] = (word>>1) & 1; i++;
values[i] = (word>>2) & 1; i++;
values[i] = (word>>3) & 1; i++;
values[i] = (word>>4) & 1; i++;
values[i] = (word>>5) & 1; i++;
values[i] = (word>>6) & 1; i++;
values[i] = (word>>7) & 1; i++;
values[i] = (word>>8) & 1; i++;
values[i] = (word>>9) & 1; i++;
values[i] = (word>>10) & 1; i++;
values[i] = (word>>11) & 1; i++;
values[i] = (word>>12) & 1; i++;
values[i] = (word>>13) & 1; i++;
values[i] = (word>>14) & 1; i++;
values[i] = (word>>15) & 1; i++;
values[i] = (word>>16) & 1; i++;
values[i] = (word>>17) & 1; i++;
values[i] = (word>>18) & 1; i++;
values[i] = (word>>19) & 1; i++;
values[i] = (word>>20) & 1; i++;
values[i] = (word>>21) & 1; i++;
values[i] = (word>>22) & 1; i++;
values[i] = (word>>23) & 1; i++;
values[i] = (word>>24) & 1; i++;
values[i] = (word>>25) & 1; i++;
values[i] = (word>>26) & 1; i++;
values[i] = (word>>27) & 1; i++;
return values;
case 1:
values = new int[21];
values[i] = (word) & 3; i++;
values[i] = (word>>2) & 3; i++;
values[i] = (word>>4) & 3; i++;
values[i] = (word>>6) & 3; i++;
values[i] = (word>>8) & 3; i++;
values[i] = (word>>10) & 3; i++;
values[i] = (word>>12) & 3; i++;
values[i] = (word>>14) & 1; i++;
values[i] = (word>>15) & 1; i++;
values[i] = (word>>16) & 1; i++;
values[i] = (word>>17) & 1; i++;
values[i] = (word>>18) & 1; i++;
values[i] = (word>>19) & 1; i++;
values[i] = (word>>20) & 1; i++;
values[i] = (word>>21) & 1; i++;
values[i] = (word>>22) & 1; i++;
values[i] = (word>>23) & 1; i++;
values[i] = (word>>24) & 1; i++;
values[i] = (word>>25) & 1; i++;
values[i] = (word>>26) & 1; i++;
values[i] = (word>>27) & 1; i++;
return values;
case 2:
values = new int[21];
values[i] = (word) & 1; i++;
values[i] = (word>>1) & 1; i++;
values[i] = (word>>2) & 1; i++;
values[i] = (word>>3) & 1; i++;
values[i] = (word>>4) & 1; i++;
values[i] = (word>>5) & 1; i++;
values[i] = (word>>6) & 1; i++;
values[i] = (word>>7) & 3; i++;
values[i] = (word>>9) & 3; i++;
values[i] = (word>>11) & 3; i++;
values[i] = (word>>13) & 3; i++;
values[i] = (word>>15) & 3; i++;
values[i] = (word>>17) & 3; i++;
values[i] = (word>>19) & 3; i++;
values[i] = (word>>21) & 1; i++;
values[i] = (word>>22) & 1; i++;
values[i] = (word>>23) & 1; i++;
values[i] = (word>>24) & 1; i++;
values[i] = (word>>25) & 1; i++;
values[i] = (word>>26) & 1; i++;
values[i] = (word>>27) & 1; i++;
return values;
case 3:
values = new int[21];
values[i] = (word) & 1; i++;
values[i] = (word>>1) & 1; i++;
values[i] = (word>>2) & 1; i++;
values[i] = (word>>3) & 1; i++;
values[i] = (word>>4) & 1; i++;
values[i] = (word>>5) & 1; i++;
values[i] = (word>>6) & 1; i++;
values[i] = (word>>7) & 1; i++;
values[i] = (word>>8) & 1; i++;
values[i] = (word>>9) & 1; i++;
values[i] = (word>>10) & 1; i++;
values[i] = (word>>11) & 1; i++;
values[i] = (word>>12) & 1; i++;
values[i] = (word>>13) & 1; i++;
values[i] = (word>>14) & 3; i++;
values[i] = (word>>16) & 3; i++;
values[i] = (word>>18) & 3; i++;
values[i] = (word>>20) & 3; i++;
values[i] = (word>>22) & 3; i++;
values[i] = (word>>24) & 3; i++;
values[i] = (word>>26) & 3; i++;
return values;
case 4:
values = new int[14];
values[i] = (word) & 3; i++;
values[i] = (word>>2) & 3; i++;
values[i] = (word>>4) & 3; i++;
values[i] = (word>>6) & 3; i++;
values[i] = (word>>8) & 3; i++;
values[i] = (word>>10) & 3; i++;
values[i] = (word>>12) & 3; i++;
values[i] = (word>>14) & 3; i++;
values[i] = (word>>16) & 3; i++;
values[i] = (word>>18) & 3; i++;
values[i] = (word>>20) & 3; i++;
values[i] = (word>>22) & 3; i++;
values[i] = (word>>24) & 3; i++;
values[i] = (word>>26) & 3; i++;
return values;
case 5:
values = new int[9];
values[i] = (word) & 15; i++;
values[i] = (word>>4) & 7; i++;
values[i] = (word>>7) & 7; i++;
values[i] = (word>>10) & 7; i++;
values[i] = (word>>13) & 7; i++;
values[i] = (word>>16) & 7; i++;
values[i] = (word>>19) & 7; i++;
values[i] = (word>>22) & 7; i++;
values[i] = (word>>25) & 7; i++;
return values;
case 6:
values = new int[8];
values[i] = (word) & 7; i++;
values[i] = (word>>3) & 15; i++;
values[i] = (word>>7) & 15; i++;
values[i] = (word>>11) & 15; i++;
values[i] = (word>>15) & 15; i++;
values[i] = (word>>19) & 7; i++;
values[i] = (word>>22) & 7; i++;
values[i] = (word>>25) & 7; i++;
return values;
case 7:
values = new int[7];
values[i] = (word) & 15; i++;
values[i] = (word>>4) & 15; i++;
values[i] = (word>>8) & 15; i++;
values[i] = (word>>12) & 15; i++;
values[i] = (word>>16) & 15; i++;
values[i] = (word>>20) & 15; i++;
values[i] = (word>>24) & 15; i++;
return values;
case 8:
values = new int[6];
values[i] = (word) & 31; i++;
values[i] = (word>>5) & 31; i++;
values[i] = (word>>10) & 31; i++;
values[i] = (word>>15) & 31; i++;
values[i] = (word>>20) & 15; i++;
values[i] = (word>>24) & 15; i++;
return values;
case 9:
values = new int[6];
values[i] = (word) & 15; i++;
values[i] = (word>>4) & 15; i++;
values[i] = (word>>8) & 31; i++;
values[i] = (word>>13) & 31; i++;
values[i] = (word>>18) & 31; i++;
values[i] = (word>>23) & 31; i++;
return values;
case 10:
values = new int[5];
values[i] = (word) & 63; i++;
values[i] = (word>>6) & 63; i++;
values[i] = (word>>12) & 63; i++;
values[i] = (word>>18) & 31; i++;
values[i] = (word>>23) & 31; i++;
return values;
case 11:
values = new int[5];
values[i] = (word) & 31; i++;
values[i] = (word>>5) & 31; i++;
values[i] = (word>>10) & 63; i++;
values[i] = (word>>16) & 63; i++;
values[i] = (word>>22) & 63; i++;
return values;
case 12:
values = new int[4];
values[i] = (word) & 127; i++;
values[i] = (word>>7) & 127; i++;
values[i] = (word>>14) & 127; i++;
values[i] = (word>>21) & 127; i++;
return values;
case 13:
values = new int[3];
values[i] = (word) & 1023; i++;
values[i] = (word>>10) & 511; i++;
values[i] = (word>>19) & 511; i++;
return values;
case 14:
values = new int[2];
values[i] = (word) & 16383; i++;
values[i] = (word>>14) & 16383; i++;
return values;
case 15:
values = new int[1];
values[i] = (word) & ((1<<28)-1); i++;
return values;
default:
throw new RuntimeException("Unknown selector: " + selector);
}
}
protected static int cbits[][] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,0,0,0,0,0,0,0},
{2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{4,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{3,4,4,4,4,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{5,5,5,5,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{4,4,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{6,6,6,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{5,5,6,6,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{10,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{14,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} };
protected static int cnum[] = {28, 21, 21, 21, 14, 9, 8, 7, 6, 6, 5, 5, 4, 3, 2, 1};
}