summaryrefslogtreecommitdiff
path: root/mysys/my_uuid.c
diff options
context:
space:
mode:
authorMichael Widenius <monty@mysql.com>2008-10-10 18:28:41 +0300
committerMichael Widenius <monty@mysql.com>2008-10-10 18:28:41 +0300
commitf47e003e1bfc56c2bf5d0f144a35517f526b538b (patch)
treee2bfb9834c6e558381465ed2f57a9d873a9b2c90 /mysys/my_uuid.c
parent51a92bbb03cc58ab8688fa9d8226afe32e6156ca (diff)
parent9daa56fd5ce3ccd33c32b5a505ac1d2b2c437460 (diff)
downloadmariadb-git-f47e003e1bfc56c2bf5d0f144a35517f526b538b.tar.gz
Merged 5.1 with maria 5.1
Diffstat (limited to 'mysys/my_uuid.c')
-rw-r--r--mysys/my_uuid.c64
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++= '-';
}
}