summaryrefslogtreecommitdiffstats
path: root/nix-rust
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-12-10 20:48:36 +0100
committerEelco Dolstra <edolstra@gmail.com>2019-12-10 22:15:20 +0100
commitf800d450b78091835ab7ca67847d76e75d877a24 (patch)
tree45f0f2677cda3c3ed484c5dd28c0a69208edab44 /nix-rust
parentf64b58b45e86e15f64aa2dff67436c2d6fe4a4d8 (diff)
Speed up StorePath::to_string()
1.81% -> 0.56%
Diffstat (limited to 'nix-rust')
-rw-r--r--nix-rust/src/c.rs9
-rw-r--r--nix-rust/src/store/path.rs4
-rw-r--r--nix-rust/src/util/base32.rs19
3 files changed, 24 insertions, 8 deletions
diff --git a/nix-rust/src/c.rs b/nix-rust/src/c.rs
index 4c1724eb3..19e737a88 100644
--- a/nix-rust/src/c.rs
+++ b/nix-rust/src/c.rs
@@ -1,6 +1,7 @@
use super::{
error,
foreign::{self, CBox},
+ store::path,
store::StorePath,
util,
};
@@ -53,8 +54,12 @@ pub unsafe extern "C" fn ffi_StorePath_drop(self_: *mut StorePath) {
}
#[no_mangle]
-pub extern "C" fn ffi_StorePath_to_string(self_: &StorePath) -> String {
- format!("{}", self_)
+pub extern "C" fn ffi_StorePath_to_string(self_: &StorePath) -> Vec<u8> {
+ let mut buf = vec![0; path::STORE_PATH_HASH_CHARS + 1 + self_.name.name().len()];
+ util::base32::encode_into(self_.hash.hash(), &mut buf[0..path::STORE_PATH_HASH_CHARS]);
+ buf[path::STORE_PATH_HASH_CHARS] = b'-';
+ buf[path::STORE_PATH_HASH_CHARS + 1..].clone_from_slice(self_.name.name().as_bytes());
+ buf
}
#[no_mangle]
diff --git a/nix-rust/src/store/path.rs b/nix-rust/src/store/path.rs
index 3ded5c428..2a2232475 100644
--- a/nix-rust/src/store/path.rs
+++ b/nix-rust/src/store/path.rs
@@ -70,7 +70,9 @@ impl StorePathHash {
impl fmt::Display for StorePathHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&base32::encode(&self.0))
+ let mut buf = vec![0; STORE_PATH_HASH_CHARS];
+ base32::encode_into(&self.0, &mut buf);
+ f.write_str(std::str::from_utf8(&buf).unwrap())
}
}
diff --git a/nix-rust/src/util/base32.rs b/nix-rust/src/util/base32.rs
index 8f6410f16..ba7368933 100644
--- a/nix-rust/src/util/base32.rs
+++ b/nix-rust/src/util/base32.rs
@@ -25,27 +25,36 @@ lazy_static! {
}
pub fn encode(input: &[u8]) -> String {
- let mut res = String::new();
- res.reserve(encoded_len(input.len()));
+ let mut buf = vec![0; encoded_len(input.len())];
+ encode_into(input, &mut buf);
+ std::str::from_utf8(&buf).unwrap().to_string()
+}
+
+pub fn encode_into(input: &[u8], output: &mut [u8]) {
+ let len = encoded_len(input.len());
+ assert_eq!(len, output.len());
let mut nr_bits_left: usize = 0;
let mut bits_left: u16 = 0;
+ let mut pos = len;
for b in input {
bits_left |= (*b as u16) << nr_bits_left;
nr_bits_left += 8;
while nr_bits_left > 5 {
- res.push(BASE32_CHARS[(bits_left & 0x1f) as usize] as char);
+ output[pos - 1] = BASE32_CHARS[(bits_left & 0x1f) as usize];
+ pos -= 1;
bits_left >>= 5;
nr_bits_left -= 5;
}
}
if nr_bits_left > 0 {
- res.push(BASE32_CHARS[(bits_left & 0x1f) as usize] as char);
+ output[pos - 1] = BASE32_CHARS[(bits_left & 0x1f) as usize];
+ pos -= 1;
}
- res.chars().rev().collect()
+ assert_eq!(pos, 0);
}
pub fn decode(input: &str) -> Result<Vec<u8>, crate::Error> {