diff --git a/core/types.rs b/core/types.rs index cdfa8eec6..ac9c00495 100644 --- a/core/types.rs +++ b/core/types.rs @@ -892,27 +892,7 @@ impl ImmutableRecord { size_values += value_size; } - let mut header_size = size_header; - const MIN_HEADER_SIZE: usize = 126; - if header_size <= MIN_HEADER_SIZE { - // common case - // This case means the header size can be contained by a single byte, therefore - // header_size == size of serial types + 1 byte from the header size - // Since header_size is a varint, and a varint the first bit is used to represent we have more bytes to read, - // header size here will be 126 == (2^7 - 1) - header_size += 1; - } else { - // Rare case of a really large header - let mut temp_buf = [0u8; 9]; - let n_varint = write_varint(&mut temp_buf, header_size as u64); // or however you get varint length - header_size += n_varint; - - // Check if adding the varint bytes changes the varint length - let new_n_varint = write_varint(&mut temp_buf, header_size as u64); - if n_varint < new_n_varint { - header_size += 1; - } - } + let header_size = Record::calc_header_size(size_header); // 1. write header size let mut buf = Vec::new(); @@ -2180,6 +2160,37 @@ impl Record { Self { values } } + /// Calculates the total size needed for a SQLite record header. + /// + /// The record header consists of: + /// 1. A varint encoding the total header size (self-referentially, e.g. a 100 byte header literally has the number '100' in the header suffix) + /// 2. A sequence of varints encoding the serial types + /// + /// For small headers (<=126 bytes), we only need 1 byte to encode the header size, because 127 fits in 7 bits (varint uses 7 bits for the value and 1 continuation bit) + /// For larger headers, we need to account for the variable length of the header size varint. + pub fn calc_header_size(sizeof_serial_types: usize) -> usize { + if sizeof_serial_types < i8::MAX as usize { + return sizeof_serial_types + 1; + } + + let mut header_size = sizeof_serial_types; + // For larger headers, calculate how many bytes we need for the header size varint + let mut temp_buf = [0u8; 9]; + let mut prev_header_size; + + loop { + prev_header_size = header_size; + let varint_len = write_varint(&mut temp_buf, header_size as u64); + header_size = sizeof_serial_types + varint_len; + + if header_size == prev_header_size { + break; + } + } + + header_size + } + pub fn serialize(&self, buf: &mut Vec) { let initial_i = buf.len(); @@ -2219,16 +2230,7 @@ impl Record { } let mut header_bytes_buf: Vec = Vec::new(); - if header_size <= 126 { - // common case - header_size += 1; - } else { - todo!("calculate big header size extra bytes"); - // get header varint len - // header_size += n; - // if( nVarint