bp7/
helpers.rs

1#[cfg(feature = "instant")]
2use crate::ByteBuffer;
3use crate::{bundle, canonical, crc, dtntime, eid, flags::BlockControlFlags, primary, Bundle};
4
5use core::num::ParseIntError;
6use nanorand::{Rng, WyRand};
7#[cfg(feature = "instant")]
8use std::convert::TryFrom;
9use std::fmt::Write as _;
10#[cfg(feature = "instant")]
11use std::io::{stdout, Write};
12use std::time::{SystemTime, UNIX_EPOCH}; // import without risk of name clashing
13
14#[cfg(not(target_arch = "wasm32"))]
15pub fn unix_timestamp() -> u64 {
16    SystemTime::now()
17        .duration_since(UNIX_EPOCH)
18        .expect("Time went backwards!!")
19        .as_secs()
20}
21
22#[cfg(target_arch = "wasm32")]
23pub fn unix_timestamp() -> u64 {
24    (stdweb::web::Date::now() / 1000.0) as u64
25}
26
27#[cfg(not(target_arch = "wasm32"))]
28pub fn ts_ms() -> u64 {
29    SystemTime::now()
30        .duration_since(UNIX_EPOCH)
31        .expect("Time went backwards!!")
32        .as_millis() as u64
33}
34
35#[cfg(target_arch = "wasm32")]
36pub fn ts_ms() -> u64 {
37    (stdweb::web::Date::now()) as u64
38}
39
40/// Convert byte slice into a hex string
41pub fn hexify(buf: &[u8]) -> String {
42    let mut hexstr = String::new();
43    for &b in buf {
44        let _ = write!(hexstr, "{:02x}", b);
45    }
46    hexstr
47}
48/// Convert a hex string into a byte vector
49pub fn unhexify(s: &str) -> Result<Vec<u8>, ParseIntError> {
50    (0..s.len())
51        .step_by(2)
52        .map(|i| u8::from_str_radix(&s[i..i + 2], 16))
53        .collect()
54}
55
56pub fn ser_dump<T: serde::ser::Serialize>(input: &T, hr: &str) {
57    println!("Description | Value");
58    println!("--- | ---");
59    println!("human-readable | {}", hr);
60    let json = serde_json::to_string(input).unwrap();
61    println!("json | `{}`", json);
62    let cbor = serde_cbor::to_vec(input).unwrap();
63    println!(
64        "hex string | [`{}`](http://cbor.me/?bytes={})",
65        hexify(&cbor),
66        hexify(&cbor)
67    );
68    println!("byte array | `{:?}`\n", cbor);
69}
70pub fn vec_dump<T: serde::ser::Serialize>(input: &T, cbor: Vec<u8>, hr: &str) {
71    println!("Description | Value");
72    println!("--- | ---");
73    println!("human-readable | {}", hr);
74    let json = serde_json::to_string(input).unwrap();
75    println!("json | `{}`", json);
76    println!(
77        "hex string | [`{}`](http://cbor.me/?bytes={})",
78        hexify(&cbor),
79        hexify(&cbor)
80    );
81    println!("byte array | `{:?}`\n", cbor);
82}
83pub fn rnd_bundle(now: dtntime::CreationTimestamp) -> bundle::Bundle {
84    let mut rng = WyRand::new();
85    let singletons = ["sms", "files", "123456", "incoming", "mavlink"];
86    let groups = ["~news", "~tele", "~mavlink"];
87    //rng.shuffle(&mut singletons);
88    //rng.shuffle(&mut groups);
89    let concatenated = [&singletons[..], &groups[..]].concat();
90    //rng.shuffle(&mut concatenated);
91    let dst_string = format!(
92        "//node{}/{}",
93        rng.generate_range(1_u32..99),
94        concatenated[rng.generate_range(0_usize..concatenated.len())]
95    );
96    let src_string = format!(
97        "//node{}/{}",
98        rng.generate_range(1_u32..99),
99        singletons[rng.generate_range(0_usize..singletons.len())]
100    );
101    let dst = eid::EndpointID::with_dtn(&dst_string).unwrap();
102    let src = eid::EndpointID::with_dtn(&src_string).unwrap();
103    //let now = dtntime::CreationTimestamp::with_time_and_seq(dtntime::dtn_time_now(), 0);;
104    //let day0 = dtntime::CreationTimestamp::with_time_and_seq(dtntime::DTN_TIME_EPOCH, 0);;
105    let mut b = bundle::new_std_payload_bundle(src, dst, b"ABC".to_vec());
106    b.primary.creation_timestamp = now;
107    b
108}
109
110pub fn get_bench_bundle(crc_type: crc::CrcRawType) -> Bundle {
111    let dst = eid::EndpointID::with_dtn("//node2/inbox").unwrap();
112    let src = eid::EndpointID::with_dtn("//node1/123456").unwrap();
113    //let dst = eid::EndpointID::with_ipn(eid::IpnAddress(1, 2));
114    //let src = eid::EndpointID::with_ipn(eid::IpnAddress(2, 3));
115    let now = dtntime::CreationTimestamp::with_time_and_seq(dtntime::dtn_time_now(), 0);
116    //let now = dtntime::CreationTimestamp::with_time_and_seq(dtntime::DTN_TIME_EPOCH, 0);
117
118    //let pblock = primary::new_primary_block("dtn:node2/inbox".to_string(), "dtn:node1/123456".to_string(), now, 60 * 60 * 1_000_000);
119    let pblock = primary::PrimaryBlockBuilder::default()
120        .destination(dst)
121        .source(src.clone())
122        .report_to(src)
123        .creation_timestamp(now)
124        .lifetime(std::time::Duration::from_secs(60 * 60))
125        .build()
126        .unwrap();
127    let cblocks = vec![
128        canonical::new_payload_block(BlockControlFlags::empty(), b"ABC".to_vec()),
129        canonical::new_bundle_age_block(
130            2,                          // block number
131            BlockControlFlags::empty(), // flags
132            0,                          // time elapsed
133        ),
134    ];
135    //let cblocks = Vec::new();
136    let mut b = bundle::Bundle::new(pblock, cblocks);
137    // bundle builder is significantly slower!
138    /*let mut b = bundle::BundleBuilder::default()
139    .primary(pblock)
140    .canonicals(cblocks)
141    .build()
142    .unwrap();*/
143    b.set_crc(crc_type);
144    b.validate().unwrap();
145    b
146}
147#[cfg(feature = "instant")]
148use instant::Instant;
149
150#[cfg(feature = "instant")]
151pub fn bench_bundle_create(runs: i64, crc_type: crc::CrcRawType) -> Vec<ByteBuffer> {
152    let crc_str = match crc_type {
153        crc::CRC_NO => "CRC_NO",
154        crc::CRC_16 => "CRC_16",
155        crc::CRC_32 => "CRC_32",
156        _ => panic!("CRC_unknown"),
157    };
158    let mut bundles: Vec<ByteBuffer> = Vec::with_capacity(runs as usize);
159
160    print!("Creating {} bundles with {}: \t", runs, crc_str);
161    stdout().flush().unwrap();
162
163    let bench_now = Instant::now();
164
165    for _x in 0..runs {
166        let mut b = get_bench_bundle(crc_type);
167        let _serialized = b.to_cbor();
168        //let _serialized = b.to_json();
169        bundles.push(_serialized);
170    }
171    let elapsed = bench_now.elapsed();
172    let sec = (elapsed.as_secs() as f64) + (f64::from(elapsed.subsec_nanos()) / 1_000_000_000.0);
173    println!("{:>15} bundles/second", (runs as f64 / sec) as i64);
174    bundles
175}
176
177#[cfg(feature = "instant")]
178pub fn bench_bundle_encode(runs: i64, crc_type: crc::CrcRawType) -> Vec<ByteBuffer> {
179    let crc_str = match crc_type {
180        crc::CRC_NO => "CRC_NO",
181        crc::CRC_16 => "CRC_16",
182        crc::CRC_32 => "CRC_32",
183        _ => panic!("CRC_unknown"),
184    };
185    let mut bundles: Vec<ByteBuffer> = Vec::with_capacity(runs as usize);
186    //let mut bundles: Vec<String> = Vec::new();
187
188    print!("Encoding {} bundles with {}: \t", runs, crc_str);
189    stdout().flush().unwrap();
190
191    let bench_now = Instant::now();
192
193    let mut b = get_bench_bundle(crc_type);
194
195    for _x in 0..runs {
196        b.primary.lifetime += std::time::Duration::new(0, 1);
197        let _serialized = b.to_cbor();
198        //let _serialized = b.to_json();
199        bundles.push(_serialized);
200    }
201    let elapsed = bench_now.elapsed();
202    let sec = (elapsed.as_secs() as f64) + (f64::from(elapsed.subsec_nanos()) / 1_000_000_000.0);
203    println!("{:>15} bundles/second", (runs as f64 / sec) as i64);
204    bundles
205}
206
207#[cfg(feature = "instant")]
208pub fn bench_bundle_load(runs: i64, crc_type: crc::CrcRawType, mut bundles: Vec<ByteBuffer>) {
209    let crc_str = match crc_type {
210        crc::CRC_NO => "CRC_NO",
211        crc::CRC_16 => "CRC_16",
212        crc::CRC_32 => "CRC_32",
213        _ => panic!("CRC_unknown"),
214    };
215    print!("Loading {} bundles with {}: \t", runs, crc_str);
216    stdout().flush().unwrap();
217
218    let bench_now = Instant::now();
219    for _x in 0..runs {
220        let b = bundles.pop().unwrap();
221        let _deserialized: Bundle = Bundle::try_from(b.as_slice()).unwrap();
222        _deserialized.validate().unwrap();
223    }
224    let elapsed = bench_now.elapsed();
225    let sec = (elapsed.as_secs() as f64) + (f64::from(elapsed.subsec_nanos()) / 1_000_000_000.0);
226    println!("{:>15} bundles/second", (runs as f64 / sec) as i64);
227}