1 19 package org.netbeans.mdr.persistence.btreeimpl.btreestorage; 20 21 import java.io.*; 22 import java.text.*; 23 import java.util.*; 24 25 103 108 public class UUID implements Comparable , Serializable 109 { 110 111 public static final int STRING_LENGTH = 36; 112 113 114 private int timeLow; 115 private short timeMid; 116 private short timeHiAndVersion; 117 private byte clockSeqHiAndReserved; 118 private byte clockSeqLow; 119 private byte nodeId[]; 120 121 124 public UUID() 125 { 126 nodeId = new byte[6]; 127 this.generate(); 128 } 129 130 136 public UUID(String str) throws NumberFormatException 137 { 138 StringTokenizer st = new StringTokenizer(str, "-", true); 139 nodeId = new byte[6]; 140 try 141 { 142 timeLow = (int)Long.parseLong(st.nextToken(), 16); 143 if (!st.nextToken().equals("-")) 144 throw new NumberFormatException (); 145 timeMid = (short)Integer.parseInt(st.nextToken(), 16); 146 if (!st.nextToken().equals("-")) 147 throw new NumberFormatException (); 148 timeHiAndVersion = (short)Integer.parseInt(st.nextToken(), 16); 149 if (!st.nextToken().equals("-")) 150 throw new NumberFormatException (); 151 short clock = (short)Integer.parseInt(st.nextToken(), 16); 152 clockSeqHiAndReserved = (byte)((clock >> 8) & 0xFF); 153 clockSeqLow = (byte)(clock & 0xFF); 154 if (!st.nextToken().equals("-")) 155 throw new NumberFormatException (); 156 String node = st.nextToken(); 157 for (int i = 0; i < 6; i++) 158 { 159 nodeId[i] = (byte)Integer.parseInt( 160 node.substring(i*2, i*2+2), 16); 161 } 162 } 163 catch (Exception ex) 164 { 165 throw new NumberFormatException (); 166 } 167 } 168 169 172 private void generate() 173 { 174 UUIDGenerator gener = UUIDGenerator.create(); 175 gener.generate(this); 176 } 177 178 186 public String toString() 187 { 188 Object nodeArgs[] = { 189 toHex(nodeId[0]), toHex(nodeId[1]), toHex(nodeId[2]), 190 toHex(nodeId[3]), toHex(nodeId[4]), toHex(nodeId[5]) 191 }; 192 String nodeString = 193 MessageFormat.format("{0}{1}{2}{3}{4}{5}", nodeArgs); 194 195 Object args[] = { 196 toHex(timeLow), toHex(timeMid), toHex(timeHiAndVersion), 197 toHex(clockSeqHiAndReserved), toHex(clockSeqLow), 198 nodeString 199 }; 200 201 return MessageFormat.format("{0}-{1}-{2}-{3}{4}-{5}", args); 202 } 203 204 207 public boolean equals(Object o) 208 { 209 if (!(o instanceof UUID)) 210 return false; 211 212 UUID other = (UUID)o; 213 return ( 214 other.timeLow == this.timeLow && 215 other.timeMid == this.timeMid && 216 other.timeHiAndVersion == this.timeHiAndVersion && 217 other.clockSeqHiAndReserved == this.clockSeqHiAndReserved && 218 other.clockSeqLow == this.clockSeqLow && 219 other.nodeId[0] == this.nodeId[0] && 220 other.nodeId[1] == this.nodeId[1] && 221 other.nodeId[2] == this.nodeId[2] && 222 other.nodeId[3] == this.nodeId[3] && 223 other.nodeId[4] == this.nodeId[4] && 224 other.nodeId[5] == this.nodeId[5]); 225 } 226 227 230 public int compareTo(Object o) 231 { 232 if (!(o instanceof UUID)) 233 throw new ClassCastException (); 234 235 UUID other = (UUID)o; 236 if (other.timeLow != this.timeLow) 237 return this.timeLow - other.timeLow; 238 if (other.timeMid != this.timeMid) 239 return this.timeMid - other.timeMid; 240 if (other.timeHiAndVersion != this.timeHiAndVersion) 241 return this.timeHiAndVersion - other.timeHiAndVersion; 242 if (other.clockSeqHiAndReserved != this.clockSeqHiAndReserved) 243 return this.clockSeqHiAndReserved - other.clockSeqHiAndReserved; 244 if (other.clockSeqLow != this.clockSeqLow) 245 return this.clockSeqLow - other.clockSeqLow; 246 for (int i = 0; i < 6; i++) 247 { 248 if (other.nodeId[i] != this.nodeId[i]) 249 return this.nodeId[i] - other.nodeId[i]; 250 } 251 return 0; 252 } 253 254 257 public int hashCode() 258 { 259 return (int)timeLow; 260 } 261 262 265 private static String toHex(byte num) 266 { 267 return toHex(((int)num & 0xFF), 2); 268 } 269 270 273 private static String toHex(short num) 274 { 275 return toHex(((int)num & 0xFFFF), 4); 276 } 277 278 281 private static String toHex(int num) 282 { 283 return toHex(num, 8); 284 } 285 286 287 291 private static String toHex(int num, int digits) 292 { 293 String hex = Integer.toHexString(num); 294 if (hex.length() < digits) 295 { 296 StringBuffer sb = new StringBuffer (); 297 int toAdd = digits - hex.length(); 298 for (int i = 0; i < toAdd; i++) 299 { 300 sb.append('0'); 301 } 302 sb.append(hex); 303 hex = sb.toString(); 304 } 305 return hex.toUpperCase(); 306 } 307 308 309 326 private static class UUIDGenerator 327 { 328 329 private static UUIDGenerator theGenerator; 330 331 332 private Random random1; 333 private Random random2; 334 335 336 private long lastTime; 337 338 342 private long timeAdjust; 343 344 348 private int clockSequence; 349 350 353 private byte nodeId[]; 354 355 356 private static final int CLOCK_SEQ_MASK = 0x3FFF; 357 358 359 private static final int VERSION_BITS = 0x1000; 360 361 362 private static final int RESERVED_BITS = 0x0080; 363 364 365 private static final int TIME_ADJUST_MASK = 0x0FFF; 366 367 368 private static final long N100NS_PER_MILLI = 10000; 369 370 371 private static final long EPOCH_CVT = 0x1B21DD213814000L; 372 373 374 375 public synchronized static UUIDGenerator create() 376 { 377 if (theGenerator == null) 378 theGenerator = new UUIDGenerator(); 379 return theGenerator; 380 } 381 382 383 private UUIDGenerator() 384 { 385 random1 = new Random(this.hashCode()); 386 random2 = new Random(Thread.currentThread().hashCode()); 387 nodeId = new byte[6]; 388 initializeNodeId(); 389 getClockSequence(); 390 } 391 392 393 public synchronized void generate(UUID uuid) 394 { 395 long now = System.currentTimeMillis(); 396 397 while (true) 398 { 399 if (now > lastTime) 400 { 401 402 getTimeAdjust(); 403 break; 404 } 405 else if (now < lastTime) 406 { 407 410 getClockSequence(); 411 getTimeAdjust(); 412 break; 413 } 414 else 415 { 416 417 timeAdjust++; 418 if (timeAdjust < N100NS_PER_MILLI) 419 { 420 break; 421 } 422 else 423 { 424 428 Thread.yield(); 429 } 430 } 431 } 432 433 lastTime = now; 434 long result = 435 (lastTime * N100NS_PER_MILLI) + EPOCH_CVT + timeAdjust; 436 437 438 uuid.timeLow = (int)(result & 0xFFFFFFFF); 439 uuid.timeMid = (short)((result >> 32) & 0xFFFF); 440 uuid.timeHiAndVersion = 441 (short)(((result >> 48) & 0xFFFF) | VERSION_BITS); 442 uuid.clockSeqHiAndReserved = 443 (byte)(((clockSequence >> 8) & 0xFF) | RESERVED_BITS); 444 uuid.clockSeqLow = (byte)(clockSequence & 0xFF); 445 for (int i = 0; i < 6; i++) 446 { 447 uuid.nodeId[i] = nodeId[i]; 448 } 449 } 450 451 452 private void getTimeAdjust() 453 { 454 timeAdjust = random2.nextInt() & TIME_ADJUST_MASK; 455 } 456 457 458 private void getClockSequence() 459 { 460 clockSequence = random1.nextInt() & CLOCK_SEQ_MASK; 461 if (clockSequence == 0) 462 clockSequence++; 463 } 464 465 466 468 private void initializeNodeId() 469 { 470 byte barr[] = new byte[2]; 471 472 Random r1 = new Random(); 473 Random r2 = new Random(r1.hashCode()); 474 r1.nextBytes(barr); 475 nodeId[0] = barr[0]; 476 nodeId[1] = barr[1]; 477 478 r2.nextBytes(barr); 479 nodeId[2] = barr[0]; 480 nodeId[3] = barr[1]; 481 482 nodeId[4] = (byte)0xaa; 483 nodeId[5] = 0x77; 484 } 485 } 486 } 487 | Popular Tags |