Skip to content

Commit c86edda

Browse files
committed
Optimize length-prefixed writes
1 parent aecb820 commit c86edda

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

lightning/src/util/ser.rs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! A very simple serialization framework which is used to serialize/deserialize messages as well
1111
//! as ChannelsManagers and ChannelMonitors.
1212
13-
use std::io::{Read, Write};
13+
use std::io::{Read, Write, Cursor};
1414
use std::collections::HashMap;
1515
use std::hash::Hash;
1616
use std::sync::Mutex;
@@ -62,6 +62,22 @@ impl Writer {
6262
pub fn len(&self) -> usize {
6363
self.0.len()
6464
}
65+
66+
/// Insert the length of a data slice before the slice start
67+
pub fn insert_length(&mut self, slice_start: usize, length_adjust: usize) -> Result<(), ::std::io::Error> {
68+
let slice_end = self.len();
69+
let length = slice_end - slice_start + length_adjust;
70+
// Write the length after the slice, to check how many bytes
71+
BigSize(length as u64).write(self)?;
72+
let len_end = self.len();
73+
let len_len = len_end - slice_end;
74+
// Shift the slice to make space for the length
75+
self.0.copy_within(slice_start..slice_end, slice_start + len_len);
76+
let mut cursor = Cursor::new(&mut self.0);
77+
cursor.set_position(slice_start as u64);
78+
// Write the length again at the right spot
79+
BigSize(length as u64).write_write(&mut cursor)
80+
}
6581
}
6682

6783
impl Write for Writer {
@@ -225,28 +241,34 @@ impl Readable for U48 {
225241
/// you're looking for an example of a variable-length integer to use for your own project, move
226242
/// along, this is a rather poor design.
227243
pub(crate) struct BigSize(pub u64);
228-
impl Writeable for BigSize {
229-
#[inline]
230-
fn write(&self, writer: &mut Writer) -> Result<(), ::std::io::Error> {
244+
impl BigSize {
245+
pub fn write_write<W: Write>(&self, write: &mut W) -> Result<(), ::std::io::Error> {
231246
match self.0 {
232247
0...0xFC => {
233-
(self.0 as u8).write(writer)
248+
write.write_all(&[self.0 as u8])
234249
},
235250
0xFD...0xFFFF => {
236-
0xFDu8.write(writer)?;
237-
(self.0 as u16).write(writer)
251+
write.write_all(&[0xFDu8])?;
252+
write.write_all(&be16_to_array(self.0 as u16))
238253
},
239254
0x10000...0xFFFFFFFF => {
240-
0xFEu8.write(writer)?;
241-
(self.0 as u32).write(writer)
255+
write.write_all(&[0xFEu8])?;
256+
write.write_all(&be32_to_array(self.0 as u32))
242257
},
243258
_ => {
244-
0xFFu8.write(writer)?;
245-
(self.0 as u64).write(writer)
259+
write.write_all(&[0xFFu8])?;
260+
write.write_all(&be64_to_array(self.0 as u64))
246261
},
247262
}
248263
}
249264
}
265+
266+
impl Writeable for BigSize {
267+
#[inline]
268+
fn write(&self, writer: &mut Writer) -> Result<(), ::std::io::Error> {
269+
self.write_write(writer)
270+
}
271+
}
250272
impl Readable for BigSize {
251273
#[inline]
252274
fn read<R: Read>(reader: &mut R) -> Result<BigSize, DecodeError> {
@@ -609,10 +631,9 @@ impl<T: Writeable> Writeable for Option<T> {
609631
match *self {
610632
None => 0u8.write(w)?,
611633
Some(ref data) => {
612-
let mut len_calc = Writer::new();
613-
data.write(&mut len_calc).expect("No in-memory data may fail to serialize");
614-
BigSize(len_calc.len() as u64 + 1).write(w)?;
615-
data.write(w)?;
634+
let start = w.len();
635+
data.write(w).expect("No in-memory data may fail to serialize");
636+
w.insert_length(start, 1)?;
616637
}
617638
}
618639
Ok(())

lightning/src/util/ser_macros.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99

1010
macro_rules! encode_tlv {
1111
($stream: expr, {$(($type: expr, $field: expr)),*}) => { {
12-
use util::ser::{BigSize, Writer};
12+
use util::ser::BigSize;
1313
$(
1414
BigSize($type).write($stream)?;
15-
let mut len_calc = Writer::new();
16-
$field.write(&mut len_calc)?;
17-
BigSize(len_calc.len() as u64).write($stream)?;
15+
let start = $stream.len();
1816
$field.write($stream)?;
17+
$stream.insert_length(start, 0)?;
1918
)*
2019
} }
2120
}

0 commit comments

Comments
 (0)