001 /*
002 Copyright (c) 1996-2012, Damon Hart-Davis
003 All rights reserved.
004
005 Redistribution and use in source and binary forms, with or without
006 modification, are permitted provided that the following conditions are
007 met:
008
009 * Redistributions of source code must retain the above copyright
010 notice, this list of conditions and the following disclaimer.
011
012 * Redistributions in binary form must reproduce the above copyright
013 notice, this list of conditions and the following disclaimer in the
014 documentation and/or other materials provided with the
015 distribution.
016
017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028 */
029 package org.hd.d.pg2k.svrCore.vars;
030
031 import java.io.InvalidObjectException;
032 import java.io.ObjectInputValidation;
033 import java.io.ObjectStreamException;
034 import java.io.Serializable;
035
036 import org.hd.d.pg2k.svrCore.MemoryTools;
037 import org.hd.d.pg2k.svrCore.Rnd;
038
039
040 /**Immutable globally-unique instance ID for a JVM participating in a set of SystemVariables.
041 * This is the key to a globalmap variable,
042 * and each participating system should have just one such value,
043 * probably generated by a data pipeline endpoint.
044 * <p>
045 * Internally, this is a randomly-generated (non-negative) long value.
046 */
047 public final class InstanceID implements Serializable,
048 ObjectInputValidation,
049 MemoryTools.Internable,
050 Comparable<InstanceID>
051 {
052 /**Create a new, unique instance ID; never null.
053 * This is immediately intern()ed so that there will never be more than
054 * one copy of each unique InstanceID in memory at any one time
055 * (except transiently during deserialisation).
056 */
057 public static InstanceID createInstanceID()
058 {
059 return(MemoryTools.intern(new InstanceID()));
060 }
061
062 /**Create a new instance with a new/unique ID from a cryptographically-good random-number source. */
063 private InstanceID()
064 {
065 // Guaranteed non-negative new ID.
066 ID = (Rnd.goodRnd.nextLong() >>> 1);
067 }
068
069 /**Unique (positive) long ID from a cryptographically-good random-number source. */
070 private final long ID;
071
072 /**Long representation of ID; non-negative. */
073 public long longValue()
074 {
075 return(ID);
076 }
077
078 /**String representation of ID as a non-negative base-36 number. */
079 @Override
080 public String toString()
081 {
082 return(Long.toString(ID, Character.MAX_RADIX));
083 }
084
085 /**Comparable ordering is on ID value alone in numeric ID order. */
086 public int compareTo(final InstanceID other)
087 {
088 if(ID < other.ID) { return(-1); }
089 if(ID > other.ID) { return(+1); }
090 return(0);
091 }
092
093 /**Equality is based on the whole ID.
094 * But in fact due to instance control we can in fact use ==
095 * at least as an optimisation!
096 */
097 @Override
098 public boolean equals(final Object obj)
099 {
100 if(this == obj) { return(true); }
101 if(!(obj instanceof InstanceID)) { return(false); }
102 final InstanceID other = (InstanceID) obj;
103
104 // Compare the ID values.
105 return(ID == other.ID);
106 }
107
108 /**The hash is derived from the ID.
109 * This implementation just uses the hash of the name.
110 */
111 @Override
112 public int hashCode()
113 {
114 return((int) ID);
115 }
116
117 /**Deserialise: validate and eliminate duplicates coming off the wire.
118 * Ensures that there is never more than one copy of any given
119 * InstanceID value in memory (other than transiently).
120 *
121 * @return identical, de-duped, non-null instance
122 */
123 protected Object readResolve()
124 throws ObjectStreamException
125 {
126 validateObject();
127 return(MemoryTools.intern(this));
128 }
129
130 /**Check for legal state. */
131 public void validateObject()
132 throws InvalidObjectException
133 {
134 if(ID < 0)
135 { throw new InvalidObjectException("bad object: negative ID"); }
136 }
137
138 /**Unique Serialisation class ID generated by http://random.hd.org/. */
139 private static final long serialVersionUID = -2320309863687936784L;
140 }