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
If there are 10 or more bytes available in the current buffer, then we can decode a 64-bit varint without doing bounds checks. We currently have an unrolled loop which generates pretty good core for varints, but it does have to read (and check availability of) a single byte at a time, this is a bit terrible.
The Thrift C++ implementation has a fast path without bounds checks for the compact protocol, but the loop isn't unrolled for some reason? maybe clang is better than ghc here, not sure. Given the fixed upper bound (10 iterations) I don't see why you wouldn't always unroll this loop? (/cc @amosr)
/** * Read an i64 from the wire as a proper varint. The MSB of each byte is set * if there is another byte to follow. This can read up to 10 bytes.*/template <classTransport_>
uint32_t TCompactProtocolT<Transport_>::readVarint64(int64_t& i64) {
uint32_t rsize = 0;
uint64_t val = 0;
int shift = 0;
uint8_t buf[10]; // 64 bits / (7 bits/byte) = 10 bytes.uint32_t buf_size = sizeof(buf);
constuint8_t* borrowed = trans_->borrow(buf, &buf_size);
// Fast path.if (borrowed != NULL) {
while (true) {
uint8_t byte = borrowed[rsize];
rsize++;
val |= (uint64_t)(byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80)) {
i64 = val;
trans_->consume(rsize);
return rsize;
}
// Have to check for invalid data so we don't crash.if (UNLIKELY(rsize == sizeof(buf))) {
throwTProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.");
}
}
}
// Slow path.else {
while (true) {
uint8_t byte;
rsize += trans_->readAll(&byte, 1);
val |= (uint64_t)(byte & 0x7f) << shift;
shift += 7;
if (!(byte & 0x80)) {
i64 = val;
return rsize;
}
// Might as well check for invalid data on the slow path too.if (UNLIKELY(rsize >= sizeof(buf))) {
throwTProtocolException(TProtocolException::INVALID_DATA, "Variable-length int over 10 bytes.");
}
}
}
}
The text was updated successfully, but these errors were encountered:
If there are 10 or more bytes available in the current buffer, then we can decode a 64-bit varint without doing bounds checks. We currently have an unrolled loop which generates pretty good core for varints, but it does have to read (and check availability of) a single byte at a time, this is a bit terrible.
The Thrift C++ implementation has a fast path without bounds checks for the compact protocol, but the loop isn't unrolled for some reason? maybe clang is better than ghc here, not sure. Given the fixed upper bound (10 iterations) I don't see why you wouldn't always unroll this loop? (/cc @amosr)
The text was updated successfully, but these errors were encountered: