0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

oid cleaning

This commit is contained in:
dwight 2010-12-31 10:48:42 -05:00
parent d60aa255e3
commit c664067e07
2 changed files with 45 additions and 39 deletions

View File

@ -20,12 +20,14 @@
#include "util/atomic_int.h"
#include "../db/nonce.h"
BOOST_STATIC_ASSERT( sizeof(mongo::OID::MachineAndPid) == 5 );
BOOST_STATIC_ASSERT( sizeof(mongo::OID) == 12 );
namespace mongo {
static unsigned ourPid() {
// machine # before folding in the process id
OID::MachineAndPid OID::ourMachine;
unsigned OID::ourPid() {
unsigned pid;
#if defined(_WIN32)
pid = (unsigned short) GetCurrentProcessId();
@ -37,10 +39,7 @@ namespace mongo {
return pid;
}
// machine # before folding in the process id
static OID::MachineAndPid ourMachine;
static void foldInPid(OID::MachineAndPid& x) {
void OID::foldInPid(OID::MachineAndPid& x) {
unsigned p = ourPid();
x._pid ^= (unsigned short) p;
// when the pid is greater than 16 bits, let the high bits modulate the machine id field.
@ -48,17 +47,16 @@ namespace mongo {
rest ^= p >> 16;
}
static OID::MachineAndPid __gen() {
OID::MachineAndPid OID::genMachineAndPid() {
BOOST_STATIC_ASSERT( sizeof(mongo::OID::MachineAndPid) == 5 );
// this is not called often, so the following is not expensive, and gives us some
// testing that nonce generation is working right and that our OIDs are (perhaps) ok.
{
nonce a = security.getNonce();
nonce b = security.getNonce();
nonce c = security.getNonce();
nonce d = security.getNonce();
assert( a != b && a != c && a != d );
assert( b != c && b != d );
assert( c != d );
assert( !(a==b && b==c) );
}
unsigned long long n = security.getNonce();
@ -68,14 +66,14 @@ namespace mongo {
}
// after folding in the process id
static OID::MachineAndPid ourMachineAndPid = __gen();
OID::MachineAndPid OID::ourMachineAndPid = OID::genMachineAndPid();
void OID::regenMachineId() {
ourMachineAndPid = __gen();
ourMachineAndPid = genMachineAndPid();
}
inline bool operator!=(const OID::MachineAndPid& l, const OID::MachineAndPid& r) {
return l._pid != r._pid || l._machineNumber != r._machineNumber;
inline bool OID::MachineAndPid::operator!=(const OID::MachineAndPid& rhs) const {
return _pid != rhs._pid || _machineNumber != rhs._machineNumber;
}
unsigned OID::getMachineId() {
@ -92,7 +90,7 @@ namespace mongo {
// we let the random # for machine go into all 5 bytes of MachineAndPid, and then
// xor in the pid into _pid. this reduces the probability of collisions.
foldInPid(x);
ourMachineAndPid = __gen();
ourMachineAndPid = genMachineAndPid();
assert( x != ourMachineAndPid );
ourMachineAndPid = x;
}

View File

@ -37,27 +37,10 @@ namespace mongo {
a mostly increasing order.
*/
class OID {
public:
struct MachineAndPid {
unsigned char _machineNumber[3];
unsigned short _pid;
};
private:
union {
struct {
// 12 bytes total
unsigned char _time[4];
MachineAndPid _machineAndPid;
unsigned char _inc[3];
};
struct {
long long a;
unsigned b;
};
unsigned char data[12];
};
public:
OID() { }
/** init from a 24 char hex string */
explicit OID(const string &s) { init(s); }
/** initialize to 'null' */
@ -70,7 +53,7 @@ namespace mongo {
int compare( const OID& other ) const { return memcmp( data , other.data , 12 ); }
bool operator<( const OID& other ) const { return compare( other ) < 0; }
/** The object ID output as 24 hex digits. */
/** @return the object ID output as 24 hex digits */
string str() const { return toHexLower(data, 12); }
string toString() const { return str(); }
@ -79,7 +62,7 @@ namespace mongo {
/** sets the contents to a new oid / randomized value */
void init();
/** Set to the hex string value specified. */
/** init from a 24 char hex string */
void init( string s );
/** Set to the min/max OID that could be generated at given timestamp. */
@ -93,8 +76,33 @@ namespace mongo {
/** call this after a fork to update the process id */
static void justForked();
static unsigned getMachineId();
static void regenMachineId();
static unsigned getMachineId(); // features command uses
static void regenMachineId(); // used by unit tests
private:
struct MachineAndPid {
unsigned char _machineNumber[3];
unsigned short _pid;
bool operator!=(const OID::MachineAndPid& rhs) const;
};
static MachineAndPid ourMachine, ourMachineAndPid;
union {
struct {
// 12 bytes total
unsigned char _time[4];
MachineAndPid _machineAndPid;
unsigned char _inc[3];
};
struct {
long long a;
unsigned b;
};
unsigned char data[12];
};
static unsigned ourPid();
static void foldInPid(MachineAndPid& x);
static MachineAndPid genMachineAndPid();
};
#pragma pack()