001/* A superdense time object consists of a time stamp and an index.
002
003 Copyright (c) 2006-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.actor.util;
029
030///////////////////////////////////////////////////////////////////
031//// SuperdenseTime
032
033/**
034 This class defines the structure of superdense time used in domains having
035 time involved in computation. A superdense time object, s, consists of a time
036 stamp and an index, denoted as s = (t, n).
037 <p>
038 Two superdense time objects can be compared to see which one happens first.
039 The order is defined by the relationship between their time stamps and
040 indexes. In particular, given s_1 = (t_1, n_1) and s_2 = (t_2, n_2), s_1
041 happens earlier than s_2 (denoted as s_1 &le; s_2), if t_1 &lt; t_2 or (t_1 == t_2
042 and n_1 &le; n_2). The equality relation holds only if both t_1 == t_2 and
043 n_1 == n_2 hold.
044
045 @author Haiyang Zheng, Edward A. Lee
046 @version $Id$
047 @since Ptolemy II 5.2
048 @Pt.ProposedRating Green (hyzheng)
049 @Pt.AcceptedRating Green (hyzheng)
050 */
051public class SuperdenseTime implements Comparable {
052
053    /** Construct a superdense time object with the specified timestamp and
054     *  index.
055     *  @param timeStamp The time stamp.
056     *  @param index The index.
057     */
058    public SuperdenseTime(Time timeStamp, int index) {
059        _index = index;
060        _timeStamp = timeStamp;
061    }
062
063    ///////////////////////////////////////////////////////////////////
064    ////                         public methods                    ////
065
066    /** Compare this superdense time object with the argument superdense
067     *  time object for an order.
068     *  The argument has to be a superdense time object.
069     *  Otherwise, a ClassCastException will be thrown.
070     *
071     *  @param superdenseTime The superdense time object to compare against.
072     *  @return -1, 0, or 1, depending on the order of the events.
073     *  @exception ClassCastException If the argument is not a superdense
074     *   time object.
075     */
076    @Override
077    public final int compareTo(Object superdenseTime) {
078        return compareTo((SuperdenseTime) superdenseTime);
079    }
080
081    /** Compare this superdense time object with the argument superdense
082     *  time object for an order. Return -1, 0, or 1 if this superdense
083     *  time object happens earlier than, simultaneously with, or later than
084     *  the argument superdense time object.
085     *  <p>
086     *  Their timestamps are compared first. If the two timestamps are not
087     *  equal, their order defines the objects' order. Otherwise, the
088     *  indexes are compared for the order, where the object with
089     *  a smaller index happens earlier. If the two objects have the same
090     *  timestamp and index, then they happen simultaneously.
091     *
092     *  @param superdenseTime The superdense time object to compare against.
093     *  @return -1, 0, or 1, depends on the order.
094     */
095    public final int compareTo(SuperdenseTime superdenseTime) {
096        // FIXME: This should be compareTo(Object)
097        if (_timeStamp.compareTo(superdenseTime.timestamp()) > 0) {
098            return 1;
099        } else if (_timeStamp.compareTo(superdenseTime.timestamp()) < 0) {
100            return -1;
101        } else if (_index > superdenseTime.index()) {
102            return 1;
103        } else if (_index < superdenseTime.index()) {
104            return -1;
105        } else {
106            return 0;
107        }
108    }
109
110    /** Return true if this SuperdenseTime object has the same
111     *  timestamp and index as that of the given SuperdenseTime
112     *  object.
113     *  @param superdenseTime The SuperDenseTime object that this
114     *  SuperdenseTime object is compared to.
115     *  @return True if the two SuperDenseTime objects have the same
116     *  timestamp and index.
117     */
118    @Override
119    public boolean equals(Object superdenseTime) {
120        // See http://www.technofundo.com/tech/java/equalhash.html
121
122        // Findbugs says:
123        // "Eq: Class defines compareTo(...) and uses Object.equals()
124        // (EQ_COMPARETO_USE_OBJECT_EQUALS)"
125
126        // "This class defines a compareTo(...) method but
127        // inherits its equals() method from
128        // java.lang.Object. Generally, the value of compareTo
129        // should return zero if and only if equals returns
130        // true. If this is violated, weird and unpredictable
131        // failures will occur in classes such as
132        // PriorityQueue. In Java 5 the PriorityQueue.remove
133        // method uses the compareTo method, while in Java 6 it
134        // uses the equals method.
135
136        // "From the JavaDoc for the compareTo method in the Comparable
137        // interface:"
138
139        // "It is strongly recommended, but not strictly required that
140        // (x.compareTo(y)==0) == (x.equals(y)). Generally speaking,
141        // any class that implements the Comparable interface and
142        // violates this condition should clearly indicate this
143        // fact. The recommended language is "Note: this class has a
144        // natural ordering that is inconsistent with equals." "
145        if (superdenseTime == this) {
146            return true;
147        }
148        if (superdenseTime == null || superdenseTime.getClass() != getClass()) {
149            return false;
150        } else {
151            return compareTo((SuperdenseTime) superdenseTime) == 0;
152        }
153    }
154
155    /** Return the hash code for the SuperdenseTime object. If two
156     *  SuperdenseTime objects contains the same timestamp and index,
157     *  then they have the same hashcode.
158     *  @return The hash code for this SuperdenseTime object.
159     */
160    @Override
161    public int hashCode() {
162        // See http://www.technofundo.com/tech/java/equalhash.html
163        int hashCode = 31;
164        if (_timeStamp != null) {
165            hashCode = 31 * hashCode + _timeStamp.hashCode();
166        }
167        return 31 * hashCode + _index;
168    }
169
170    /** Return the index.
171     *  @return The index.
172     */
173    public final int index() {
174        return _index;
175    }
176
177    /** Return the timestamp.
178     *  @return The timestamp.
179     */
180    public final Time timestamp() {
181        return _timeStamp;
182    }
183
184    /** Return a description of this superdense time object.
185     *  @return A description of this superdense time object.
186     */
187    @Override
188    public final String toString() {
189        return "Superdense Time: time stamp = " + _timeStamp + " and index = "
190                + _index + ".";
191    }
192
193    ///////////////////////////////////////////////////////////////////
194    ////                         private variables                 ////
195
196    // The index of this superdense time object.
197    private int _index;
198
199    // The timestamp of this superdense time object.
200    private Time _timeStamp;
201}