From 3e43955fea64f26cdc1f260839b2980c931a962d Mon Sep 17 00:00:00 2001 From: lrlna Date: Sat, 5 Jan 2019 15:36:16 +0100 Subject: [PATCH 1/3] support wasm targets --- .travis.yml | 2 ++ Cargo.toml | 5 ++++- src/lib.rs | 7 +++++-- src/oid.rs | 39 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6e6daa6c..a790b7c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,9 @@ env: sudo: false script: + - rustup target add wasm32-unknown-unknown - cargo build -v + - cargo check --target wasm32-unknown-unknown - cargo test -v --no-fail-fast - cargo test -v --no-fail-fast --features u2i - cd serde-tests && cargo test -v --no-fail-fast diff --git a/Cargo.toml b/Cargo.toml index f7b4e98b..1cb18add 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,11 +29,14 @@ serde = "1.0" serde_json = { version = "1.0", features = ["preserve_order"] } time = "0.1" linked-hash-map = "0.5" -hostname = "0.1" hex = "0.3" md5 = "0.3" try_from = "0.2" +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +hostname = "0.1" +libc = "0.2" + [dev-dependencies] assert_matches = "1.2" serde_derive = "1.0" diff --git a/src/lib.rs b/src/lib.rs index c7b672e8..f74e3438 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,8 +45,6 @@ extern crate byteorder; extern crate chrono; extern crate hex; -extern crate hostname; -extern crate libc; extern crate linked_hash_map; extern crate rand; extern crate serde; @@ -56,6 +54,11 @@ extern crate md5; extern crate time; extern crate try_from; +#[cfg(not(target_arch = "wasm32"))] +extern crate hostname; +#[cfg(not(target_arch = "wasm32"))] +extern crate libc; + pub use self::bson::{Array, Bson, Document, TimeStamp, UtcDateTime}; pub use self::decoder::{decode_document, decode_document_utf8_lossy, from_bson, Decoder, DecoderError, DecoderResult}; pub use self::encoder::{encode_document, to_bson, Encoder, EncoderError, EncoderResult}; diff --git a/src/oid.rs b/src/oid.rs index ec1fbb4c..348a7fb6 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -1,18 +1,21 @@ //! ObjectId -use libc; - use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use std::{error, fmt, io, result}; use byteorder::{BigEndian, ByteOrder, LittleEndian}; -use md5; use hex::{self, FromHexError}; use rand::{thread_rng, Rng}; +#[cfg(not(target_arch = "wasm32"))] use hostname::get_hostname; +#[cfg(not(target_arch = "wasm32"))] +use libc; +#[cfg(not(target_arch = "wasm32"))] +use md5; + use time; const TIMESTAMP_SIZE: usize = 4; @@ -197,6 +200,7 @@ impl ObjectId { // Generates a new machine id represented as an MD5-hashed 3-byte-encoded hostname string. // Represented in Little Endian. + #[cfg(not(target_arch = "wasm32"))] fn gen_machine_id() -> Result<[u8; 3]> { // Short-circuit if machine id has already been calculated. // Since the generated machine id is not variable, arising race conditions @@ -230,8 +234,28 @@ impl ObjectId { Ok(vec) } + // In case of wasm compilation generates a random 3-byte array. + #[cfg(target_arch = "wasm32")] + fn gen_machine_id() -> Result<[u8; 3]> { + // Short-circuit if machine id has already been calculated. + // Since the generated machine id is not variable, arising race conditions + // will have the same MACHINE_BYTES result. + unsafe { + if let Some(bytes) = MACHINE_BYTES.as_ref() { + return Ok(bytes.clone()); + } + } + + let mut rng = rand::thread_rng(); + let vec: [u8; 3] = [rng.gen(), rng.gen(), rng.gen()]; + + unsafe { MACHINE_BYTES = Some(vec) }; + Ok(vec) + } + // Gets the process ID and returns it as a 2-byte array. // Represented in Little Endian. + #[cfg(not(target_arch = "wasm32"))] fn gen_process_id() -> [u8; 2] { let pid = unsafe { libc::getpid() as u16 }; let mut buf: [u8; 2] = [0; 2]; @@ -239,6 +263,14 @@ impl ObjectId { buf } + // In case of wasm return a random 2-byte array. + #[cfg(target_arch = "wasm32")] + fn gen_process_id() -> [u8; 2] { + let mut rng = rand::thread_rng(); + let vec: [u8; 2] = [rng.gen(), rng.gen()]; + vec + } + // Gets an incremental 3-byte count. // Represented in Big Endian. fn gen_count() -> Result<[u8; 3]> { @@ -279,6 +311,7 @@ impl fmt::Debug for ObjectId { } #[test] +#[cfg(not(target_arch = "wasm33"))] fn pid_generation() { let pid = unsafe { libc::getpid() as u16 }; let generated = ObjectId::gen_process_id(); From a1e7aa09adc72abbe01ab3fa6cf10af4fe52577e Mon Sep 17 00:00:00 2001 From: lrlna Date: Sat, 12 Jan 2019 12:21:57 +0100 Subject: [PATCH 2/3] generate a 5-byte random array instead of machine-id + process-id --- Cargo.toml | 4 -- src/lib.rs | 5 -- src/oid.rs | 117 +++---------------------------------------- tests/modules/oid.rs | 24 +++------ 4 files changed, 15 insertions(+), 135 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1cb18add..efbd1e01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,10 +33,6 @@ hex = "0.3" md5 = "0.3" try_from = "0.2" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -hostname = "0.1" -libc = "0.2" - [dev-dependencies] assert_matches = "1.2" serde_derive = "1.0" diff --git a/src/lib.rs b/src/lib.rs index f74e3438..f95f5564 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,11 +54,6 @@ extern crate md5; extern crate time; extern crate try_from; -#[cfg(not(target_arch = "wasm32"))] -extern crate hostname; -#[cfg(not(target_arch = "wasm32"))] -extern crate libc; - pub use self::bson::{Array, Bson, Document, TimeStamp, UtcDateTime}; pub use self::decoder::{decode_document, decode_document_utf8_lossy, from_bson, Decoder, DecoderError, DecoderResult}; pub use self::encoder::{encode_document, to_bson, Encoder, EncoderError, EncoderResult}; diff --git a/src/oid.rs b/src/oid.rs index 348a7fb6..5308303b 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -3,35 +3,25 @@ use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use std::{error, fmt, io, result}; -use byteorder::{BigEndian, ByteOrder, LittleEndian}; +use byteorder::{BigEndian, ByteOrder}; use hex::{self, FromHexError}; use rand::{thread_rng, Rng}; -#[cfg(not(target_arch = "wasm32"))] -use hostname::get_hostname; -#[cfg(not(target_arch = "wasm32"))] -use libc; -#[cfg(not(target_arch = "wasm32"))] -use md5; - use time; const TIMESTAMP_SIZE: usize = 4; -const MACHINE_ID_SIZE: usize = 3; -const PROCESS_ID_SIZE: usize = 2; +const PROCESS_ID_SIZE: usize = 5; const COUNTER_SIZE: usize = 3; const TIMESTAMP_OFFSET: usize = 0; -const MACHINE_ID_OFFSET: usize = TIMESTAMP_OFFSET + TIMESTAMP_SIZE; -const PROCESS_ID_OFFSET: usize = MACHINE_ID_OFFSET + MACHINE_ID_SIZE; +const PROCESS_ID_OFFSET: usize = TIMESTAMP_OFFSET + TIMESTAMP_SIZE; const COUNTER_OFFSET: usize = PROCESS_ID_OFFSET + PROCESS_ID_SIZE; const MAX_U24: usize = 0xFFFFFF; static OID_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; -static mut MACHINE_BYTES: Option<[u8; 3]> = None; /// Errors that can occur during OID construction and generation. #[derive(Debug)] @@ -100,7 +90,6 @@ impl ObjectId { /// for more information. pub fn new() -> Result { let timestamp = ObjectId::gen_timestamp(); - let machine_id = ObjectId::gen_machine_id()?; let process_id = ObjectId::gen_process_id(); let counter = ObjectId::gen_count()?; @@ -108,9 +97,6 @@ impl ObjectId { for i in 0..TIMESTAMP_SIZE { buf[TIMESTAMP_OFFSET + i] = timestamp[i]; } - for i in 0..MACHINE_ID_SIZE { - buf[MACHINE_ID_OFFSET + i] = machine_id[i]; - } for i in 0..PROCESS_ID_SIZE { buf[PROCESS_ID_OFFSET + i] = process_id[i]; } @@ -159,20 +145,6 @@ impl ObjectId { BigEndian::read_u32(&self.id) } - /// Retrieves the machine id associated with an ObjectId. - pub fn machine_id(&self) -> u32 { - let mut buf: [u8; 4] = [0; 4]; - for i in 0..MACHINE_ID_SIZE { - buf[i] = self.id[MACHINE_ID_OFFSET + i]; - } - LittleEndian::read_u32(&buf) - } - - /// Retrieves the process id associated with an ObjectId. - pub fn process_id(&self) -> u16 { - LittleEndian::read_u16(&self.id[PROCESS_ID_OFFSET..]) - } - /// Retrieves the increment counter from an ObjectId. pub fn counter(&self) -> u32 { let mut buf: [u8; 4] = [0; 4]; @@ -198,79 +170,14 @@ impl ObjectId { buf } - // Generates a new machine id represented as an MD5-hashed 3-byte-encoded hostname string. - // Represented in Little Endian. - #[cfg(not(target_arch = "wasm32"))] - fn gen_machine_id() -> Result<[u8; 3]> { - // Short-circuit if machine id has already been calculated. - // Since the generated machine id is not variable, arising race conditions - // will have the same MACHINE_BYTES result. - unsafe { - if let Some(bytes) = MACHINE_BYTES.as_ref() { - return Ok(bytes.clone()); - } - } - - let hostname = get_hostname(); - if hostname.is_none() { - return Err(Error::HostnameError); - } - - // Hash hostname string - let digest = md5::compute(hostname.unwrap().as_str()); - let hash = format!("{:x}", digest); - - // Re-convert string to bytes and grab first three - let mut bytes = hash.bytes(); - let mut vec: [u8; 3] = [0; 3]; - for i in 0..MACHINE_ID_SIZE { - match bytes.next() { - Some(b) => vec[i] = b, - None => break, - } - } - - unsafe { MACHINE_BYTES = Some(vec) }; - Ok(vec) - } - - // In case of wasm compilation generates a random 3-byte array. - #[cfg(target_arch = "wasm32")] - fn gen_machine_id() -> Result<[u8; 3]> { - // Short-circuit if machine id has already been calculated. - // Since the generated machine id is not variable, arising race conditions - // will have the same MACHINE_BYTES result. - unsafe { - if let Some(bytes) = MACHINE_BYTES.as_ref() { - return Ok(bytes.clone()); - } - } - - let mut rng = rand::thread_rng(); - let vec: [u8; 3] = [rng.gen(), rng.gen(), rng.gen()]; - - unsafe { MACHINE_BYTES = Some(vec) }; - Ok(vec) - } - - // Gets the process ID and returns it as a 2-byte array. - // Represented in Little Endian. - #[cfg(not(target_arch = "wasm32"))] - fn gen_process_id() -> [u8; 2] { - let pid = unsafe { libc::getpid() as u16 }; - let mut buf: [u8; 2] = [0; 2]; - LittleEndian::write_u16(&mut buf, pid); + // Generate a random 5-byte array. + fn gen_process_id() -> [u8; 5] { + let rng = thread_rng().gen_range(0, MAX_U24) as u32; + let mut buf: [u8; 5] = [0; 5]; + BigEndian::write_u32(&mut buf, rng); buf } - // In case of wasm return a random 2-byte array. - #[cfg(target_arch = "wasm32")] - fn gen_process_id() -> [u8; 2] { - let mut rng = rand::thread_rng(); - let vec: [u8; 2] = [rng.gen(), rng.gen()]; - vec - } - // Gets an incremental 3-byte count. // Represented in Big Endian. fn gen_count() -> Result<[u8; 3]> { @@ -310,14 +217,6 @@ impl fmt::Debug for ObjectId { } } -#[test] -#[cfg(not(target_arch = "wasm33"))] -fn pid_generation() { - let pid = unsafe { libc::getpid() as u16 }; - let generated = ObjectId::gen_process_id(); - assert_eq!(pid, LittleEndian::read_u16(&generated)); -} - #[test] fn count_generated_is_big_endian() { let start = 1122866; diff --git a/tests/modules/oid.rs b/tests/modules/oid.rs index 770c18bd..4017f85c 100644 --- a/tests/modules/oid.rs +++ b/tests/modules/oid.rs @@ -3,23 +3,12 @@ use hex; #[test] fn deserialize() { - let bytes: [u8; 12] = [0xDEu8, - 0xADu8, - 0xBEu8, - 0xEFu8, // timestamp is 3735928559 - 0xEFu8, - 0xCDu8, - 0xABu8, // machine_id is 11259375 - 0xFAu8, - 0x29u8, // process_id is 10746 - 0x11u8, - 0x22u8, + let bytes: [u8; 12] = [0xDEu8, 0xADu8, 0xBEu8, 0xEFu8, // timestamp is 3735928559 + 0xEFu8, 0xCDu8, 0xABu8, 0xFAu8, 0x29u8, 0x11u8, 0x22u8, 0x33u8 /* increment is 1122867 */]; let oid = ObjectId::with_bytes(bytes); assert_eq!(3735928559 as u32, oid.timestamp()); - assert_eq!(11259375 as u32, oid.machine_id()); - assert_eq!(10746 as u16, oid.process_id()); assert_eq!(1122867 as u32, oid.counter()); } @@ -83,14 +72,15 @@ fn oid_not_equals() { assert!(oid1 != oid2); } +// check that the last byte in objectIDs is increasing #[test] -fn increasing() { +fn counter_increasing() { let oid1_res = ObjectId::new(); let oid2_res = ObjectId::new(); assert!(oid1_res.is_ok()); assert!(oid2_res.is_ok()); - let oid1 = oid1_res.unwrap(); - let oid2 = oid2_res.unwrap(); - assert!(oid1 < oid2); + let oid1_bytes = oid1_res.unwrap().bytes(); + let oid2_bytes = oid2_res.unwrap().bytes(); + assert!(oid1_bytes[11] < oid2_bytes[11]); } From 2ca9739f12134b9ea3c6fa38104d84310320e747 Mon Sep 17 00:00:00 2001 From: lrlna Date: Tue, 14 May 2019 12:33:04 +0200 Subject: [PATCH 3/3] remove wasm check from travis to pass decimal128 check in upstream master --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a790b7c1..6e6daa6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,7 @@ env: sudo: false script: - - rustup target add wasm32-unknown-unknown - cargo build -v - - cargo check --target wasm32-unknown-unknown - cargo test -v --no-fail-fast - cargo test -v --no-fail-fast --features u2i - cd serde-tests && cargo test -v --no-fail-fast