@@ -100,24 +100,20 @@ public static ObjectId massageToObjectId( Object o ){
100
100
}
101
101
102
102
public ObjectId ( Date time ){
103
- _time = _flip ( (int )(time .getTime () / 1000 ) );
104
- _machine = _genmachine ;
105
- _inc = _nextInc .getAndIncrement ();
106
- _new = false ;
103
+ this (time , _genmachine , _nextInc .getAndIncrement ());
107
104
}
108
105
109
106
public ObjectId ( Date time , int inc ){
110
107
this ( time , _genmachine , inc );
111
108
}
112
109
113
110
public ObjectId ( Date time , int machine , int inc ){
114
- _time = _flip ( ( int )(time .getTime () / 1000 ) );
111
+ _time = ( int )(time .getTime () / 1000 );
115
112
_machine = machine ;
116
113
_inc = inc ;
117
114
_new = false ;
118
115
}
119
116
120
-
121
117
/** Creates a new instance from a string.
122
118
* @param s the string to convert
123
119
* @throws IllegalArgumentException if the string is not a valid id
@@ -133,44 +129,45 @@ public ObjectId( String s , boolean babble ){
133
129
134
130
if ( babble )
135
131
s = babbleToMongod ( s );
136
-
132
+
137
133
byte b [] = new byte [12 ];
138
134
for ( int i =0 ; i <b .length ; i ++ ){
139
- b [b . length -( i + 1 ) ] = (byte )Integer .parseInt ( s .substring ( i *2 , i *2 + 2 ) , 16 );
135
+ b [i ] = (byte )Integer .parseInt ( s .substring ( i *2 , i *2 + 2 ) , 16 );
140
136
}
141
137
ByteBuffer bb = ByteBuffer .wrap ( b );
142
-
143
- _inc = bb .getInt ();
144
- _machine = bb .getInt ();
145
138
_time = bb .getInt ();
146
-
139
+ _machine = bb .getInt ();
140
+ _inc = bb .getInt ();
147
141
_new = false ;
148
142
}
149
143
150
144
public ObjectId ( byte [] b ){
151
145
if ( b .length != 12 )
152
146
throw new IllegalArgumentException ( "need 12 bytes" );
153
- reverse ( b );
154
147
ByteBuffer bb = ByteBuffer .wrap ( b );
155
-
156
- _inc = bb .getInt ();
157
- _machine = bb .getInt ();
158
148
_time = bb .getInt ();
149
+ _machine = bb .getInt ();
150
+ _inc = bb .getInt ();
151
+ _new = false ;
159
152
}
160
153
161
-
154
+ /**
155
+ * Creates an ObjectId
156
+ * @param time time in seconds
157
+ * @param machine machine ID
158
+ * @param inc incremental value
159
+ */
162
160
public ObjectId ( int time , int machine , int inc ){
163
161
_time = time ;
164
162
_machine = machine ;
165
163
_inc = inc ;
166
-
167
164
_new = false ;
168
165
}
169
166
170
167
/** Create a new object id.
171
168
*/
172
169
public ObjectId (){
173
- _time = _curtime ( );
170
+ _time = ( int ) ( System . currentTimeMillis () / 1000 );
174
171
_machine = _genmachine ;
175
172
_inc = _nextInc .getAndIncrement ();
176
173
_new = true ;
@@ -221,20 +218,12 @@ public String toStringMongod(){
221
218
public byte [] toByteArray (){
222
219
byte b [] = new byte [12 ];
223
220
ByteBuffer bb = ByteBuffer .wrap ( b );
224
- bb .putInt ( _inc );
225
- bb .putInt ( _machine );
221
+ // by default BB is big endian like we need
226
222
bb .putInt ( _time );
227
- reverse ( b );
223
+ bb .putInt ( _machine );
224
+ bb .putInt ( _inc );
228
225
return b ;
229
226
}
230
-
231
- static void reverse ( byte [] b ){
232
- for ( int i =0 ; i <b .length /2 ; i ++ ){
233
- byte t = b [i ];
234
- b [i ] = b [ b .length -(i +1 ) ];
235
- b [b .length -(i +1 )] = t ;
236
- }
237
- }
238
227
239
228
static String _pos ( String s , int p ){
240
229
return s .substring ( p * 2 , ( p * 2 ) + 2 );
@@ -257,41 +246,61 @@ public String toString(){
257
246
return toStringMongod ();
258
247
}
259
248
260
- int _compare ( int i , int j ){
261
- i = _flip ( i ) ;
262
- j = _flip ( j ) ;
263
-
264
- final int diff = j - i ;
265
-
266
- if ( i >= 0 ){
267
- return j >= 0 ? - diff : - 1 ;
268
- }
269
-
270
- return j < 0 ? - diff : 1 ;
249
+ int _compareUnsigned ( int i , int j ){
250
+ long li = 0xFFFFFFFFL ;
251
+ li = i & li ;
252
+ long lj = 0xFFFFFFFFL ;
253
+ lj = j & lj ;
254
+ long diff = li - lj ;
255
+ if (diff < Integer . MIN_VALUE )
256
+ return Integer . MIN_VALUE ;
257
+ if ( diff > Integer . MAX_VALUE )
258
+ return Integer . MAX_VALUE ;
259
+ return ( int ) diff ;
271
260
}
272
261
273
262
public int compareTo ( ObjectId id ){
274
263
if ( id == null )
275
264
return -1 ;
276
265
277
- int x = _compare ( _time , id ._time );
266
+ int x = _compareUnsigned ( _time , id ._time );
278
267
if ( x != 0 )
279
268
return x ;
280
269
281
- x = _compare ( _machine , id ._machine );
270
+ x = _compareUnsigned ( _machine , id ._machine );
282
271
if ( x != 0 )
283
272
return x ;
284
273
285
- return _compare ( _inc , id ._inc );
274
+ x = _compareUnsigned ( _inc , id ._inc );
275
+ if (Math .abs (x ) > Integer .MAX_VALUE / 2 ) {
276
+ // this means that for same second and process more than (max int)/2 were generated
277
+ // highly unlikely, most likely the counter wrapped
278
+ if (x < 0 )
279
+ return 1 ;
280
+ else
281
+ return -1 ;
282
+ }
283
+ return x ;
286
284
}
287
285
288
286
public int getMachine (){
289
287
return _machine ;
290
288
}
291
-
289
+
290
+ /**
291
+ * Gets the time of this ID, in milliseconds
292
+ * @return
293
+ */
292
294
public long getTime (){
293
- long z = _flip ( _time );
294
- return z * 1000 ;
295
+ return _time * 1000L ;
296
+ }
297
+
298
+ /**
299
+ * Gets the time of this ID, in seconds
300
+ * @return
301
+ */
302
+ public int getTimeSecond (){
303
+ return _time ;
295
304
}
296
305
297
306
public int getInc (){
@@ -316,6 +325,22 @@ public void notNew(){
316
325
_new = false ;
317
326
}
318
327
328
+ /**
329
+ * Gets the generated machine ID, identifying the machine / process / class loader
330
+ * @return
331
+ */
332
+ public static int getGenMachineId () {
333
+ return _genmachine ;
334
+ }
335
+
336
+ /**
337
+ * Gets the current value of the auto increment
338
+ * @return
339
+ */
340
+ public static int getCurrentInc () {
341
+ return _nextInc .get ();
342
+ }
343
+
319
344
final int _time ;
320
345
final int _machine ;
321
346
final int _inc ;
@@ -331,12 +356,7 @@ public static int _flip( int x ){
331
356
return z ;
332
357
}
333
358
334
- private static int _curtime (){
335
- return _flip ( (int )(System .currentTimeMillis ()/1000 ) );
336
- }
337
-
338
359
private static AtomicInteger _nextInc = new AtomicInteger ( (new java .util .Random ()).nextInt () );
339
- private static final String _incLock = new String ( "ObjectId._incLock" );
340
360
341
361
private static final int _genmachine ;
342
362
static {
0 commit comments