@@ -36,13 +36,9 @@ public struct ObjectId : IComparable<ObjectId>, IEquatable<ObjectId>, IConvertib
36
36
private static int __staticIncrement ; // high byte will be masked out when generating new ObjectId
37
37
38
38
// private fields
39
- // we're using 14 bytes instead of 12 to hold the ObjectId in memory but unlike a byte[] there is no additional object on the heap
40
- // the extra two bytes are not visible to anyone outside of this class and they buy us considerable simplification
41
- // an additional advantage of this representation is that it will serialize to JSON without any 64 bit overflow problems
42
- private int _timestamp ;
43
- private int _machine ;
44
- private short _pid ;
45
- private int _increment ;
39
+ private int _a ;
40
+ private int _b ;
41
+ private int _c ;
46
42
47
43
// static constructor
48
44
static ObjectId ( )
@@ -71,7 +67,10 @@ public ObjectId(byte[] bytes)
71
67
{
72
68
throw new ArgumentNullException ( "bytes" ) ;
73
69
}
74
- Unpack ( bytes , out _timestamp , out _machine , out _pid , out _increment ) ;
70
+
71
+ _a = ( bytes [ 0 ] << 24 ) | ( bytes [ 1 ] << 16 ) | ( bytes [ 2 ] << 8 ) | bytes [ 3 ] ;
72
+ _b = ( bytes [ 4 ] << 24 ) | ( bytes [ 5 ] << 16 ) | ( bytes [ 6 ] << 8 ) | bytes [ 7 ] ;
73
+ _c = ( bytes [ 8 ] << 24 ) | ( bytes [ 9 ] << 16 ) | ( bytes [ 10 ] << 8 ) | bytes [ 11 ] ;
75
74
}
76
75
77
76
/// <summary>
@@ -81,10 +80,9 @@ public ObjectId(byte[] bytes)
81
80
/// <param name="index">The index into the byte array where the ObjectId starts.</param>
82
81
internal ObjectId ( byte [ ] bytes , int index )
83
82
{
84
- _timestamp = ( bytes [ index ] << 24 ) | ( bytes [ index + 1 ] << 16 ) | ( bytes [ index + 2 ] << 8 ) | bytes [ index + 3 ] ;
85
- _machine = ( bytes [ index + 4 ] << 16 ) | ( bytes [ index + 5 ] << 8 ) | bytes [ index + 6 ] ;
86
- _pid = ( short ) ( ( bytes [ index + 7 ] << 8 ) | bytes [ index + 8 ] ) ;
87
- _increment = ( bytes [ index + 9 ] << 16 ) | ( bytes [ index + 10 ] << 8 ) | bytes [ index + 11 ] ;
83
+ _a = ( bytes [ index ] << 24 ) | ( bytes [ index + 1 ] << 16 ) | ( bytes [ index + 2 ] << 8 ) | bytes [ index + 3 ] ;
84
+ _b = ( bytes [ index + 4 ] << 24 ) | ( bytes [ index + 5 ] << 16 ) | ( bytes [ index + 6 ] << 8 ) | bytes [ index + 7 ] ;
85
+ _c = ( bytes [ index + 8 ] << 24 ) | ( bytes [ index + 9 ] << 16 ) | ( bytes [ index + 10 ] << 8 ) | bytes [ index + 11 ] ;
88
86
}
89
87
90
88
/// <summary>
@@ -117,10 +115,9 @@ public ObjectId(int timestamp, int machine, short pid, int increment)
117
115
throw new ArgumentOutOfRangeException ( "increment" , "The increment value must be between 0 and 16777215 (it must fit in 3 bytes)." ) ;
118
116
}
119
117
120
- _timestamp = timestamp ;
121
- _machine = machine ;
122
- _pid = pid ;
123
- _increment = increment ;
118
+ _a = timestamp ;
119
+ _b = ( machine << 8 ) | ( ( ( int ) pid >> 8 ) & 0xff ) ;
120
+ _c = ( ( int ) pid << 24 ) | increment ;
124
121
}
125
122
126
123
/// <summary>
@@ -133,7 +130,11 @@ public ObjectId(string value)
133
130
{
134
131
throw new ArgumentNullException ( "value" ) ;
135
132
}
136
- Unpack ( BsonUtils . ParseHexString ( value ) , out _timestamp , out _machine , out _pid , out _increment ) ;
133
+
134
+ var bytes = BsonUtils . ParseHexString ( value ) ;
135
+ _a = ( bytes [ 0 ] << 24 ) | ( bytes [ 1 ] << 16 ) | ( bytes [ 2 ] << 8 ) | bytes [ 3 ] ;
136
+ _b = ( bytes [ 4 ] << 24 ) | ( bytes [ 5 ] << 16 ) | ( bytes [ 6 ] << 8 ) | bytes [ 7 ] ;
137
+ _c = ( bytes [ 8 ] << 24 ) | ( bytes [ 9 ] << 16 ) | ( bytes [ 10 ] << 8 ) | bytes [ 11 ] ;
137
138
}
138
139
139
140
// public static properties
@@ -151,39 +152,39 @@ public static ObjectId Empty
151
152
/// </summary>
152
153
public int Timestamp
153
154
{
154
- get { return _timestamp ; }
155
+ get { return _a ; }
155
156
}
156
157
157
158
/// <summary>
158
159
/// Gets the machine.
159
160
/// </summary>
160
161
public int Machine
161
162
{
162
- get { return _machine ; }
163
+ get { return ( _b >> 8 ) & 0xffffff ; }
163
164
}
164
165
165
166
/// <summary>
166
167
/// Gets the PID.
167
168
/// </summary>
168
169
public short Pid
169
170
{
170
- get { return _pid ; }
171
+ get { return ( short ) ( ( ( _b << 8 ) & 0xff00 ) | ( ( _c >> 24 ) & 0x00ff ) ) ; }
171
172
}
172
173
173
174
/// <summary>
174
175
/// Gets the increment.
175
176
/// </summary>
176
177
public int Increment
177
178
{
178
- get { return _increment ; }
179
+ get { return _c & 0xffffff ; }
179
180
}
180
181
181
182
/// <summary>
182
183
/// Gets the creation time (derived from the timestamp).
183
184
/// </summary>
184
185
public DateTime CreationTime
185
186
{
186
- get { return BsonConstants . UnixEpoch . AddSeconds ( _timestamp ) ; }
187
+ get { return BsonConstants . UnixEpoch . AddSeconds ( Timestamp ) ; }
187
188
}
188
189
189
190
// public operators
@@ -330,6 +331,7 @@ public static ObjectId Parse(string s)
330
331
{
331
332
throw new ArgumentNullException ( "s" ) ;
332
333
}
334
+
333
335
ObjectId objectId ;
334
336
if ( TryParse ( s , out objectId ) )
335
337
{
@@ -383,6 +385,7 @@ public static void Unpack(byte[] bytes, out int timestamp, out int machine, out
383
385
{
384
386
throw new ArgumentOutOfRangeException ( "bytes" , "Byte array must be 12 bytes long." ) ;
385
387
}
388
+
386
389
timestamp = ( bytes [ 0 ] << 24 ) + ( bytes [ 1 ] << 16 ) + ( bytes [ 2 ] << 8 ) + bytes [ 3 ] ;
387
390
machine = ( bytes [ 4 ] << 16 ) + ( bytes [ 5 ] << 8 ) + bytes [ 6 ] ;
388
391
pid = ( short ) ( ( bytes [ 7 ] << 8 ) + bytes [ 8 ] ) ;
@@ -425,13 +428,11 @@ private static int GetTimestampFromDateTime(DateTime timestamp)
425
428
/// <returns>A 32-bit signed integer that indicates whether this ObjectId is less than, equal to, or greather than the other.</returns>
426
429
public int CompareTo ( ObjectId other )
427
430
{
428
- int r = _timestamp . CompareTo ( other . _timestamp ) ;
429
- if ( r != 0 ) { return r ; }
430
- r = _machine . CompareTo ( other . _machine ) ;
431
- if ( r != 0 ) { return r ; }
432
- r = _pid . CompareTo ( other . _pid ) ;
433
- if ( r != 0 ) { return r ; }
434
- return _increment . CompareTo ( other . _increment ) ;
431
+ int result = ( ( uint ) _a ) . CompareTo ( ( uint ) other . _a ) ;
432
+ if ( result != 0 ) { return result ; }
433
+ result = ( ( uint ) _b ) . CompareTo ( ( uint ) other . _b ) ;
434
+ if ( result != 0 ) { return result ; }
435
+ return ( ( uint ) _c ) . CompareTo ( ( uint ) other . _c ) ;
435
436
}
436
437
437
438
/// <summary>
@@ -442,10 +443,9 @@ public int CompareTo(ObjectId other)
442
443
public bool Equals ( ObjectId rhs )
443
444
{
444
445
return
445
- _timestamp == rhs . _timestamp &&
446
- _machine == rhs . _machine &&
447
- _pid == rhs . _pid &&
448
- _increment == rhs . _increment ;
446
+ _a == rhs . _a &&
447
+ _b == rhs . _b &&
448
+ _c == rhs . _c ;
449
449
}
450
450
451
451
/// <summary>
@@ -472,10 +472,9 @@ public override bool Equals(object obj)
472
472
public override int GetHashCode ( )
473
473
{
474
474
int hash = 17 ;
475
- hash = 37 * hash + _timestamp . GetHashCode ( ) ;
476
- hash = 37 * hash + _machine . GetHashCode ( ) ;
477
- hash = 37 * hash + _pid . GetHashCode ( ) ;
478
- hash = 37 * hash + _increment . GetHashCode ( ) ;
475
+ hash = 37 * hash + _a . GetHashCode ( ) ;
476
+ hash = 37 * hash + _b . GetHashCode ( ) ;
477
+ hash = 37 * hash + _c . GetHashCode ( ) ;
479
478
return hash ;
480
479
}
481
480
@@ -485,7 +484,20 @@ public override int GetHashCode()
485
484
/// <returns>A byte array.</returns>
486
485
public byte [ ] ToByteArray ( )
487
486
{
488
- return Pack ( _timestamp , _machine , _pid , _increment ) ;
487
+ var bytes = new byte [ 12 ] ;
488
+ bytes [ 0 ] = ( byte ) ( _a >> 24 ) ;
489
+ bytes [ 1 ] = ( byte ) ( _a >> 16 ) ;
490
+ bytes [ 2 ] = ( byte ) ( _a >> 8 ) ;
491
+ bytes [ 3 ] = ( byte ) ( _a ) ;
492
+ bytes [ 4 ] = ( byte ) ( _b >> 24 ) ;
493
+ bytes [ 5 ] = ( byte ) ( _b >> 16 ) ;
494
+ bytes [ 6 ] = ( byte ) ( _b >> 8 ) ;
495
+ bytes [ 7 ] = ( byte ) ( _b ) ;
496
+ bytes [ 8 ] = ( byte ) ( _c >> 24 ) ;
497
+ bytes [ 9 ] = ( byte ) ( _c >> 16 ) ;
498
+ bytes [ 10 ] = ( byte ) ( _c >> 8 ) ;
499
+ bytes [ 11 ] = ( byte ) ( _c ) ;
500
+ return bytes ;
489
501
}
490
502
491
503
/// <summary>
@@ -495,18 +507,18 @@ public byte[] ToByteArray()
495
507
/// <param name="offset">The offset.</param>
496
508
public void ToByteArray ( byte [ ] destination , int offset )
497
509
{
498
- destination [ offset + 0 ] = ( byte ) ( _timestamp >> 24 ) ;
499
- destination [ offset + 1 ] = ( byte ) ( _timestamp >> 16 ) ;
500
- destination [ offset + 2 ] = ( byte ) ( _timestamp >> 8 ) ;
501
- destination [ offset + 3 ] = ( byte ) ( _timestamp ) ;
502
- destination [ offset + 4 ] = ( byte ) ( _machine >> 16 ) ;
503
- destination [ offset + 5 ] = ( byte ) ( _machine >> 8 ) ;
504
- destination [ offset + 6 ] = ( byte ) ( _machine ) ;
505
- destination [ offset + 7 ] = ( byte ) ( _pid >> 8 ) ;
506
- destination [ offset + 8 ] = ( byte ) ( _pid ) ;
507
- destination [ offset + 9 ] = ( byte ) ( _increment >> 16 ) ;
508
- destination [ offset + 10 ] = ( byte ) ( _increment >> 8 ) ;
509
- destination [ offset + 11 ] = ( byte ) ( _increment ) ;
510
+ destination [ offset + 0 ] = ( byte ) ( _a >> 24 ) ;
511
+ destination [ offset + 1 ] = ( byte ) ( _a >> 16 ) ;
512
+ destination [ offset + 2 ] = ( byte ) ( _a >> 8 ) ;
513
+ destination [ offset + 3 ] = ( byte ) ( _a ) ;
514
+ destination [ offset + 4 ] = ( byte ) ( _b >> 24 ) ;
515
+ destination [ offset + 5 ] = ( byte ) ( _b >> 16 ) ;
516
+ destination [ offset + 6 ] = ( byte ) ( _b >> 8 ) ;
517
+ destination [ offset + 7 ] = ( byte ) ( _b ) ;
518
+ destination [ offset + 8 ] = ( byte ) ( _c >> 24 ) ;
519
+ destination [ offset + 9 ] = ( byte ) ( _c >> 16 ) ;
520
+ destination [ offset + 10 ] = ( byte ) ( _c >> 8 ) ;
521
+ destination [ offset + 11 ] = ( byte ) ( _c ) ;
510
522
}
511
523
512
524
/// <summary>
@@ -515,24 +527,7 @@ public void ToByteArray(byte[] destination, int offset)
515
527
/// <returns>A string representation of the value.</returns>
516
528
public override string ToString ( )
517
529
{
518
- return BsonUtils . ToHexString ( Pack ( _timestamp , _machine , _pid , _increment ) ) ;
519
- }
520
-
521
- // internal methods
522
- internal void GetBytes ( byte [ ] bytes , int index )
523
- {
524
- bytes [ index ] = ( byte ) ( _timestamp >> 24 ) ;
525
- bytes [ 1 + index ] = ( byte ) ( _timestamp >> 16 ) ;
526
- bytes [ 2 + index ] = ( byte ) ( _timestamp >> 8 ) ;
527
- bytes [ 3 + index ] = ( byte ) ( _timestamp ) ;
528
- bytes [ 4 + index ] = ( byte ) ( _machine >> 16 ) ;
529
- bytes [ 5 + index ] = ( byte ) ( _machine >> 8 ) ;
530
- bytes [ 6 + index ] = ( byte ) ( _machine ) ;
531
- bytes [ 7 + index ] = ( byte ) ( _pid >> 8 ) ;
532
- bytes [ 8 + index ] = ( byte ) ( _pid ) ;
533
- bytes [ 9 + index ] = ( byte ) ( _increment >> 16 ) ;
534
- bytes [ 10 + index ] = ( byte ) ( _increment >> 8 ) ;
535
- bytes [ 11 + index ] = ( byte ) ( _increment ) ;
530
+ return BsonUtils . ToHexString ( ToByteArray ( ) ) ;
536
531
}
537
532
538
533
// explicit IConvertible implementation
0 commit comments