001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/framework/util/BasicUUIDFactory.java $ 002 /* 003 * 004 This class orginaly has been part of the apache derby project. It has 005 slightly been changed to match the requirements of deegree. 006 007 Derby - Class org.apache.derby.impl.services.uuid.BasicUUIDFactory 008 009 Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable. 010 011 Licensed under the Apache License, Version 2.0 (the "License"); 012 you may not use this file except in compliance with the License. 013 You may obtain a copy of the License at 014 015 http://www.apache.org/licenses/LICENSE-2.0 016 017 Unless required by applicable law or agreed to in writing, software 018 distributed under the License is distributed on an "AS IS" BASIS, 019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 020 See the License for the specific language governing permissions and 021 limitations under the License. 022 023 */ 024 package org.deegree.framework.util; 025 026 /** 027 * 028 * A hack implementation of something similar to a DCE UUID generator. Generates unique 128-bit 029 * numbers based on the current machine's internet address, the current time, and a sequence number. 030 * This implementation should be made to conform to the DCE specification. ("DEC/HP, Network 031 * Computing Architecture, Remote Procedure Call Runtime Extensions Specification, version OSF 032 * TX1.0.11," Steven Miller, July 23, 1992. This is part of the OSF DCE Documentation. Chapter 10 033 * describes the UUID generation algorithm.) 034 * <P> 035 * Some known deficiencies: 036 * <ul> 037 * <li> Rather than using the 48-bit hardware network address, it uses the 32-bit IP address. IP 038 * addresses are not guaranteed to be unique. 039 * <li> There is no provision for generating a suitably unique number if no IP address is available. 040 * <li> Two processes running on this machine which start their respective UUID services within a 041 * millisecond of one another may generate duplicate UUIDS. 042 * </ul> 043 * <P> 044 * However, the intention is that UUIDs generated from this class will be unique with respect to 045 * UUIDs generated by other DCE UUID generators. 046 * 047 * @deprecated use 048 * @see UUID 049 * 050 */ 051 052 public final class BasicUUIDFactory { 053 /* 054 * * Fields of BasicUUIDFactory. 055 */ 056 057 private long majorId; // 48 bits only 058 059 private long timemillis; 060 061 public BasicUUIDFactory() { 062 063 majorId = Runtime.getRuntime().freeMemory(); 064 065 majorId &= 0x0000ffffffffffffL; 066 resetCounters(); 067 } 068 069 public BasicUUIDFactory( long majorId ) { 070 071 this.majorId = majorId; 072 073 this.majorId &= 0x0000ffffffffffffL; 074 resetCounters(); 075 } 076 077 // 078 // Constants and fields for computing the sequence number. We started out with monotonically 079 // increasing sequence numbers but realized that this causes collisions at the 080 // ends of BTREEs built on UUID columns. So now we have a random number 081 // generator. We generate these numbers using a technique from Knuth 082 // "Seminumerical Algorithms," section 3.2 (Generating Uniform Random Numbers). 083 // The formula is: 084 // 085 // next = ( (MULTIPLIER * current) + STEP ) % MODULUS 086 // 087 // Here 088 // 089 // MODULUS = int size. 090 // MULTIPLIER = fairly close to the square root of MODULUS to force the 091 // sequence number to jump around. satisifies the rule that 092 // (MULTIPLIER-1) is divisible by 4 and by all the primes which 093 // divide MODULUS. 094 // STEP = a large number that keeps the sequence number jumping around. 095 // must be relatively prime to MODULUS. 096 // INITIAL_VALUE = a number guaranteeing that the first couple sequence numbers 097 // won't be monotonically increasing. 098 // 099 // The sequence numbers should jump around and cycle through all numbers which fit in an int. 100 101 private static final long MODULUS = ( 1L << 32 ); 102 103 private static final long MULTIPLIER = ( ( 1L << 14 ) + 1 ); 104 105 private static final long STEP = ( ( 1L << 27 ) + 1 ); 106 107 private static final long INITIAL_VALUE = ( 2551218188L ); 108 109 private long currentValue; 110 111 /* 112 * * Methods of UUID 113 */ 114 115 /** 116 * Generate a new UUID. 117 * 118 * @see UUIDFactory#createUUID 119 */ 120 public synchronized UUID createUUID() { 121 long cv = currentValue = ( ( MULTIPLIER * currentValue ) + STEP ) % MODULUS; 122 if ( cv == INITIAL_VALUE ) { 123 bumpMajor(); 124 } 125 int sequence = (int) cv; 126 127 return new BasicUUID( majorId, timemillis, sequence ); 128 } 129 130 /** 131 * Recreate a UUID previously generated UUID value. 132 * 133 * @see UUIDFactory#recreateUUID 134 */ 135 public UUID recreateUUID( String uuidstring ) { 136 return new BasicUUID( uuidstring ); 137 } 138 139 /** 140 * @see UUIDFactory#recreateUUID 141 */ 142 public UUID recreateUUID( byte[] b ) { 143 return new BasicUUID( b ); 144 } 145 146 private void bumpMajor() { 147 148 // 48 bits only 149 majorId = ( majorId + 1L ) & 0x0000ffffffffffffL; 150 if ( majorId == 0L ) 151 resetCounters(); 152 153 } 154 155 private void resetCounters() { 156 timemillis = System.currentTimeMillis(); 157 currentValue = INITIAL_VALUE; 158 } 159 }