Ocean/NumGen/GetUniqueID.go

72 lines
1.6 KiB
Go
Raw Permalink Normal View History

package NumGen
import (
"time"
)
// Function to generate a unique ID.
func GetUniqueID() (id int64) {
// Exklusive access:
genLock.Lock()
defer genLock.Unlock()
incremented := false
Retry:
// Read the current time
t1 := time.Now().UTC()
t1Milliseconds := int(float64(t1.Nanosecond()) / 1000000.0)
// Calculate the difference to the last generated number:
diff := t1.Sub(genCurrentTime)
// Case 1: Huge difference?
if diff.Seconds() > 1.0 {
genCurrentTime = t1
genCurrentMillisecond = t1Milliseconds
genCurrentMillisecondCounter = 0
id = generateUniqueID(genCurrentMillisecondCounter)
return
}
/*
The fist case is necessary, because the same count of milliseconds
can occur every second, etc. ;-) Therefore, a check only by the
milliseconds is not sufficient.
*/
// Case 2: Small difference?
if t1Milliseconds != genCurrentMillisecond {
genCurrentTime = t1
genCurrentMillisecond = t1Milliseconds
genCurrentMillisecondCounter = 0
id = generateUniqueID(genCurrentMillisecondCounter)
return
}
//
// Case 3: Another number must be generated at the same millisecond!
//
if incremented == false {
genCurrentMillisecondCounter++
incremented = true
}
// Case 3.1: More than 1000 numbers are generated at one millisecond?
if genCurrentMillisecondCounter > 999 {
// This is not possible with the current algorithm!
// Therefore, we force this and all other request to wait some time:
time.Sleep(1 * time.Millisecond)
// Try it again:
goto Retry
// Case 3.2: Less than 1000 numbers are generated at one millisecond?
} else {
// This case is fine:
id = generateUniqueID(genCurrentMillisecondCounter)
return
}
}