aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/java/rmi/server/UID.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/rmi/server/UID.java')
-rw-r--r--libjava/classpath/java/rmi/server/UID.java262
1 files changed, 181 insertions, 81 deletions
diff --git a/libjava/classpath/java/rmi/server/UID.java b/libjava/classpath/java/rmi/server/UID.java
index 0f492ba..3596304 100644
--- a/libjava/classpath/java/rmi/server/UID.java
+++ b/libjava/classpath/java/rmi/server/UID.java
@@ -1,5 +1,5 @@
-/* UID.java --
- Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
+/* UID.java -- The unique object Id
+ Copyright (c) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,86 +42,186 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
-
-public final class UID implements Serializable
-{
-private static final long serialVersionUID = 1086053664494604050L;
-
-private static final Object lock = UID.class;
-private static long baseTime = System.currentTimeMillis();
-private static short nextCount = Short.MIN_VALUE;
-// This is sun's algorithm - don't ask me why ...
-private static final int uniqueNr = (new Object()).hashCode();
-
-private int unique;
-private long time;
-private short count;
+import java.net.InetAddress;
/**
- * This is sun's algorithm - don't ask me why ...
+ * Represents the unique identifier over time for the host which has generated
+ * it. It contains time (when created), counter (the number of the UID
+ * creation order) and virtual machine id components. The UID can also be
+ * constructed specifying a "well known" identifier in the for of short:
+ * this identifier defines the UID uniqueness alone.
+ *
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
*/
-public UID() {
- synchronized (lock) {
- if (nextCount == Short.MAX_VALUE) {
- long newtime;
- for (;;) {
- newtime = System.currentTimeMillis();
- if (newtime - baseTime > 1000) {
- break;
- }
- try {
- Thread.sleep(1000);
- }
- catch (InterruptedException _) {
- }
- }
- baseTime = newtime;
- nextCount = Short.MIN_VALUE;
- }
- count = nextCount++;
- unique = uniqueNr;
- time = baseTime;
- }
-}
-
-public UID(short num) {
- unique = (int)num;
- time = 0;
- count = 0;
-}
-
-public int hashCode() {
- return (unique);
-}
-
-public boolean equals(Object obj) {
- if (obj instanceof UID) {
- UID uid = (UID)obj;
- if (this.unique == uid.unique &&
- this.time == uid.time &&
- this.count == uid.count) {
- return (true);
- }
- }
- return (false);
-}
-
-public String toString() {
- return ("[UID: " + unique + "," + time + "," + count + "]");
-}
-
-public void write(DataOutput out) throws IOException {
- out.writeInt(unique);
- out.writeLong(time);
- out.writeShort(count);
-}
-
-public static UID read(DataInput in) throws IOException {
- UID id = new UID();
- id.unique = in.readInt();
- id.time = in.readLong();
- id.count = in.readShort();
- return (id);
-}
-
+public final class UID
+ implements Serializable
+{
+ /**
+ * Use the serial version uid for interoperability.
+ */
+ private static final long serialVersionUID = 1086053664494604050L;
+
+ /**
+ * The UID counter (the ordinary number in the sequence of number of UID's,
+ * created during the recent millisecond). In the next millisecond, it
+ * starts from the minimal value again. In the unlikely case of creating
+ * more than 65536 uids per millisecond the process pauses till the next
+ * ms.
+ */
+ private static short uidCounter = Short.MIN_VALUE;
+
+ /**
+ * The time, when the last UID has been created.
+ */
+ private static long last;
+
+ /**
+ * This constant tries to be the unique identifier of the virtual machine.
+ */
+ private static final int machineId = getMachineId();
+
+ /**
+ * The UID number in the UID creation sequence.
+ */
+ private short count;
+
+ /**
+ * Always gets the uniqueNr value.
+ */
+ private int unique;
+
+ /**
+ * The time stamp, when the UID was created.
+ */
+ private long time;
+
+ /**
+ * Create the new UID that would have the described features of the
+ * uniqueness.
+ */
+ public UID()
+ {
+ time = System.currentTimeMillis();
+ unique = machineId;
+ if (time > last)
+ {
+ last = time;
+ count = uidCounter = Short.MIN_VALUE;
+ }
+ else
+ {
+ synchronized (UID.class)
+ {
+ if (uidCounter == Short.MAX_VALUE)
+ {
+ // Make a 2 ms pause if the counter has reached the maximal
+ // value. This should seldom happen.
+ try
+ {
+ Thread.sleep(2);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ uidCounter = Short.MIN_VALUE;
+ time = last = System.currentTimeMillis();
+ }
+
+ count = uidCounter++;
+ }
+ }
+ }
+
+ /**
+ * Create the new UID with the well known id (number). All UIDs, creates
+ * with the this constructor having the same parameter are equal to each
+ * other (regardless to the host and time where they were created.
+ *
+ * @param wellKnownId the well known UID.
+ */
+ public UID(short wellKnownId)
+ {
+ unique = wellKnownId;
+ }
+
+ /**
+ * Get the hashCode of this UID.
+ */
+ public int hashCode()
+ {
+ return (int) (unique ^ time ^ count);
+ }
+
+ /**
+ * Compare this UID with another UID for equality (not equal to other types of
+ * objects).
+ */
+ public boolean equals(Object other)
+ {
+ if (other instanceof UID)
+ {
+ UID ui = (UID) other;
+ return unique == ui.unique && time == ui.time && count == ui.count;
+ }
+ else
+ return false;
+ }
+
+ public static UID read(DataInput in) throws IOException
+ {
+ UID uid = new UID();
+ uid.unique = in.readInt();
+ uid.time = in.readLong();
+ uid.count = in.readShort();
+ return (uid);
+ }
+
+ public void write(DataOutput out) throws IOException
+ {
+ out.writeInt(unique);
+ out.writeLong(time);
+ out.writeShort(count);
+ }
+
+ /**
+ * Do our best to get the Id of this virtual machine.
+ */
+ static int getMachineId()
+ {
+ int hostIpHash;
+
+ try
+ {
+ // Try to get the host IP.
+ String host = InetAddress.getLocalHost().toString();
+ // This hash is content - based, not the address based.
+ hostIpHash = host.hashCode();
+ }
+ catch (Exception e)
+ {
+ // Failed due some reason.
+ hostIpHash = 0;
+ }
+
+ // Should be the unque address if hashcodes are addresses.
+ // Additionally, add the time when the RMI system was probably started
+ // (this class was first instantiated).
+ return new Object().hashCode() ^ (int) System.currentTimeMillis()
+ ^ hostIpHash;
+ }
+
+ /**
+ * Get the string representation of this UID.
+ *
+ * @return a string, uniquely identifying this id.
+ */
+ public String toString()
+ {
+ int max = Character.MAX_RADIX;
+ // Translate into object count, counting from 0.
+ long lc = (count + Short.MIN_VALUE) & 0xFFFF;
+ return Long.toString(time, max) + ":"
+ + Long.toString(unique, max) + ":"
+ + Long.toString(lc, max);
+ }
}