blob: 979bbd3a5f56f9aa622089186f7c96913d7a2873 [file] [log] [blame]
/*
* Copyright 2009-2010 by The Regents of the University of California
* Licensed 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 from
*
* 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.
*/
package edu.uci.ics.hyracks.storage.am.common.tuples;
// encodes positive integers in a variable-byte format
public class VarLenIntEncoderDecoder {
public static final int ENCODE_MASK = 0x0000007F;
public static final byte CONTINUE_CHUNK = (byte) 0x80;
public static final byte DECODE_MASK = (byte) 0x7F;
private byte[] encTmp = new byte[5];
private int pos;
private byte[] bytes;
public void reset(byte[] bytes, int pos) {
this.bytes = bytes;
this.pos = pos;
}
public int encode(int val) {
int origPos = 0;
int tmpPos = 0;
while (val > ENCODE_MASK) {
encTmp[tmpPos++] = (byte) (val & ENCODE_MASK);
val = val >>> 7;
}
encTmp[tmpPos++] = (byte) (val);
// reverse order to optimize for decoding speed
for (int i = 0; i < tmpPos - 1; i++) {
bytes[pos++] = (byte) (encTmp[tmpPos - 1 - i] | CONTINUE_CHUNK);
}
bytes[pos++] = encTmp[0];
return pos - origPos;
}
public int decode() {
int sum = 0;
while ((bytes[pos] & CONTINUE_CHUNK) == CONTINUE_CHUNK) {
sum = (sum + (bytes[pos] & DECODE_MASK)) << 7;
pos++;
}
sum += bytes[pos++];
return sum;
}
// calculate the number of bytes needed for encoding
public int getBytesRequired(int val) {
int byteCount = 0;
while (val > ENCODE_MASK) {
val = val >>> 7;
byteCount++;
}
return byteCount + 1;
}
public int getPos() {
return pos;
}
// fast encoding, slow decoding version
/*
* public void encode(int val) { while(val > ENCODE_MASK) { bytes[pos++] =
* (byte)(((byte)(val & ENCODE_MASK)) | CONTINUE_CHUNK); val = val >>> 7; }
* bytes[pos++] = (byte)(val); }
*
* public int decode() { int sum = 0; int shift = 0; while( (bytes[pos] &
* CONTINUE_CHUNK) == CONTINUE_CHUNK) { sum = (sum + (bytes[pos] &
* DECODE_MASK)) << 7 * shift++; pos++; } sum += bytes[pos++] << 7 * shift;
* return sum; }
*/
}