View Javadoc

1   /*
2    * @(#)Resource.java Feb 1, 2003
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
9    */
10  package nl.tudelft.simulation.dsol.formalisms;
11  
12  import java.rmi.RemoteException;
13  import java.util.ArrayList;
14  import java.util.Collections;
15  import java.util.Iterator;
16  import java.util.List;
17  
18  import nl.tudelft.simulation.dsol.SimRuntimeException;
19  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
20  import nl.tudelft.simulation.event.EventProducer;
21  import nl.tudelft.simulation.event.EventType;
22  
23  /***
24   * A resource defines a shared and limited amount.
25   * <p>
26   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
27   * University of Technology </a>, the Netherlands. <br>
28   * See for project information <a href="http://www.simulation.tudelft.nl">
29   * www.simulation.tudelft.nl </a> <br>
30   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
31   * License (GPL) </a>, no warranty <br>
32   * 
33   * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
34   *         Jacobs </a>
35   * @version 1.2 2004-03-26
36   * @since 1.0
37   */
38  public class Resource extends EventProducer
39  {
40  	/*** UTILIZATION_EVENT is fired on activity */
41  	public static final EventType UTILIZATION_EVENT = new EventType(
42  			"UTILIZATION_EVENT");
43  
44  	/*** RESOURCE_REQUESTED_QUEUE_LENGTH fired on changes in queue length */
45  	public static final EventType RESOURCE_REQUESTED_QUEUE_LENGTH = new EventType(
46  			"RESOURCE_REQUESTED_QUEUE_LENGTH");
47  
48  	/***
49  	 * capacity defines the maximuum capacity of the resource
50  	 * 
51  	 * @uml.property name="capacity"
52  	 */
53  	protected double capacity;
54  
55  
56  	/*** claimedCapacity defines the currently claimed capacity */
57  	protected double claimedCapacity = 0.0;
58  
59  	/*** request defines the list of requestors for this resource */
60  	private List requests = Collections.synchronizedList(new ArrayList());
61  
62  	/*** simulator defines the simulator on which is scheduled */
63  	protected DEVSSimulatorInterface simulator;
64  
65  	/*** the description of the resource */
66  	protected String description = "resource";
67  
68  	/***
69  	 * Method Resource.
70  	 * 
71  	 * @param simulator on which is scheduled
72  	 * @param description the description of this resource
73  	 * @param capacity of the resource
74  	 */
75  	public Resource(final DEVSSimulatorInterface simulator,
76  			final String description, final double capacity)
77  	{
78  		super();
79  		this.description = description;
80  		this.simulator = simulator;
81  		this.capacity = capacity;
82  	}
83  
84  	/***
85  	 * Method Resource.
86  	 * 
87  	 * @param simulator on which is scheduled
88  	 * @param capacity of the resource
89  	 */
90  	public Resource(final DEVSSimulatorInterface simulator,
91  			final double capacity)
92  	{
93  		this(simulator, "resource", capacity);
94  	}
95  
96  	/***
97  	 * returns the capacity of the resource
98  	 * 
99  	 * @return capacity
100 	 * 
101 	 * @uml.property name="capacity"
102 	 */
103 	public double getCapacity()
104 	{
105 		return this.capacity;
106 	}
107 
108 
109 	/***
110 	 * Method alterClaimedCapacity.
111 	 * 
112 	 * @param amount refers the amount which is added to the claimed capacity
113 	 * @throws RemoteException on network failure
114 	 */
115 	private synchronized void alterClaimedCapacity(final double amount)
116 			throws RemoteException
117 	{
118 		this.claimedCapacity += amount;
119 		this.fireEvent(Resource.UTILIZATION_EVENT, this.claimedCapacity,
120 				this.simulator.getSimulatorTime());
121 	}
122 
123 	/***
124 	 * sets the capacity of the resource
125 	 * 
126 	 * @param capacity the new maximal capacity
127 	 * 
128 	 * @uml.property name="capacity"
129 	 */
130 	public void setCapacity(final double capacity)
131 	{
132 		this.capacity = capacity;
133 	}
134 
135 	/***
136 	 * requests an amount of capacity from the resource \
137 	 * 
138 	 * @param amount the requested amount
139 	 * @param requestor the RequestorInterface requesting the amount
140 	 * @throws RemoteException on network failure
141 	 * @throws SimRuntimeException on other failures
142 	 */
143 	public synchronized void requestCapacity(final double amount,
144 			final ResourceRequestorInterface requestor) throws RemoteException,
145 			SimRuntimeException
146 	{
147 		if (amount < 0.0)
148 		{
149 			throw new SimRuntimeException(
150 					"requested capacity on resource cannot <0.0");
151 		}
152 		if ((this.claimedCapacity + amount) <= this.capacity)
153 		{
154 			this.alterClaimedCapacity(amount);
155 			this.simulator.scheduleEvent(0, this, requestor,
156 					"receiveRequestedResource", new Object[]{
157 							new Double(amount), this});
158 		} else
159 		{
160 			synchronized (this.requests)
161 			{
162 				this.requests.add(new Request(requestor, amount));
163 			}
164 			this.fireEvent(Resource.RESOURCE_REQUESTED_QUEUE_LENGTH,
165 					(double) this.requests.size(), this.simulator
166 							.getSimulatorTime());
167 		}
168 	}
169 
170 	/***
171 	 * releases an amount of capacity from the resource.
172 	 * 
173 	 * @param amount the amount to release
174 	 * @throws RemoteException on network failure
175 	 */
176 	public void releaseCapacity(final double amount) throws RemoteException
177 	{
178 		if (amount < 0.0)
179 		{
180 			throw new IllegalArgumentException(
181 					"released capacity on resource cannot <0.0");
182 		}
183 		this.alterClaimedCapacity(-amount);
184 		synchronized (this.requests)
185 		{
186 			for (Iterator i = this.requests.iterator(); i.hasNext();)
187 			{
188 				Request request = (Request) i.next();
189 				if ((this.capacity - this.claimedCapacity) >= request
190 						.getAmount())
191 				{
192 					this.alterClaimedCapacity(amount);
193 					request.getRequestor().receiveRequestedResource(
194 							request.getAmount(), this);
195 					synchronized (this.requests)
196 					{
197 						this.requests.remove(request);
198 					}
199 					this.fireEvent(Resource.RESOURCE_REQUESTED_QUEUE_LENGTH,
200 							(double) this.requests.size(), this.simulator
201 									.getSimulatorTime());
202 					if ((this.capacity - this.claimedCapacity) >= 0.0)
203 					{
204 						this.releaseCapacity(0);
205 					}
206 					return;
207 				}
208 			}
209 		}
210 	}
211 
212 	/***
213 	 * @see java.lang.Object#toString()
214 	 */
215 	public String toString()
216 	{
217 		return this.description;
218 	}
219 
220 	/***
221 	 * A Request.
222 	 */
223 	public class Request
224 	{
225 		/*** requestor the resourceRequestor */
226 		private ResourceRequestorInterface requestor;
227 
228 		/*** amount is the amount requested by the resource */
229 		private double amount;
230 
231 		/***
232 		 * constructs a new Request
233 		 * 
234 		 * @param requestor the requestor
235 		 * @param amount the requested amount
236 		 */
237 		public Request(final ResourceRequestorInterface requestor,
238 				final double amount)
239 		{
240 			this.requestor = requestor;
241 			this.amount = amount;
242 		}
243 
244 		/***
245 		 * gets the requested amount.
246 		 * 
247 		 * @return the requested amount
248 		 */
249 		public double getAmount()
250 		{
251 			return this.amount;
252 		}
253 
254 		/***
255 		 * gets the requestor.
256 		 * 
257 		 * @return the Requestor.
258 		 */
259 		public ResourceRequestorInterface getRequestor()
260 		{
261 			return this.requestor;
262 		}
263 	}
264 }