11//! ObjectId
22
3- use libc;
4-
53use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
64use std:: { error, fmt, io, result} ;
75
8- use byteorder:: { BigEndian , ByteOrder , LittleEndian } ;
9- use md5;
6+ use byteorder:: { BigEndian , ByteOrder } ;
107
118use hex:: { self , FromHexError } ;
129
1310use rand:: { thread_rng, Rng } ;
1411
15- use hostname:: get_hostname;
1612use time;
1713
1814const TIMESTAMP_SIZE : usize = 4 ;
19- const MACHINE_ID_SIZE : usize = 3 ;
20- const PROCESS_ID_SIZE : usize = 2 ;
15+ const PROCESS_ID_SIZE : usize = 5 ;
2116const COUNTER_SIZE : usize = 3 ;
2217
2318const TIMESTAMP_OFFSET : usize = 0 ;
24- const MACHINE_ID_OFFSET : usize = TIMESTAMP_OFFSET + TIMESTAMP_SIZE ;
25- const PROCESS_ID_OFFSET : usize = MACHINE_ID_OFFSET + MACHINE_ID_SIZE ;
19+ const PROCESS_ID_OFFSET : usize = TIMESTAMP_OFFSET + TIMESTAMP_SIZE ;
2620const COUNTER_OFFSET : usize = PROCESS_ID_OFFSET + PROCESS_ID_SIZE ;
2721
2822const MAX_U24 : usize = 0xFF_FFFF ;
2923
3024static OID_COUNTER : AtomicUsize = AtomicUsize :: new ( 0 ) ;
31- static mut MACHINE_BYTES : Option < [ u8 ; 3 ] > = None ;
3225
3326/// Errors that can occur during OID construction and generation.
3427#[ derive( Debug ) ]
@@ -97,17 +90,13 @@ impl ObjectId {
9790 /// for more information.
9891 pub fn new ( ) -> Result < ObjectId > {
9992 let timestamp = ObjectId :: gen_timestamp ( ) ;
100- let machine_id = ObjectId :: gen_machine_id ( ) ?;
10193 let process_id = ObjectId :: gen_process_id ( ) ;
10294 let counter = ObjectId :: gen_count ( ) ?;
10395
10496 let mut buf: [ u8 ; 12 ] = [ 0 ; 12 ] ;
10597 for i in 0 ..TIMESTAMP_SIZE {
10698 buf[ TIMESTAMP_OFFSET + i] = timestamp[ i] ;
10799 }
108- for i in 0 ..MACHINE_ID_SIZE {
109- buf[ MACHINE_ID_OFFSET + i] = machine_id[ i] ;
110- }
111100 for i in 0 ..PROCESS_ID_SIZE {
112101 buf[ PROCESS_ID_OFFSET + i] = process_id[ i] ;
113102 }
@@ -154,20 +143,6 @@ impl ObjectId {
154143 BigEndian :: read_u32 ( & self . id )
155144 }
156145
157- /// Retrieves the machine id associated with an ObjectId.
158- pub fn machine_id ( & self ) -> u32 {
159- let mut buf: [ u8 ; 4 ] = [ 0 ; 4 ] ;
160- for i in 0 ..MACHINE_ID_SIZE {
161- buf[ i] = self . id [ MACHINE_ID_OFFSET + i] ;
162- }
163- LittleEndian :: read_u32 ( & buf)
164- }
165-
166- /// Retrieves the process id associated with an ObjectId.
167- pub fn process_id ( & self ) -> u16 {
168- LittleEndian :: read_u16 ( & self . id [ PROCESS_ID_OFFSET ..] )
169- }
170-
171146 /// Retrieves the increment counter from an ObjectId.
172147 pub fn counter ( & self ) -> u32 {
173148 let mut buf: [ u8 ; 4 ] = [ 0 ; 4 ] ;
@@ -193,47 +168,11 @@ impl ObjectId {
193168 buf
194169 }
195170
196- // Generates a new machine id represented as an MD5-hashed 3-byte-encoded hostname string.
197- // Represented in Little Endian.
198- fn gen_machine_id ( ) -> Result < [ u8 ; 3 ] > {
199- // Short-circuit if machine id has already been calculated.
200- // Since the generated machine id is not variable, arising race conditions
201- // will have the same MACHINE_BYTES result.
202- unsafe {
203- if let Some ( bytes) = MACHINE_BYTES . as_ref ( ) {
204- return Ok ( * bytes) ;
205- }
206- }
207-
208- let hostname = get_hostname ( ) ;
209- if hostname. is_none ( ) {
210- return Err ( Error :: HostnameError ) ;
211- }
212-
213- // Hash hostname string
214- let digest = md5:: compute ( hostname. unwrap ( ) . as_str ( ) ) ;
215- let hash = format ! ( "{:x}" , digest) ;
216-
217- // Re-convert string to bytes and grab first three
218- let mut bytes = hash. bytes ( ) ;
219- let mut vec: [ u8 ; 3 ] = [ 0 ; 3 ] ;
220- for v in & mut vec {
221- match bytes. next ( ) {
222- Some ( b) => * v = b,
223- None => break ,
224- }
225- }
226-
227- unsafe { MACHINE_BYTES = Some ( vec) } ;
228- Ok ( vec)
229- }
230-
231- // Gets the process ID and returns it as a 2-byte array.
232- // Represented in Little Endian.
233- fn gen_process_id ( ) -> [ u8 ; 2 ] {
234- let pid = unsafe { libc:: getpid ( ) as u16 } ;
235- let mut buf: [ u8 ; 2 ] = [ 0 ; 2 ] ;
236- LittleEndian :: write_u16 ( & mut buf, pid) ;
171+ // Generate a random 5-byte array.
172+ fn gen_process_id ( ) -> [ u8 ; 5 ] {
173+ let rng = thread_rng ( ) . gen_range ( 0 , MAX_U24 ) as u32 ;
174+ let mut buf: [ u8 ; 5 ] = [ 0 ; 5 ] ;
175+ BigEndian :: write_u32 ( & mut buf, rng) ;
237176 buf
238177 }
239178
@@ -276,13 +215,6 @@ impl fmt::Debug for ObjectId {
276215 }
277216}
278217
279- #[ test]
280- fn pid_generation ( ) {
281- let pid = unsafe { libc:: getpid ( ) as u16 } ;
282- let generated = ObjectId :: gen_process_id ( ) ;
283- assert_eq ! ( pid, LittleEndian :: read_u16( & generated) ) ;
284- }
285-
286218#[ test]
287219fn count_generated_is_big_endian ( ) {
288220 let start = 1_122_866 ;
0 commit comments