1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +03:00

use varbincode for mux protocol; results in ~3x smaller packets

Reduces the size of the full screen serialized size from 40k -> 13k.

Note that the `zlo` crate (which doesn't appear to have a repo
on github any longer; sources are only found in the crates.io
documentation source view), employes zigzag encoding of all integers
and floating point values and takes the size down to just under 10k.

A todo is to follow up on that and see if we could adopt the same
scheme in varbincode.
This commit is contained in:
Wez Furlong 2019-03-16 00:58:01 -07:00
parent 322f7c74e6
commit 2077e3fd21
4 changed files with 32 additions and 35 deletions

View File

@ -31,9 +31,8 @@ rayon = "1.0"
promise = { path = "promise" } promise = { path = "promise" }
base91 = { path = "base91" } base91 = { path = "base91" }
varbincode = { path = "varbincode" } varbincode = { path = "varbincode" }
varu64 = "0.6"
bincode = "1.1"
lazy_static = "1.3" lazy_static = "1.3"
leb128 = "0.2"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
harfbuzz-sys = { git = "https://github.com/wez/rust-harfbuzz", branch="coretext" } harfbuzz-sys = { git = "https://github.com/wez/rust-harfbuzz", branch="coretext" }

View File

@ -162,7 +162,7 @@ fn main() -> Result<(), Error> {
let data = client.get_coarse_tab_renderable_data(GetCoarseTabRenderableData { let data = client.get_coarse_tab_renderable_data(GetCoarseTabRenderableData {
tab_id: *tab_id, tab_id: *tab_id,
})?; })?;
eprintln!("coarse: {:?}", data); // eprintln!("coarse: {:?}", data);
} }
Ok(()) Ok(())
} }

View File

@ -11,14 +11,29 @@
#![allow(dead_code)] #![allow(dead_code)]
use crate::mux::tab::TabId; use crate::mux::tab::TabId;
use bincode;
use failure::Error; use failure::Error;
use leb128;
use serde_derive::*; use serde_derive::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use term::{CursorPosition, Line}; use term::{CursorPosition, Line};
use termwiz::hyperlink::Hyperlink; use termwiz::hyperlink::Hyperlink;
use varu64; use varbincode;
/// Returns the encoded length of the leb128 representation of value
fn encoded_length(value: u64) -> usize {
struct NullWrite {};
impl std::io::Write for NullWrite {
fn write(&mut self, buf: &[u8]) -> std::result::Result<usize, std::io::Error> {
Ok(buf.len())
}
fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
Ok(())
}
};
leb128::write::unsigned(&mut NullWrite {}, value).unwrap()
}
fn encode_raw<W: std::io::Write>( fn encode_raw<W: std::io::Write>(
ident: u64, ident: u64,
@ -26,34 +41,16 @@ fn encode_raw<W: std::io::Write>(
data: &[u8], data: &[u8],
mut w: W, mut w: W,
) -> Result<(), std::io::Error> { ) -> Result<(), std::io::Error> {
let len = data.len() + varu64::encoding_length(ident) + varu64::encoding_length(serial); let len = data.len() + encoded_length(ident) + encoded_length(serial);
varu64::encode_write(len as u64, w.by_ref())?; leb128::write::unsigned(w.by_ref(), len as u64)?;
varu64::encode_write(serial, w.by_ref())?; leb128::write::unsigned(w.by_ref(), serial)?;
varu64::encode_write(ident, w.by_ref())?; leb128::write::unsigned(w.by_ref(), ident)?;
w.write_all(data) w.write_all(data)
} }
fn read_u64<R: std::io::Read>(mut r: R) -> Result<u64, std::io::Error> { fn read_u64<R: std::io::Read>(mut r: R) -> Result<u64, std::io::Error> {
let mut intbuf = [0u8; 9]; leb128::read::unsigned(&mut r)
r.read_exact(&mut intbuf[0..1])?; .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", err)))
let len = match intbuf[0] {
0...247 => 0,
248 => 1,
249 => 2,
250 => 3,
251 => 4,
252 => 5,
253 => 6,
254 => 7,
255 => 8,
_ => unreachable!(),
};
if len > 0 {
r.read_exact(&mut intbuf[1..=len])?;
}
let (value, _) = varu64::decode(&intbuf[0..=len])
.map_err(|(err, _)| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", err)))?;
Ok(value)
} }
#[derive(Debug)] #[derive(Debug)]
@ -65,9 +62,10 @@ struct Decoded {
fn decode_raw<R: std::io::Read>(mut r: R) -> Result<Decoded, std::io::Error> { fn decode_raw<R: std::io::Read>(mut r: R) -> Result<Decoded, std::io::Error> {
let len = read_u64(r.by_ref())? as usize; let len = read_u64(r.by_ref())? as usize;
eprintln!("decode_raw: {} bytes", len);
let serial = read_u64(r.by_ref())?; let serial = read_u64(r.by_ref())?;
let ident = read_u64(r.by_ref())?; let ident = read_u64(r.by_ref())?;
let data_len = len - (varu64::encoding_length(ident) + varu64::encoding_length(serial)); let data_len = len - (encoded_length(ident) + encoded_length(serial));
let mut data = vec![0u8; data_len]; let mut data = vec![0u8; data_len];
r.read_exact(&mut data)?; r.read_exact(&mut data)?;
Ok(Decoded { Ok(Decoded {
@ -99,7 +97,7 @@ macro_rules! pdu {
Pdu::Invalid{..} => bail!("attempted to serialize Pdu::Invalid"), Pdu::Invalid{..} => bail!("attempted to serialize Pdu::Invalid"),
$( $(
Pdu::$name(s) => { Pdu::$name(s) => {
let data = bincode::serialize(s)?; let data = varbincode::serialize(s)?;
encode_raw($vers, serial, &data, w)?; encode_raw($vers, serial, &data, w)?;
Ok(()) Ok(())
} }
@ -114,7 +112,7 @@ macro_rules! pdu {
$vers => { $vers => {
Ok(DecodedPdu { Ok(DecodedPdu {
serial: decoded.serial, serial: decoded.serial,
pdu: Pdu::$name(bincode::deserialize(&decoded.data)?) pdu: Pdu::$name(varbincode::deserialize(decoded.data.as_slice())?)
}) })
} }
,)* ,)*
@ -188,7 +186,7 @@ mod test {
fn test_frame() { fn test_frame() {
let mut encoded = Vec::new(); let mut encoded = Vec::new();
encode_raw(0x81, 0x42, b"hello", &mut encoded).unwrap(); encode_raw(0x81, 0x42, b"hello", &mut encoded).unwrap();
assert_eq!(&encoded, b"\x07\x42\x81hello"); assert_eq!(&encoded, b"\x08\x42\x81\x01hello");
let decoded = decode_raw(encoded.as_slice()).unwrap(); let decoded = decode_raw(encoded.as_slice()).unwrap();
assert_eq!(decoded.ident, 0x81); assert_eq!(decoded.ident, 0x81);
assert_eq!(decoded.serial, 0x42); assert_eq!(decoded.serial, 0x42);

View File

@ -1,5 +1,5 @@
use super::{deserialize, error::Error, serialize}; use super::{deserialize, serialize};
use serde::{Deserialize, Serialize}; use serde::Serialize;
use serde_derive::*; use serde_derive::*;
use std::collections::HashMap; use std::collections::HashMap;