Remove checkstyle syntax warnings from dr-node
[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.HashSet;
28 import java.util.Iterator;
29
30 /**
31  * Manage a list of tasks to be executed when an event occurs. 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
38  * called.
39  * </ul>
40  */
41 public class TaskList {
42
43     private Iterator<Runnable> runlist;
44     private HashSet<Runnable> tasks = new HashSet<>();
45     private HashSet<Runnable> togo;
46     private HashSet<Runnable> sofar;
47     private HashSet<Runnable> added;
48     private HashSet<Runnable> removed;
49
50     /**
51      * Start executing the sequence of tasks.
52      */
53     public synchronized void startRun() {
54         sofar = new HashSet<>();
55         added = new HashSet<>();
56         removed = new HashSet<>();
57         togo = new HashSet<>(tasks);
58         runlist = togo.iterator();
59     }
60
61     /**
62      * Get the next task to execute.
63      */
64     public synchronized Runnable next() {
65         while (runlist != null) {
66             if (runlist.hasNext()) {
67                 Runnable task = runlist.next();
68                 if (addTaskToSoFar(task)) {
69                     return task;
70                 }
71             }
72             if (!added.isEmpty()) {
73                 togo = added;
74                 added = new HashSet<>();
75                 removed.clear();
76                 runlist = togo.iterator();
77                 continue;
78             }
79             togo = null;
80             added = null;
81             removed = null;
82             sofar = null;
83             runlist = null;
84         }
85         return (null);
86     }
87
88     /**
89      * Add a task to the list of tasks to run whenever the event occurs.
90      */
91     public synchronized void addTask(Runnable task) {
92         if (runlist != null) {
93             added.add(task);
94             removed.remove(task);
95         }
96         tasks.add(task);
97     }
98
99     /**
100      * Remove a task from the list of tasks to run whenever the event occurs.
101      */
102     public synchronized void removeTask(Runnable task) {
103         if (runlist != null) {
104             removed.add(task);
105             added.remove(task);
106         }
107         tasks.remove(task);
108     }
109
110     private boolean addTaskToSoFar(Runnable task) {
111         if (removed.contains(task)) {
112             return false;
113         }
114         if (sofar.contains(task)) {
115             return false;
116         }
117         sofar.add(task);
118         return true;
119     }
120 }