48 * <p>
49 * Objects of this type run to completion and are then immutable.
50 */
51 class TT_NodeCache implements Runnable {
52
53 /**
54 * Construct a cache object which will collect info about the given node
55 * with respect to the supplied filter.
56 *
57 * @param n Node to examine, should not be null.
58 * @param f Filter to use when producing information. Can be null.
59 */
60 TT_NodeCache(TestResultTable.TreeNode n, TestFilter f, Logger l) {
61 filter = f;
62 node = n;
63 log = l;
64
65 // all the states plus filtered out
66 testLists = new Vector[Status.NUM_STATES + 1];
67 for (int i = 0; i < Status.NUM_STATES + 1; i++) {
68 testLists[i] = new Vector();
69 }
70 }
71
72 /**
73 * Start or resume processing.
74 */
75 public void run() {
76 if (debug) {
77 Debug.println("TT_NodeCache starting");
78 Debug.println(" -> " + this);
79 Debug.println(" -> node " + node + "(" + node.getName() + ")");
80 Debug.println(" -> filter=" + filter);
81 Debug.println(" -> old state=" + state);
82 }
83
84 // needed for a new run, a paused object will already have one
85 if (it == null) {
86 it = init();
87 }
88
501 * @see #isActive()
502 * @see com.sun.javatest.Status#NUM_STATES
503 */
504 int[] getStats() {
505 return stats;
506 }
507
508 /**
509 * Find out how many tests were rejected by filters.
510 * @return Number of rejected tests found in and below this node.
511 */
512 int getRejectCount() {
513 if (it != null) {
514 return it.getRejectCount() + localRejectCount;
515 } else {
516 return localRejectCount;
517 }
518 }
519
520 TestFilter getRejectReason(TestResult tr) {
521 return (TestFilter) (rejectReasons.get(tr));
522 }
523
524 /**
525 * Snapshot the current data and add an observer.
526 * This is an atomic operation so that you can get completely up to date
527 * and monitor all changes going forward.
528 *
529 * @param obs The observer to attach. Must not be null.
530 * @param needSnapshot Does the caller want a snapshot of the current test lists.
531 * True if yes, false if not.
532 * @return A copy of the Vectors that contain the current list of tests. Null if
533 * <tt>needSnapshot</tt> is false.
534 */
535 synchronized Vector[] addObserver(TT_NodeCacheObserver obs, boolean needSnapshot) {
536 // snapshot the current data
537 // must be done before adding the observer to ensure correct data
538 // delivery to client
539
540 Vector[] cp = null;
541 if (needSnapshot) {
542 cp = new Vector[testLists.length];
543 for (int i = 0; i < testLists.length; i++) {
544 cp[i] = (Vector) (testLists[i].clone());
545 }
546 }
547
548 if (obs != null) {
549 observers = (TT_NodeCacheObserver[]) DynamicArray.append(observers, obs);
550 }
551
552 return cp;
553 }
554
555 // advisory - many thread access this. you should lock this object before
556 // calling. See BP_TestListSubpanel.reset(TT_NodeCache), which locks this,
557 // THEN itself (the GUI component) for proper locking sequence, since the
558 // highest contention is for this cache object.
559 synchronized void removeObserver(TT_NodeCacheObserver obs) {
560 observers = (TT_NodeCacheObserver[]) DynamicArray.remove(observers, obs);
561 }
562
563 // ------------- PRIVATE -----------------
564 private void process() {
774 private synchronized void notifyStats() {
775 if (observers.length == 0) {
776 return;
777 }
778
779 for (int i = 0; i < observers.length; i++) {
780 boolean[] mask = observers[i].getEventMasks();
781 if (mask[0] || mask[TT_NodeCacheObserver.MSGS_STATS]) {
782 observers[i].statsUpdated(stats);
783 }
784 } // for
785 }
786
787
788 private final TestResultTable.TreeNode node;
789 private final Logger log;
790 private TestResultTable.TreeIterator it;
791 private TestFilter filter;
792 private int[] stats = new int[Status.NUM_STATES];
793 private int localRejectCount;
794 private Hashtable rejectReasons = new Hashtable();
795 private final FilterObserver fObs = new FilterObserver();
796 private TT_NodeCacheObserver[] observers = new TT_NodeCacheObserver[0];
797 private Vector[] testLists; // could use unsynchronized data structure
798 private volatile int state;
799 private volatile boolean valid = true;
800 private static final int NOT_COMPUTED = 0;
801 private static final int COMPUTING = 1;
802 private static final int COMPLETED = 2;
803 private static final int PAUSED = 3;
804 private static final int ABORTED = 4;
805 private static final boolean debug = Debug.getBoolean(TT_NodeCache.class);
806
807 static abstract class TT_NodeCacheObserver {
808
809 public TT_NodeCacheObserver() {
810 interestList = new boolean[EVENT_LIST_SIZE];
811 }
812
813 /**
814 * Find out what messages this observer is interested in.
815 */
816 public boolean[] getEventMasks() {
817 return interestList;
|
48 * <p>
49 * Objects of this type run to completion and are then immutable.
50 */
51 class TT_NodeCache implements Runnable {
52
53 /**
54 * Construct a cache object which will collect info about the given node
55 * with respect to the supplied filter.
56 *
57 * @param n Node to examine, should not be null.
58 * @param f Filter to use when producing information. Can be null.
59 */
60 TT_NodeCache(TestResultTable.TreeNode n, TestFilter f, Logger l) {
61 filter = f;
62 node = n;
63 log = l;
64
65 // all the states plus filtered out
66 testLists = new Vector[Status.NUM_STATES + 1];
67 for (int i = 0; i < Status.NUM_STATES + 1; i++) {
68 testLists[i] = new Vector<>();
69 }
70 }
71
72 /**
73 * Start or resume processing.
74 */
75 public void run() {
76 if (debug) {
77 Debug.println("TT_NodeCache starting");
78 Debug.println(" -> " + this);
79 Debug.println(" -> node " + node + "(" + node.getName() + ")");
80 Debug.println(" -> filter=" + filter);
81 Debug.println(" -> old state=" + state);
82 }
83
84 // needed for a new run, a paused object will already have one
85 if (it == null) {
86 it = init();
87 }
88
501 * @see #isActive()
502 * @see com.sun.javatest.Status#NUM_STATES
503 */
504 int[] getStats() {
505 return stats;
506 }
507
508 /**
509 * Find out how many tests were rejected by filters.
510 * @return Number of rejected tests found in and below this node.
511 */
512 int getRejectCount() {
513 if (it != null) {
514 return it.getRejectCount() + localRejectCount;
515 } else {
516 return localRejectCount;
517 }
518 }
519
520 TestFilter getRejectReason(TestResult tr) {
521 return rejectReasons.get(tr);
522 }
523
524 /**
525 * Snapshot the current data and add an observer.
526 * This is an atomic operation so that you can get completely up to date
527 * and monitor all changes going forward.
528 *
529 * @param obs The observer to attach. Must not be null.
530 * @param needSnapshot Does the caller want a snapshot of the current test lists.
531 * True if yes, false if not.
532 * @return A copy of the Vectors that contain the current list of tests. Null if
533 * <tt>needSnapshot</tt> is false.
534 */
535 synchronized Vector<TestResult>[] addObserver(TT_NodeCacheObserver obs, boolean needSnapshot) {
536 // snapshot the current data
537 // must be done before adding the observer to ensure correct data
538 // delivery to client
539
540 Vector<TestResult>[] cp = null;
541 if (needSnapshot) {
542 cp = new Vector[testLists.length];
543 for (int i = 0; i < testLists.length; i++) {
544 cp[i] = (Vector<TestResult>) (testLists[i].clone());
545 }
546 }
547
548 if (obs != null) {
549 observers = (TT_NodeCacheObserver[]) DynamicArray.append(observers, obs);
550 }
551
552 return cp;
553 }
554
555 // advisory - many thread access this. you should lock this object before
556 // calling. See BP_TestListSubpanel.reset(TT_NodeCache), which locks this,
557 // THEN itself (the GUI component) for proper locking sequence, since the
558 // highest contention is for this cache object.
559 synchronized void removeObserver(TT_NodeCacheObserver obs) {
560 observers = (TT_NodeCacheObserver[]) DynamicArray.remove(observers, obs);
561 }
562
563 // ------------- PRIVATE -----------------
564 private void process() {
774 private synchronized void notifyStats() {
775 if (observers.length == 0) {
776 return;
777 }
778
779 for (int i = 0; i < observers.length; i++) {
780 boolean[] mask = observers[i].getEventMasks();
781 if (mask[0] || mask[TT_NodeCacheObserver.MSGS_STATS]) {
782 observers[i].statsUpdated(stats);
783 }
784 } // for
785 }
786
787
788 private final TestResultTable.TreeNode node;
789 private final Logger log;
790 private TestResultTable.TreeIterator it;
791 private TestFilter filter;
792 private int[] stats = new int[Status.NUM_STATES];
793 private int localRejectCount;
794 private Hashtable<TestResult, TestFilter> rejectReasons = new Hashtable<>();
795 private final FilterObserver fObs = new FilterObserver();
796 private TT_NodeCacheObserver[] observers = new TT_NodeCacheObserver[0];
797 private Vector<TestResult>[] testLists; // could use unsynchronized data structure
798 private volatile int state;
799 private volatile boolean valid = true;
800 private static final int NOT_COMPUTED = 0;
801 private static final int COMPUTING = 1;
802 private static final int COMPLETED = 2;
803 private static final int PAUSED = 3;
804 private static final int ABORTED = 4;
805 private static final boolean debug = Debug.getBoolean(TT_NodeCache.class);
806
807 static abstract class TT_NodeCacheObserver {
808
809 public TT_NodeCacheObserver() {
810 interestList = new boolean[EVENT_LIST_SIZE];
811 }
812
813 /**
814 * Find out what messages this observer is interested in.
815 */
816 public boolean[] getEventMasks() {
817 return interestList;
|