Skip to content

Commit

Permalink
[RSDK-9344] Use snappy for robot configuration compression
Browse files Browse the repository at this point in the history
  • Loading branch information
acmorrow committed Dec 18, 2024
1 parent 7bca1ac commit d315660
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ secrecy = { version = "~0.8.0", features = ["serde"] }
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
sha2 = "0.10.8"
snap = "1.1.1"
socket2 = "0.5.8"
stun_codec = { version = "0.3.0" , git = "https://github.com/viamrobotics/stun_codec"}
syn = "2.0.90"
Expand Down
1 change: 1 addition & 0 deletions micro-rdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ stun_codec.workspace = true
thiserror.workspace = true
trackable.workspace = true
uuid = { workspace = true, features = ["v4"]}
snap.workspace = true

[build-dependencies]
embuild.workspace = true
Expand Down
46 changes: 42 additions & 4 deletions micro-rdk/src/esp32/nvs_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
use bytes::Bytes;
use hyper::{http::uri::InvalidUri, Uri};
use prost::{DecodeError, Message};
use std::{cell::RefCell, rc::Rc};
use snap::{read::FrameDecoder, write::FrameEncoder};
use std::{
cell::RefCell,
io::{Read, Write},
rc::Rc,
};
use thiserror::Error;

use crate::{
Expand Down Expand Up @@ -34,6 +39,8 @@ pub enum NVSStorageError {
NVSValueDecodeError(#[from] DecodeError),
#[error(transparent)]
NVSUriParseError(#[from] InvalidUri),
#[error(transparent)]
NVSRobotConfigCompressionError(#[from] std::io::Error),
}

#[derive(Clone)]
Expand Down Expand Up @@ -207,13 +214,44 @@ impl RobotConfigurationStorage for NVSStorage {
}

fn store_robot_configuration(&self, cfg: &RobotConfig) -> Result<(), Self::Error> {
self.set_blob(NVS_ROBOT_CONFIG_KEY, cfg.encode_to_vec().into())?;
// Normally, we would just rely on blob comparison in
// `NVSStorage::set_blob` to dedup the write, but if snappy
// compression of the robot config isn't entirely
// deterministic, then that protection would be defeated. So,
// check the preimages here instead, and if they are
// equivalent, skip writing.
if self.has_robot_configuration() {
if let Ok(cached_cfg) = self.get_robot_configuration() {
if cached_cfg == *cfg {
return Ok(());
}
}
}

let encoded_cfg = cfg.encode_to_vec();
let mut compressor = FrameEncoder::new(Vec::new());
compressor
.write_all(&encoded_cfg[..])
.map_err(NVSStorageError::NVSRobotConfigCompressionError)?;
let compressed = compressor
.into_inner()
.map_err(|e| NVSStorageError::NVSRobotConfigCompressionError(e.into_error()))?;
log::info!(
"robot configuration compressed for NVS storage: {} bytes before, {} bytes after",
encoded_cfg.len(),
compressed.len()
);
self.set_blob(NVS_ROBOT_CONFIG_KEY, compressed.into())?;
Ok(())
}

fn get_robot_configuration(&self) -> Result<RobotConfig, Self::Error> {
let robot_config = self.get_blob(NVS_ROBOT_CONFIG_KEY)?;
RobotConfig::decode(&robot_config[..]).map_err(NVSStorageError::NVSValueDecodeError)
let mut decompressed_robot_config = vec![];
FrameDecoder::new(&self.get_blob(NVS_ROBOT_CONFIG_KEY)?[..])
.read_to_end(&mut decompressed_robot_config)
.map_err(NVSStorageError::NVSRobotConfigCompressionError)?;
RobotConfig::decode(&decompressed_robot_config[..])
.map_err(NVSStorageError::NVSValueDecodeError)
}

fn reset_robot_configuration(&self) -> Result<(), Self::Error> {
Expand Down

0 comments on commit d315660

Please sign in to comment.