You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[help] how to efficiently encode and decode custom int using unsafe #1477
I'm currently maintaining a library (avro4k, that is apache avro format for kotlin) and I think that okio would be really powerful as a multiplatform streaming input and output.
I would like to encode int and long using zig-zag encoding, and I would like to have a performant encoding. As there is buffer segments, reading byte by byte can be done as a slow path.
The encoding is always in little endian, and each byte has its highest bit indicating if there is another byte to read or not, that ends up to 7 bits * n bytes (4 bytes for int and 8 bytes for long).
Encoding:
Here is the int encoding (original code) , but you can guess that long encoding is similar.
publicstaticintencodeInt(intn, byte[] buf, intpos) {
// move sign to low-order bit, and flip others if negativen = (n << 1) ^ (n >> 31);
intstart = pos;
if ((n & ~0x7F) != 0) {
buf[pos++] = (byte) ((n | 0x80) & 0xFF);
n >>>= 7;
if (n > 0x7F) {
buf[pos++] = (byte) ((n | 0x80) & 0xFF);
n >>>= 7;
if (n > 0x7F) {
buf[pos++] = (byte) ((n | 0x80) & 0xFF);
n >>>= 7;
if (n > 0x7F) {
buf[pos++] = (byte) ((n | 0x80) & 0xFF);
n >>>= 7;
}
}
}
}
buf[pos++] = (byte) n;
returnpos - start;
}
Decoding:
Now the reverse, we read byte per byte (original code):
publicintreadInt() throwsIOException {
intn = 0;
intb;
intshift = 0;
do {
b = in.read();
if (b >= 0) {
n |= (b & 0x7F) << shift;
if ((b & 0x80) == 0) {
return (n >>> 1) ^ -(n & 1); // back to two's-complement
}
} else {
thrownewEOFException();
}
shift += 7;
} while (shift < 32);
thrownewInvalidNumberEncodingException("Invalid int encoding");
}
Do you think this would be the most performant, or unsafe cursors could help to improve that?
Activity