Skip to content

Commit

Permalink
Get rid of an unnecessary vector allocation in map_new_from_slices (s…
Browse files Browse the repository at this point in the history
…tellar#1062)

* Get rid of an unnecessary vector allocation in `map_new_from_slices`

* Add/update the key/value slice len mismatch errors.
  • Loading branch information
dmkozh authored Sep 14, 2023
1 parent 1eadaec commit 0d7b94e
Showing 1 changed file with 19 additions and 14 deletions.
33 changes: 19 additions & 14 deletions soroban-env-host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,20 +1146,25 @@ impl EnvBase for Host {
}

fn map_new_from_slices(&self, keys: &[&str], vals: &[Val]) -> Result<MapObject, HostError> {
Vec::<Symbol>::charge_bulk_init_cpy(keys.len() as u64, self)?;
// If only fallible iterators worked better in Rust, we would not need this Vec<...>.
let mut key_syms: Vec<Symbol> = Vec::with_capacity(keys.len());
for k in keys.iter() {
key_syms.push(Symbol::try_from_val(self, k)?);
}
for v in vals.iter() {
self.check_val_integrity(*v)?;
if keys.len() != vals.len() {
return Err(self.err(
ScErrorType::Object,
ScErrorCode::UnexpectedSize,
"differing key and value slice lengths when creating map from slices",
&[],
));
}
let pair_iter = key_syms
Vec::<(Val, Val)>::charge_bulk_init_cpy(keys.len() as u64, self)?;
let map_vec = keys
.iter()
.map(|s| s.to_val())
.zip(vals.iter().cloned());
let map = HostMap::from_exact_iter(pair_iter, self)?;
.zip(vals.iter().copied())
.map(|(key_str, val)| {
let sym = Symbol::try_from_val(self, key_str)?;
self.check_val_integrity(val)?;
Ok((sym.to_val(), val))
})
.collect::<Result<Vec<(Val, Val)>, HostError>>()?;
let map = HostMap::from_map(map_vec, self)?;
self.add_host_object(map)
}

Expand All @@ -1173,7 +1178,7 @@ impl EnvBase for Host {
return Err(self.err(
ScErrorType::Object,
ScErrorCode::UnexpectedSize,
"differing key and value vector lengths when unpacking map to slice",
"differing key and value slice lengths when unpacking map to slice",
&[],
));
}
Expand All @@ -1182,7 +1187,7 @@ impl EnvBase for Host {
return Err(self.err(
ScErrorType::Object,
ScErrorCode::UnexpectedSize,
"differing host map and output vector lengths when unpacking map to slice",
"differing host map and output slice lengths when unpacking map to slice",
&[],
));
}
Expand Down

0 comments on commit 0d7b94e

Please sign in to comment.