1 /* 2 * (C) 2001 by Argonne National Laboratory 3 * See COPYRIGHT in top-level directory. 4 */ 5 6 /* 7 * @author Anthony Chan 8 */ 9 10 package base.drawable; 11 12 import java.util.Comparator; 13 import java.io.DataOutput; 14 import java.io.DataInput; 15 16 import base.io.DataIO; 17 18 public class TimeBoundingBox implements DataIO 19 { 20 public static final TimeBoundingBox ALL_TIMES 21 = new TimeBoundingBox( Double.NEGATIVE_INFINITY, 22 Double.POSITIVE_INFINITY ); 23 24 public static final Order INCRE_STARTTIME_ORDER 25 = new IncreasingStarttimeOrder(); 26 27 public static final Order DECRE_STARTTIME_ORDER 28 = new DecreasingStarttimeOrder(); 29 30 public static final Order INCRE_FINALTIME_ORDER 31 = new IncreasingFinaltimeOrder(); 32 33 public static final Order DECRE_FINALTIME_ORDER 34 = new DecreasingFinaltimeOrder(); 35 36 public static final int BYTESIZE = 8 /* earliest_time */ 37 + 8 /* latest_time */ ; 38 39 private double earliest_time; 40 private double latest_time; 41 TimeBoundingBox()42 public TimeBoundingBox() 43 { 44 earliest_time = Double.POSITIVE_INFINITY; 45 latest_time = Double.NEGATIVE_INFINITY; 46 } 47 TimeBoundingBox( final TimeBoundingBox timebox )48 public TimeBoundingBox( final TimeBoundingBox timebox ) 49 { 50 earliest_time = timebox.earliest_time; 51 latest_time = timebox.latest_time; 52 } 53 TimeBoundingBox( final Coord[] vtxs )54 public TimeBoundingBox( final Coord[] vtxs ) 55 { 56 if ( vtxs != null ) { 57 earliest_time = latest_time = vtxs[ 0 ].time; 58 for ( int idx = 1; idx < vtxs.length; idx++ ) { 59 this.affectEarliestTime( vtxs[ idx ].time ); 60 this.affectLatestTime( vtxs[ idx ].time ); 61 } 62 } 63 else { 64 earliest_time = Double.POSITIVE_INFINITY; 65 latest_time = Double.NEGATIVE_INFINITY; 66 } 67 } 68 TimeBoundingBox( double starttime, double finaltime )69 public TimeBoundingBox( double starttime, double finaltime ) 70 { 71 earliest_time = starttime; 72 latest_time = finaltime; 73 } 74 reinitialize()75 public void reinitialize() 76 { 77 earliest_time = Double.POSITIVE_INFINITY; 78 latest_time = Double.NEGATIVE_INFINITY; 79 } 80 affectTimeBounds( final TimeBoundingBox endtimes )81 public void affectTimeBounds( final TimeBoundingBox endtimes ) 82 { 83 this.affectEarliestTime( endtimes.getEarliestTime() ); 84 this.affectLatestTime( endtimes.getLatestTime() ); 85 } 86 affectTimeBounds( final Coord vtx )87 public void affectTimeBounds( final Coord vtx ) 88 { 89 this.affectEarliestTime( vtx.time ); 90 this.affectLatestTime( vtx.time ); 91 } 92 affectTimeBounds( final Coord[] vtxs )93 public void affectTimeBounds( final Coord[] vtxs ) 94 { 95 for ( int idx = 0; idx < vtxs.length; idx++ ) { 96 this.affectEarliestTime( vtxs[ idx ].time ); 97 this.affectLatestTime( vtxs[ idx ].time ); 98 } 99 } 100 101 affectEarliestTime( double in_time )102 public void affectEarliestTime( double in_time ) 103 { 104 if ( in_time < earliest_time ) 105 earliest_time = in_time; 106 } 107 setEarliestTime( double in_time )108 public void setEarliestTime( double in_time ) 109 { 110 earliest_time = in_time; 111 } 112 getEarliestTime()113 public double getEarliestTime() 114 { 115 return earliest_time; 116 } 117 118 affectLatestTime( double in_time )119 public void affectLatestTime( double in_time ) 120 { 121 if ( in_time > latest_time ) 122 latest_time = in_time; 123 } 124 setLatestTime( double in_time )125 public void setLatestTime( double in_time ) 126 { 127 latest_time = in_time; 128 } 129 getLatestTime()130 public double getLatestTime() 131 { 132 return latest_time; 133 } 134 135 getBorderTime( boolean isStartTime )136 public double getBorderTime( boolean isStartTime ) 137 { 138 if ( isStartTime ) 139 return earliest_time; 140 else 141 return latest_time; 142 } 143 144 145 // Functions useful in ScrollableObject 146 // This is used after this.setEarliestTime() is invoked. 147 // time_extent is positive definite setLatestFromEarliest( double time_extent )148 public void setLatestFromEarliest( double time_extent ) 149 { 150 latest_time = earliest_time + time_extent; 151 } 152 153 // This is used after this.setLatestTime() is invoked. 154 // time_extent is positive definite setEarliestFromLatest( double time_extent )155 public void setEarliestFromLatest( double time_extent ) 156 { 157 earliest_time = latest_time - time_extent; 158 } 159 isTimeOrdered()160 public boolean isTimeOrdered() 161 { 162 return earliest_time <= latest_time; 163 } 164 165 // Return true when endtimes covers the one end of this.TimeBoundingBox remove( final TimeBoundingBox endtimes )166 public boolean remove( final TimeBoundingBox endtimes ) 167 { 168 if ( this.earliest_time == endtimes.earliest_time ) { 169 this.earliest_time = endtimes.latest_time; 170 return true; 171 } 172 if ( this.latest_time == endtimes.latest_time ) { 173 this.latest_time = endtimes.earliest_time; 174 return true; 175 } 176 return false; 177 } 178 179 // TimeBoundingBox Checking Routines for SLOG-2 Input API 180 /* 181 Logic concerning overlaps(), covers() and disjoints() 182 1) covers() implies overlaps(). 183 2) !overlaps() implies disjoints(). 184 3) !disjoints() implies overlaps(). 185 */ covers( final TimeBoundingBox endtimes )186 public boolean covers( final TimeBoundingBox endtimes ) 187 { 188 return ( this.earliest_time <= endtimes.earliest_time ) 189 && ( endtimes.latest_time <= this.latest_time ); 190 } 191 overlaps( final TimeBoundingBox endtimes )192 public boolean overlaps( final TimeBoundingBox endtimes ) 193 { 194 return ( this.earliest_time <= endtimes.latest_time ) 195 && ( endtimes.earliest_time <= this.latest_time ); 196 } 197 198 // For consistence: Avoid using disjoints(), use !overlaps() instead disjoints( final TimeBoundingBox endtimes )199 public boolean disjoints( final TimeBoundingBox endtimes ) 200 { 201 return ( this.latest_time < endtimes.earliest_time ) 202 || ( endtimes.latest_time < this.earliest_time ); 203 } 204 contains( double timestamp )205 public boolean contains( double timestamp ) 206 { 207 return ( this.earliest_time <= timestamp ) 208 && ( timestamp <= this.latest_time ); 209 } 210 equals( final TimeBoundingBox endtimes )211 public boolean equals( final TimeBoundingBox endtimes ) 212 { 213 return ( this.earliest_time == endtimes.earliest_time ) 214 && ( this.latest_time == endtimes.latest_time ); 215 } 216 217 /* 218 containsWithinLeft()/containsWithinRight() are for logformat.slog2.Print 219 Or they are for logformat.slog2.input.InputLog.iterator() 220 */ containsWithinLeft( double timestamp )221 public boolean containsWithinLeft( double timestamp ) 222 { 223 return ( this.earliest_time <= timestamp ) 224 && ( timestamp < this.latest_time ); 225 } 226 containsWithinRight( double timestamp )227 public boolean containsWithinRight( double timestamp ) 228 { 229 return ( this.earliest_time < timestamp ) 230 && ( timestamp <= this.latest_time ); 231 } 232 getIntersection( final TimeBoundingBox endtimes )233 public TimeBoundingBox getIntersection( final TimeBoundingBox endtimes ) 234 { 235 TimeBoundingBox intersect_endtimes; 236 double intersect_earliest_time, intersect_latest_time; 237 238 if ( this.overlaps( endtimes ) ) { 239 if ( this.earliest_time < endtimes.earliest_time ) 240 intersect_earliest_time = endtimes.earliest_time; 241 else 242 intersect_earliest_time = this.earliest_time; 243 if ( this.latest_time < endtimes.latest_time ) 244 intersect_latest_time = this.latest_time; 245 else 246 intersect_latest_time = endtimes.latest_time; 247 intersect_endtimes = new TimeBoundingBox(); 248 intersect_endtimes.earliest_time = intersect_earliest_time; 249 intersect_endtimes.latest_time = intersect_latest_time; 250 return intersect_endtimes; 251 } 252 else 253 return null; 254 } 255 getIntersectionDuration( final TimeBoundingBox endtimes )256 public double getIntersectionDuration( final TimeBoundingBox endtimes ) 257 { 258 double intersect_earliest_time, intersect_latest_time; 259 double intersect_duration; 260 261 if ( this.overlaps( endtimes ) ) { 262 if ( this.earliest_time < endtimes.earliest_time ) 263 intersect_earliest_time = endtimes.earliest_time; 264 else 265 intersect_earliest_time = this.earliest_time; 266 if ( this.latest_time < endtimes.latest_time ) 267 intersect_latest_time = this.latest_time; 268 else 269 intersect_latest_time = endtimes.latest_time; 270 intersect_duration = intersect_latest_time 271 - intersect_earliest_time; 272 if ( intersect_duration > 0.0d ) 273 return intersect_duration; 274 else 275 return 0.0d; 276 } 277 else 278 return 0.0d; 279 } 280 281 /* For SLOG-2 Input API & viewer */ getDuration()282 public double getDuration() 283 { 284 return latest_time - earliest_time; 285 } 286 setZeroDuration( double time )287 public void setZeroDuration( double time ) 288 { 289 earliest_time = time; 290 latest_time = time; 291 } 292 293 writeObject( final TimeBoundingBox timebox, DataOutput outs )294 public static void writeObject( final TimeBoundingBox timebox, 295 DataOutput outs ) 296 throws java.io.IOException 297 { 298 outs.writeDouble( timebox.earliest_time ); 299 outs.writeDouble( timebox.latest_time ); 300 // timebox.writeObject( outs ) invokes InfoBox.writeObject( outs ) 301 } 302 readObject( TimeBoundingBox timebox, DataInput ins )303 public static void readObject( TimeBoundingBox timebox, 304 DataInput ins ) 305 throws java.io.IOException 306 { 307 timebox.earliest_time = ins.readDouble(); 308 timebox.latest_time = ins.readDouble(); 309 } 310 writeObject( DataOutput outs )311 public void writeObject( DataOutput outs ) 312 throws java.io.IOException 313 { 314 outs.writeDouble( earliest_time ); 315 outs.writeDouble( latest_time ); 316 } 317 TimeBoundingBox( DataInput ins )318 public TimeBoundingBox( DataInput ins ) 319 throws java.io.IOException 320 { 321 this.readObject( ins ); 322 } 323 readObject( DataInput ins )324 public void readObject( DataInput ins ) 325 throws java.io.IOException 326 { 327 earliest_time = ins.readDouble(); 328 latest_time = ins.readDouble(); 329 } 330 toString()331 public String toString() 332 { 333 /* 334 if ( latest_time - earliest_time >= 0 ) 335 return ( "TimeBBox( + )" ); 336 else 337 return ( "TimeBBox( - )" ); 338 */ 339 return ( "TimeBBox(" + earliest_time + "," + latest_time + ")" ); 340 } 341 toShortString()342 public String toShortString() 343 { 344 return ( "TimeBBox(" + (float) earliest_time 345 + "," + (float) latest_time + ")" ); 346 } 347 348 349 350 /* 351 Define TimeBoundingBox.Order as an alias of java.util.Comparator 352 */ 353 public interface Order extends Comparator 354 { isIncreasingTimeOrdered()355 public boolean isIncreasingTimeOrdered(); isStartTimeOrdered()356 public boolean isStartTimeOrdered(); toString()357 public String toString(); 358 } 359 360 /* 361 This comparator to Collections.sort() will arrange TimeBoundingBoxs 362 in increasing starttime order. If starttimes are equals, TimeBoundingBox 363 will then be arranged in decreasing finaltime order. 364 */ 365 private static class IncreasingStarttimeOrder implements Order 366 { compare( Object o1, Object o2 )367 public int compare( Object o1, Object o2 ) 368 { 369 TimeBoundingBox timebox1, timebox2; 370 timebox1 = (TimeBoundingBox) o1; 371 timebox2 = (TimeBoundingBox) o2; 372 if ( timebox1.earliest_time != timebox2.earliest_time ) 373 // increasing starttime order ( 1st order ) 374 return ( timebox1.earliest_time < timebox2.earliest_time 375 ? -1 : 1 ); 376 else { 377 if ( timebox1.latest_time != timebox2.latest_time ) 378 // decreasing finaltime order ( 2nd order ) 379 return ( timebox1.latest_time > timebox2.latest_time 380 ? -1 : 1 ); 381 else { 382 // if ( timebox1 == timebox2 ) 383 return 0; 384 } // FinalTime 385 } // StartTime 386 } 387 isIncreasingTimeOrdered()388 public boolean isIncreasingTimeOrdered() {return true;} isStartTimeOrdered()389 public boolean isStartTimeOrdered() {return true;} toString()390 public String toString() {return "INCRE_STARTTIME_ORDER";} 391 } 392 393 /* 394 This comparator to Collections.sort() will arrange TimeBoundingBoxs 395 in decreasing starttime order. If starttimes are equals, TimeBoundingBox 396 will then be arranged in increasing finaltime order. 397 */ 398 private static class DecreasingStarttimeOrder implements Order 399 { compare( Object o1, Object o2 )400 public int compare( Object o1, Object o2 ) 401 { 402 TimeBoundingBox timebox1, timebox2; 403 timebox1 = (TimeBoundingBox) o1; 404 timebox2 = (TimeBoundingBox) o2; 405 if ( timebox1.earliest_time != timebox2.earliest_time ) 406 // decreasing starttime order ( 1st order ) 407 return ( timebox1.earliest_time > timebox2.earliest_time 408 ? -1 : 1 ); 409 else { 410 if ( timebox1.latest_time != timebox2.latest_time ) 411 // increasing finaltime order ( 2nd order ) 412 return ( timebox1.latest_time < timebox2.latest_time 413 ? -1 : 1 ); 414 else { 415 // if ( timebox1 == timebox2 ) 416 return 0; 417 } // FinalTime 418 } // StartTime 419 } 420 isIncreasingTimeOrdered()421 public boolean isIncreasingTimeOrdered() {return false;} isStartTimeOrdered()422 public boolean isStartTimeOrdered() {return true;} toString()423 public String toString() {return "DECRE_STARTTIME_ORDER";} 424 } 425 426 /* 427 This comparator to Collections.sort() will arrange TimeBoundingBoxs 428 in increasing finaltime order. If finaltimes are equals, TimeBoundingBox 429 will then be arranged in decreasing starttime order. 430 */ 431 private static class IncreasingFinaltimeOrder implements Order 432 { compare( Object o1, Object o2 )433 public int compare( Object o1, Object o2 ) 434 { 435 TimeBoundingBox timebox1, timebox2; 436 timebox1 = (TimeBoundingBox) o1; 437 timebox2 = (TimeBoundingBox) o2; 438 if ( timebox1.latest_time != timebox2.latest_time ) 439 // increasing finaltime order ( 1st order ) 440 return ( timebox1.latest_time < timebox2.latest_time 441 ? -1 : 1 ); 442 else { 443 if ( timebox1.earliest_time != timebox2.earliest_time ) 444 // decreasing starttime order ( 2nd order ) 445 return ( timebox1.earliest_time > timebox2.earliest_time 446 ? -1 : 1 ); 447 else { 448 // if ( timebox1 == timebox2 ) 449 return 0; 450 } // StartTime 451 } // FinalTime 452 } 453 isIncreasingTimeOrdered()454 public boolean isIncreasingTimeOrdered() {return true;} isStartTimeOrdered()455 public boolean isStartTimeOrdered() {return false;} toString()456 public String toString() {return "INCRE_FINALTIME_ORDER";} 457 } 458 459 /* 460 This comparator to Collections.sort() will arrange TimeBoundingBoxs 461 in decreasing finaltime order. If finaltimes are equals, TimeBoundingBox 462 will then be arranged in increasing starttime order. 463 */ 464 private static class DecreasingFinaltimeOrder implements Order 465 { compare( Object o1, Object o2 )466 public int compare( Object o1, Object o2 ) 467 { 468 TimeBoundingBox timebox1, timebox2; 469 timebox1 = (TimeBoundingBox) o1; 470 timebox2 = (TimeBoundingBox) o2; 471 if ( timebox1.latest_time != timebox2.latest_time ) 472 // increasing finaltime order ( 1st order ) 473 return ( timebox1.latest_time > timebox2.latest_time 474 ? -1 : 1 ); 475 else { 476 if ( timebox1.earliest_time != timebox2.earliest_time ) 477 // decreasing starttime order ( 2nd order ) 478 return ( timebox1.earliest_time < timebox2.earliest_time 479 ? -1 : 1 ); 480 else { 481 // if ( timebox1 == timebox2 ) 482 return 0; 483 } // StartTime 484 } // FinalTime 485 } 486 isIncreasingTimeOrdered()487 public boolean isIncreasingTimeOrdered() {return false;} isStartTimeOrdered()488 public boolean isStartTimeOrdered() {return false;} toString()489 public String toString() {return "DECRE_FINALTIME_ORDER";} 490 } 491 main( String[] args )492 public static final void main( String[] args ) 493 { 494 TimeBoundingBox timebox = new TimeBoundingBox(); 495 System.out.println( timebox ); 496 497 if ( INCRE_STARTTIME_ORDER.equals( DECRE_STARTTIME_ORDER ) ) 498 System.out.println( "INCRE_STARTTIME_ORDER=DECRE_STARTTIME_ORDER" ); 499 else 500 System.out.println( "INCRE_STARTTIME_ORDER!DECRE_STARTTIME_ORDER" ); 501 502 if ( INCRE_STARTTIME_ORDER.equals( INCRE_FINALTIME_ORDER ) ) 503 System.out.println( "INCRE_STARTTIME_ORDER=INCRE_FINALTIME_ORDER" ); 504 else 505 System.out.println( "INCRE_STARTTIME_ORDER!INCRE_FINALTIME_ORDER" ); 506 507 if ( INCRE_STARTTIME_ORDER.equals( DECRE_FINALTIME_ORDER ) ) 508 System.out.println( "INCRE_STARTTIME_ORDER=DECRE_FINALTIME_ORDER" ); 509 else 510 System.out.println( "INCRE_STARTTIME_ORDER!DECRE_FINALTIME_ORDER" ); 511 512 if ( INCRE_STARTTIME_ORDER.equals( INCRE_STARTTIME_ORDER ) ) 513 System.out.println( "INCRE_STARTTIME_ORDER=INCRE_STARTTIME_ORDER" ); 514 else 515 System.out.println( "INCRE_STARTTIME_ORDER!INCRE_STARTTIME_ORDER" ); 516 517 TimeBoundingBox.Order tmp_order = new IncreasingStarttimeOrder(); 518 if ( INCRE_STARTTIME_ORDER.equals( tmp_order ) ) 519 System.out.println( "INCRE_STARTTIME_ORDER=tmp_order" ); 520 else 521 System.out.println( "INCRE_STARTTIME_ORDER!tmp_order" ); 522 } 523 524 } 525