[JAVA-81] ObjectId does not follow the BSON ObjectId specification Created: 26/Jan/10  Updated: 01/Mar/10  Resolved: 26/Jan/10

Status: Closed
Project: Java Driver
Component/s: None
Affects Version/s: 1.2
Fix Version/s: None

Type: Bug Priority: Critical - P2
Reporter: Dror Bereznitsky Assignee: Eliot Horowitz (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The BSON ObjectId specification declares that the ObjectID is a 12-byte value consisting of a 4-byte timestamp, a 3-byte machine id, a 2-byte process id, and a 3-byte counter (http://www.mongodb.org/display/DOCS/Object+IDs)
The Java ObjectId constructors treat the 12-byte buffer as 3 4-bite integers - time, machine, inc. The 2-byte process id is not taken into consideration.
While time is initialized correctly, the other two values are wrong. This is especially critical for the compareTo method which fails in cases where the two ObjectId timestamps are equal and the inc part is used for comparison.



 Comments   
Comment by Dror Bereznitsky [ 27/Jan/10 ]

1) I would like to be able to get all the 4 parts of the ObjectId - timestamp, machine, process id and inc. Right now ObjectId already have getMachine(), getTime(), getInc() but getMachine() and getInc() returns incorrect values (when ObjectId is initialized from a String).
2) I would the compareTo method to behave as MongoDB behaves when it compares two ObjectIds.
Currently I have an issue where I query MongoDB for a set of documents sorted by their ObjectId and get a certain order, but if I sort the same set of documents using the ObjectId.compareTo() method I get another order.

Comment by Eliot Horowitz (Inactive) [ 26/Jan/10 ]

how its stored internally doesn't really matter.

do you mean the getMachine() method

are you saying you want a
getMachineCode()
getProcessCode()
etc?

Comment by Dror Bereznitsky [ 26/Jan/10 ]

I was referring to a scenario where I am creating an ObjectId from its String representation.
For example:

ObjectId id = new ObjectId("49902cde5162504500b45c2c");

It this case the following code from the constructor is incorrect since it disregards the process id:

_inc = bb.getInt();
_machine = bb.getInt();
_time = bb.getInt();

Asking for the "inc" or "machine" parts of the ObjectId will return wrong values.

Comment by Eliot Horowitz (Inactive) [ 26/Jan/10 ]

Look at the static initializer around line 314.

it gets the machine and the process

final int machinePiece;
{
StringBuilder sb = new StringBuilder();
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while ( e.hasMoreElements() )

{ NetworkInterface ni = e.nextElement(); sb.append( ni.toString() ); }

machinePiece = sb.toString().hashCode() << 16;
if ( D ) System.out.println( "machine piece post: " + Integer.toHexString( machinePiece ) );
}

final int processPiece = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().hashCode() & 0xFFFF;
if ( D ) System.out.println( "process piece: " + Integer.toHexString( processPiece ) );

_genmachine = machinePiece | processPiece;
if ( D ) System.out.println( "machine : " + Integer.toHexString( _genmachine ) );

Generated at Thu Feb 08 08:51:28 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.