diff options
author | Michael Widenius <monty@mysql.com> | 2008-10-10 18:28:41 +0300 |
---|---|---|
committer | Michael Widenius <monty@mysql.com> | 2008-10-10 18:28:41 +0300 |
commit | f47e003e1bfc56c2bf5d0f144a35517f526b538b (patch) | |
tree | e2bfb9834c6e558381465ed2f57a9d873a9b2c90 /mysys/my_uuid.c | |
parent | 51a92bbb03cc58ab8688fa9d8226afe32e6156ca (diff) | |
parent | 9daa56fd5ce3ccd33c32b5a505ac1d2b2c437460 (diff) | |
download | mariadb-git-f47e003e1bfc56c2bf5d0f144a35517f526b538b.tar.gz |
Merged 5.1 with maria 5.1
Diffstat (limited to 'mysys/my_uuid.c')
-rw-r--r-- | mysys/my_uuid.c | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/mysys/my_uuid.c b/mysys/my_uuid.c index d6a4946954a..36f1d2227f0 100644 --- a/mysys/my_uuid.c +++ b/mysys/my_uuid.c @@ -58,7 +58,8 @@ pthread_mutex_t LOCK_uuid_generator; 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */ -#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10) +#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \ + 1000 * 1000 * 10) #define UUID_VERSION 0x1000 #define UUID_VARIANT 0x8000 @@ -134,22 +135,63 @@ void my_uuid(uchar *to) pthread_mutex_lock(&LOCK_uuid_generator); tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq; - if (unlikely(tv < uuid_time)) - set_clock_seq(); - else if (unlikely(tv == uuid_time)) + + if (likely(tv > uuid_time)) { - /* special protection for low-res system clocks */ - nanoseq++; - tv++; + /* + Current time is ahead of last timestamp, as it should be. + If we "borrowed time", give it back, just as long as we + stay ahead of the previous timestamp. + */ + if (nanoseq) + { + DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0)); + /* + -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time) + */ + long delta= min(nanoseq, tv - uuid_time -1); + tv-= delta; + nanoseq-= delta; + } } else { - if (nanoseq && likely(tv-nanoseq >= uuid_time)) + if (unlikely(tv == uuid_time)) { - tv-=nanoseq; - nanoseq=0; + /* + For low-res system clocks. If several requests for UUIDs + end up on the same tick, we add a nano-second to make them + different. + ( current_timestamp + nanoseq * calls_in_this_period ) + may end up > next_timestamp; this is OK. Nonetheless, we'll + try to unwind nanoseq when we get a chance to. + If nanoseq overflows, we'll start over with a new numberspace + (so the if() below is needed so we can avoid the ++tv and thus + match the follow-up if() if nanoseq overflows!). + */ + if (likely(++nanoseq)) + ++tv; + } + + if (unlikely(tv <= uuid_time)) + { + /* + If the admin changes the system clock (or due to Daylight + Saving Time), the system clock may be turned *back* so we + go through a period once more for which we already gave out + UUIDs. To avoid duplicate UUIDs despite potentially identical + times, we make a new random component. + We also come here if the nanoseq "borrowing" overflows. + In either case, we throw away any nanoseq borrowing since it's + irrelevant in the new numberspace. + */ + set_clock_seq(); + tv= my_getsystime() + UUID_TIME_OFFSET; + nanoseq= 0; + DBUG_PRINT("uuid",("making new numberspace")); } } + uuid_time=tv; pthread_mutex_unlock(&LOCK_uuid_generator); @@ -185,7 +227,7 @@ void my_uuid2str(const uchar *guid, char *s) { *s++= _dig_vec_lower[guid[i] >>4]; *s++= _dig_vec_lower[guid[i] & 15]; - if(i == 4 || i == 6 || i == 8 || i == 10) + if(i == 3 || i == 5 || i == 7 || i == 9) *s++= '-'; } } |