KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > services > uuid > BasicUUIDFactory


1 /*
2
3    Derby - Class org.apache.derby.impl.services.uuid.BasicUUIDFactory
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.services.uuid;
23
24 import org.apache.derby.iapi.services.monitor.Monitor;
25 import org.apache.derby.catalog.UUID;
26 import org.apache.derby.iapi.services.uuid.UUIDFactory;
27
28 /**
29
30   A hack implementation of something similar to a DCE UUID
31   generator. Generates unique 128-bit numbers based on the
32   current machine's internet address, the current time, and
33   a sequence number. This implementation should be made to
34   conform to the DCE specification. ("DEC/HP, Network Computing
35   Architecture, Remote Procedure Call Runtime Extensions
36   Specification, version OSF TX1.0.11," Steven Miller, July
37   23, 1992. This is part of the OSF DCE Documentation.
38   Chapter 10 describes the UUID generation algorithm.)
39   <P>
40   Some known deficiencies:
41   <ul>
42   <li> Rather than using the 48-bit hardware network address,
43   it uses the 32-bit IP address. IP addresses are not
44   guaranteed to be unique.
45   <li> There is no provision for generating a suitably unique
46   number if no IP address is available.
47   <li> Two processes running on this machine which start their
48   respective UUID services within a millisecond of one another
49   may generate duplicate UUIDS.
50   </ul>
51   <P>
52   However, the intention is that UUIDs generated from this class
53   will be unique with respect to UUIDs generated by other DCE
54   UUID generators.
55
56 **/

57
58 public final class BasicUUIDFactory
59     implements UUIDFactory
60 {
61     /*
62     ** Fields of BasicUUIDFactory.
63     */

64
65     private long majorId; // 48 bits only
66
private long timemillis;
67
68     public BasicUUIDFactory() {
69         Object JavaDoc env = Monitor.getMonitor().getEnvironment();
70         if (env != null) {
71             String JavaDoc s = env.toString();
72             if (s != null)
73                 env = s;
74
75             majorId = ((long) env.hashCode());
76
77             
78         } else {
79             majorId = Runtime.getRuntime().freeMemory();
80         }
81
82         majorId &= 0x0000ffffffffffffL;
83         resetCounters();
84     }
85
86
87     //
88
// Constants and fields for computing the sequence number. We started out with monotonically
89
// increasing sequence numbers but realized that this causes collisions at the
90
// ends of BTREEs built on UUID columns. So now we have a random number
91
// generator. We generate these numbers using a technique from Knuth
92
// "Seminumerical Algorithms," section 3.2 (Generating Uniform Random Numbers).
93
// The formula is:
94
//
95
// next = ( (MULTIPLIER * current) + STEP ) % MODULUS
96
//
97
// Here
98
//
99
// MODULUS = int size.
100
// MULTIPLIER = fairly close to the square root of MODULUS to force the
101
// sequence number to jump around. satisifies the rule that
102
// (MULTIPLIER-1) is divisible by 4 and by all the primes which
103
// divide MODULUS.
104
// STEP = a large number that keeps the sequence number jumping around.
105
// must be relatively prime to MODULUS.
106
// INITIAL_VALUE = a number guaranteeing that the first couple sequence numbers
107
// won't be monotonically increasing.
108
//
109
// The sequence numbers should jump around and cycle through all numbers which fit in an int.
110

111     private static final long MODULUS = ( 1L << 32 );
112     private static final long MULTIPLIER = ( ( 1L << 14 ) + 1 );
113     private static final long STEP = ( ( 1L << 27 ) + 1 );
114     private static final long INITIAL_VALUE = ( 2551218188L );
115
116     private long currentValue;
117
118     /*
119     ** Methods of UUID
120     */

121
122     /**
123         Generate a new UUID.
124         @see UUIDFactory#createUUID
125     **/

126     public synchronized UUID createUUID()
127     {
128         long cv = currentValue = ( ( MULTIPLIER * currentValue ) + STEP ) % MODULUS;
129         if ( cv == INITIAL_VALUE ) { bumpMajor(); }
130         int sequence = (int) cv;
131
132         return new BasicUUID(majorId, timemillis, sequence);
133     }
134
135     /**
136         Recreate a UUID previously generated UUID value.
137         @see UUIDFactory#recreateUUID
138     **/

139     public UUID recreateUUID(String JavaDoc uuidstring)
140     {
141         return new BasicUUID(uuidstring);
142     }
143
144     /**
145         @see UUIDFactory#recreateUUID
146     **/

147     public UUID recreateUUID(byte[] b)
148     {
149         return new BasicUUID(b);
150     }
151
152     private void bumpMajor() {
153
154         // 48 bits only
155
majorId = (majorId + 1L) & 0x0000ffffffffffffL;
156         if (majorId == 0L)
157             resetCounters();
158
159     }
160     private void resetCounters()
161     {
162         timemillis = System.currentTimeMillis();
163         currentValue = INITIAL_VALUE;
164     }
165 }
166
167
Popular Tags