Merge "Unit test base"
[dmaap/datarouter.git] / datarouter-node / src / main / java / org / onap / dmaap / datarouter / node / TaskList.java
1 /*******************************************************************************
2  * ============LICENSE_START==================================================
3  * * org.onap.dmaap
4  * * ===========================================================================
5  * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * * ===========================================================================
7  * * Licensed under the Apache License, Version 2.0 (the "License");
8  * * you may not use this file except in compliance with the License.
9  * * You may obtain a copy of the License at
10  * *
11  *  *      http://www.apache.org/licenses/LICENSE-2.0
12  * *
13  *  * Unless required by applicable law or agreed to in writing, software
14  * * distributed under the License is distributed on an "AS IS" BASIS,
15  * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * * See the License for the specific language governing permissions and
17  * * limitations under the License.
18  * * ============LICENSE_END====================================================
19  * *
20  * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  * *
22  ******************************************************************************/
23
24
25 package org.onap.dmaap.datarouter.node;
26
27 import java.util.*;
28
29 /**
30  * Manage a list of tasks to be executed when an event occurs.
31  * This makes the following guarantees:
32  * <ul>
33  * <li>Tasks can be safely added and removed in the middle of a run.</li>
34  * <li>No task will be returned more than once during a run.</li>
35  * <li>No task will be returned when it is not, at that moment, in the list of tasks.</li>
36  * <li>At the moment when next() returns null, all tasks on the list have been returned during the run.</li>
37  * <li>Initially and once next() returns null during a run, next() will continue to return null until startRun() is called.
38  * </ul>
39  */
40 public class TaskList {
41     private Iterator<Runnable> runlist;
42     private HashSet<Runnable> tasks = new HashSet<Runnable>();
43     private HashSet<Runnable> togo;
44     private HashSet<Runnable> sofar;
45     private HashSet<Runnable> added;
46     private HashSet<Runnable> removed;
47
48     /**
49      * Construct a new TaskList
50      */
51     public TaskList() {
52     }
53
54     /**
55      * Start executing the sequence of tasks.
56      */
57     public synchronized void startRun() {
58         sofar = new HashSet<Runnable>();
59         added = new HashSet<Runnable>();
60         removed = new HashSet<Runnable>();
61         togo = new HashSet<Runnable>(tasks);
62         runlist = togo.iterator();
63     }
64
65     /**
66      * Get the next task to execute
67      */
68     public synchronized Runnable next() {
69         while (runlist != null) {
70             if (runlist.hasNext()) {
71                 Runnable task = runlist.next();
72                 if (removed.contains(task)) {
73                     continue;
74                 }
75                 if (sofar.contains(task)) {
76                     continue;
77                 }
78                 sofar.add(task);
79                 return (task);
80             }
81             if (added.size() != 0) {
82                 togo = added;
83                 added = new HashSet<Runnable>();
84                 removed.clear();
85                 runlist = togo.iterator();
86                 continue;
87             }
88             togo = null;
89             added = null;
90             removed = null;
91             sofar = null;
92             runlist = null;
93         }
94         return (null);
95     }
96
97     /**
98      * Add a task to the list of tasks to run whenever the event occurs.
99      */
100     public synchronized void addTask(Runnable task) {
101         if (runlist != null) {
102             added.add(task);
103             removed.remove(task);
104         }
105         tasks.add(task);
106     }
107
108     /**
109      * Remove a task from the list of tasks to run whenever the event occurs.
110      */
111     public synchronized void removeTask(Runnable task) {
112         if (runlist != null) {
113             removed.add(task);
114             added.remove(task);
115         }
116         tasks.remove(task);
117     }
118 }