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