From 0739820819dbbab9ebd4b91efc2dbda775d2f313 Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Mon, 3 Feb 2025 10:56:52 +0200 Subject: Optimize buffer construction --- log_db/src/common.rs | 45 ++++++++++++++++++++++----------------------- log_db/src/engine.rs | 25 +++++++++++-------------- 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/log_db/src/common.rs b/log_db/src/common.rs index d4a95b5..3e06db5 100644 --- a/log_db/src/common.rs +++ b/log_db/src/common.rs @@ -170,14 +170,11 @@ pub struct MetadataHeader { const METADATA_HEADER_PADDING: &[u8] = &[0; 7]; impl MetadataHeader { - pub fn serialize(&self) -> Vec { - let uuid_bytes = self.uuid.as_bytes().to_vec(); - - let mut header = vec![self.version]; - header.extend(METADATA_HEADER_PADDING); - header.extend(uuid_bytes); - - assert_eq!(header.len(), METADATA_FILE_HEADER_SIZE); + pub fn serialize(&self) -> [u8; METADATA_FILE_HEADER_SIZE] { + let mut header = [0u8; METADATA_FILE_HEADER_SIZE]; + header[0] = self.version; + header[1..8].copy_from_slice(METADATA_HEADER_PADDING); + header[8..].copy_from_slice(self.uuid.as_bytes()); header } @@ -278,31 +275,33 @@ impl Eq for Value {} impl Value { pub fn serialize(&self) -> Vec { match self { - Value::Null => { - vec![B_NULL] - } + Value::Null => vec![B_NULL], Value::Int(i) => { - let mut bytes = vec![B_INT]; - bytes.extend(i.to_be_bytes()); + let mut bytes = Vec::with_capacity(1 + 16); + bytes.push(B_INT); + bytes.extend_from_slice(&i.to_be_bytes()); bytes } Value::Decimal(d) => { - let mut bytes = vec![B_DECIMAL]; - bytes.extend(d.serialize()); // 16 bytes + let mut bytes = Vec::with_capacity(1 + 16); + bytes.push(B_DECIMAL); + bytes.extend_from_slice(&d.serialize()); bytes } Value::String(s) => { - let mut bytes = vec![B_STRING]; - let length = s.len() as u64; - bytes.extend(length.to_be_bytes()); - bytes.extend(s.as_bytes()); + let len = s.len(); + let mut bytes = Vec::with_capacity(1 + 8 + len); + bytes.push(B_STRING); + bytes.extend_from_slice(&(len as u64).to_be_bytes()); + bytes.extend_from_slice(s.as_bytes()); bytes } Value::Bytes(b) => { - let mut bytes = vec![B_BYTES]; - let length = b.len() as u64; - bytes.extend(length.to_be_bytes()); - bytes.extend(b); + let len = b.len(); + let mut bytes = Vec::with_capacity(1 + 8 + len); + bytes.push(B_BYTES); + bytes.extend_from_slice(&(len as u64).to_be_bytes()); + bytes.extend_from_slice(b); bytes } } diff --git a/log_db/src/engine.rs b/log_db/src/engine.rs index edf8af6..4391451 100644 --- a/log_db/src/engine.rs +++ b/log_db/src/engine.rs @@ -318,11 +318,9 @@ impl Engine { debug!("Found log keys in memtable: {:?}", log_key_batches); let mut tagged = vec![]; - let mut tag: usize = 0; - for batch in log_key_batches { + for (tag, batch) in log_key_batches.into_iter().enumerate() { let mapped = batch.into_iter().map(|log_key| (tag, log_key)); tagged.extend(mapped); - tag += 1; } let tagged_records = self.read_tagged_log_keys(tagged.into_iter())?; @@ -513,9 +511,11 @@ impl Engine { let initial_data_offset = self.active_data_file.seek(SeekFrom::End(0))?; let initial_metadata_offset = self.active_metadata_file.seek(SeekFrom::End(0))?; let mut serialized_data: Vec = vec![]; - let mut serialized_metadata: Vec = vec![]; + let mut serialized_metadata: Vec = Vec::with_capacity(self.tx_log.len() * 16); let mut pending_memtable_ops: Vec<(LogKey, TxEntry)> = vec![]; + let mut metadata_buf = [0u8; 16]; + debug!("Serializing tx_log to byte arrays"); for tx_entry in &self.tx_log { let record = match tx_entry { @@ -534,14 +534,11 @@ impl Engine { let metadata_index = (metadata_pos - METADATA_FILE_HEADER_SIZE as u64) / METADATA_ROW_LENGTH as u64; - // Write the record metadata to the metadata file - let mut metadata_buf = vec![]; - metadata_buf.extend(record_offset.to_be_bytes().into_iter()); - metadata_buf.extend(record_length.to_be_bytes().into_iter()); - - assert_eq!(metadata_buf.len(), 16); + // Write the record metadata to the fixed-size metadata buffer + metadata_buf[..8].copy_from_slice(&record_offset.to_be_bytes()); + metadata_buf[8..].copy_from_slice(&record_length.to_be_bytes()); - serialized_metadata.extend(metadata_buf); + serialized_metadata.extend_from_slice(&metadata_buf); let log_key = LogKey::new(segment_num, metadata_index); pending_memtable_ops.push((log_key, tx_entry.clone())); @@ -661,12 +658,12 @@ impl Engine { temp_metadata_file.write_all(&metadata_header.serialize())?; + let mut metadata_buf = [0u8; 16]; for (pk, _) in forward_read_items.iter() { let (offset, len) = pk_to_data_map.get(&pk).unwrap(); - let mut metadata_buf = vec![]; - metadata_buf.extend(offset.to_be_bytes().into_iter()); - metadata_buf.extend(len.to_be_bytes().into_iter()); + metadata_buf[..8].copy_from_slice(&offset.to_be_bytes()); + metadata_buf[8..].copy_from_slice(&len.to_be_bytes()); temp_metadata_file.write_all(&metadata_buf)?; } -- cgit v1.3