001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.apache.hadoop.yarn.api.records;
020
021 import java.io.Serializable;
022
023 import org.apache.hadoop.classification.InterfaceAudience.Public;
024 import org.apache.hadoop.classification.InterfaceStability.Stable;
025 import org.apache.hadoop.yarn.api.ApplicationMasterProtocol;
026 import org.apache.hadoop.yarn.util.Records;
027
028 /**
029 * <p><code>ResourceRequest</code> represents the request made by an
030 * application to the <code>ResourceManager</code> to obtain various
031 * <code>Container</code> allocations.</p>
032 *
033 * <p>It includes:
034 * <ul>
035 * <li>{@link Priority} of the request.</li>
036 * <li>
037 * The <em>name</em> of the machine or rack on which the allocation is
038 * desired. A special value of <em>*</em> signifies that
039 * <em>any</em> host/rack is acceptable to the application.
040 * </li>
041 * <li>{@link Resource} required for each request.</li>
042 * <li>
043 * Number of containers, of above specifications, which are required
044 * by the application.
045 * </li>
046 * <li>
047 * A boolean <em>relaxLocality</em> flag, defaulting to <code>true</code>,
048 * which tells the <code>ResourceManager</code> if the application wants
049 * locality to be loose (i.e. allows fall-through to rack or <em>any</em>)
050 * or strict (i.e. specify hard constraint on resource allocation).
051 * </li>
052 * </ul>
053 * </p>
054 *
055 * @see Resource
056 * @see ApplicationMasterProtocol#allocate(org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest)
057 */
058 @Public
059 @Stable
060 public abstract class ResourceRequest implements Comparable<ResourceRequest> {
061
062 @Public
063 @Stable
064 public static ResourceRequest newInstance(Priority priority, String hostName,
065 Resource capability, int numContainers) {
066 return newInstance(priority, hostName, capability, numContainers, true);
067 }
068
069 @Public
070 @Stable
071 public static ResourceRequest newInstance(Priority priority, String hostName,
072 Resource capability, int numContainers, boolean relaxLocality) {
073 ResourceRequest request = Records.newRecord(ResourceRequest.class);
074 request.setPriority(priority);
075 request.setResourceName(hostName);
076 request.setCapability(capability);
077 request.setNumContainers(numContainers);
078 request.setRelaxLocality(relaxLocality);
079 return request;
080 }
081
082 @Public
083 @Stable
084 public static class ResourceRequestComparator implements
085 java.util.Comparator<ResourceRequest>, Serializable {
086
087 private static final long serialVersionUID = 1L;
088
089 @Override
090 public int compare(ResourceRequest r1, ResourceRequest r2) {
091
092 // Compare priority, host and capability
093 int ret = r1.getPriority().compareTo(r2.getPriority());
094 if (ret == 0) {
095 String h1 = r1.getResourceName();
096 String h2 = r2.getResourceName();
097 ret = h1.compareTo(h2);
098 }
099 if (ret == 0) {
100 ret = r1.getCapability().compareTo(r2.getCapability());
101 }
102 return ret;
103 }
104 }
105
106 /**
107 * The constant string representing no locality.
108 * It should be used by all references that want to pass an arbitrary host
109 * name in.
110 */
111 public static final String ANY = "*";
112
113 /**
114 * Check whether the given <em>host/rack</em> string represents an arbitrary
115 * host name.
116 *
117 * @param hostName <em>host/rack</em> on which the allocation is desired
118 * @return whether the given <em>host/rack</em> string represents an arbitrary
119 * host name
120 */
121 @Public
122 @Stable
123 public static boolean isAnyLocation(String hostName) {
124 return ANY.equals(hostName);
125 }
126
127 /**
128 * Get the <code>Priority</code> of the request.
129 * @return <code>Priority</code> of the request
130 */
131 @Public
132 @Stable
133 public abstract Priority getPriority();
134
135 /**
136 * Set the <code>Priority</code> of the request
137 * @param priority <code>Priority</code> of the request
138 */
139 @Public
140 @Stable
141 public abstract void setPriority(Priority priority);
142
143 /**
144 * Get the resource (e.g. <em>host/rack</em>) on which the allocation
145 * is desired.
146 *
147 * A special value of <em>*</em> signifies that <em>any</em> resource
148 * (host/rack) is acceptable.
149 *
150 * @return resource (e.g. <em>host/rack</em>) on which the allocation
151 * is desired
152 */
153 @Public
154 @Stable
155 public abstract String getResourceName();
156
157 /**
158 * Set the resource name (e.g. <em>host/rack</em>) on which the allocation
159 * is desired.
160 *
161 * A special value of <em>*</em> signifies that <em>any</em> resource name
162 * (e.g. host/rack) is acceptable.
163 *
164 * @param resourceName (e.g. <em>host/rack</em>) on which the
165 * allocation is desired
166 */
167 @Public
168 @Stable
169 public abstract void setResourceName(String resourceName);
170
171 /**
172 * Get the <code>Resource</code> capability of the request.
173 * @return <code>Resource</code> capability of the request
174 */
175 @Public
176 @Stable
177 public abstract Resource getCapability();
178
179 /**
180 * Set the <code>Resource</code> capability of the request
181 * @param capability <code>Resource</code> capability of the request
182 */
183 @Public
184 @Stable
185 public abstract void setCapability(Resource capability);
186
187 /**
188 * Get the number of containers required with the given specifications.
189 * @return number of containers required with the given specifications
190 */
191 @Public
192 @Stable
193 public abstract int getNumContainers();
194
195 /**
196 * Set the number of containers required with the given specifications
197 * @param numContainers number of containers required with the given
198 * specifications
199 */
200 @Public
201 @Stable
202 public abstract void setNumContainers(int numContainers);
203
204 /**
205 * Get whether locality relaxation is enabled with this
206 * <code>ResourceRequest</code>. Defaults to true.
207 *
208 * @return whether locality relaxation is enabled with this
209 * <code>ResourceRequest</code>.
210 */
211 @Public
212 @Stable
213 public abstract boolean getRelaxLocality();
214
215 /**
216 * <p>For a request at a network hierarchy level, set whether locality can be relaxed
217 * to that level and beyond.<p>
218 *
219 * <p>If the flag is off on a rack-level <code>ResourceRequest</code>,
220 * containers at that request's priority will not be assigned to nodes on that
221 * request's rack unless requests specifically for those nodes have also been
222 * submitted.<p>
223 *
224 * <p>If the flag is off on an {@link ResourceRequest#ANY}-level
225 * <code>ResourceRequest</code>, containers at that request's priority will
226 * only be assigned on racks for which specific requests have also been
227 * submitted.<p>
228 *
229 * <p>For example, to request a container strictly on a specific node, the
230 * corresponding rack-level and any-level requests should have locality
231 * relaxation set to false. Similarly, to request a container strictly on a
232 * specific rack, the corresponding any-level request should have locality
233 * relaxation set to false.<p>
234 *
235 * @param relaxLocality whether locality relaxation is enabled with this
236 * <code>ResourceRequest</code>.
237 */
238 @Public
239 @Stable
240 public abstract void setRelaxLocality(boolean relaxLocality);
241
242 @Override
243 public int hashCode() {
244 final int prime = 2153;
245 int result = 2459;
246 Resource capability = getCapability();
247 String hostName = getResourceName();
248 Priority priority = getPriority();
249 result =
250 prime * result + ((capability == null) ? 0 : capability.hashCode());
251 result = prime * result + ((hostName == null) ? 0 : hostName.hashCode());
252 result = prime * result + getNumContainers();
253 result = prime * result + ((priority == null) ? 0 : priority.hashCode());
254 return result;
255 }
256
257 @Override
258 public boolean equals(Object obj) {
259 if (this == obj)
260 return true;
261 if (obj == null)
262 return false;
263 if (getClass() != obj.getClass())
264 return false;
265 ResourceRequest other = (ResourceRequest) obj;
266 Resource capability = getCapability();
267 if (capability == null) {
268 if (other.getCapability() != null)
269 return false;
270 } else if (!capability.equals(other.getCapability()))
271 return false;
272 String hostName = getResourceName();
273 if (hostName == null) {
274 if (other.getResourceName() != null)
275 return false;
276 } else if (!hostName.equals(other.getResourceName()))
277 return false;
278 if (getNumContainers() != other.getNumContainers())
279 return false;
280 Priority priority = getPriority();
281 if (priority == null) {
282 if (other.getPriority() != null)
283 return false;
284 } else if (!priority.equals(other.getPriority()))
285 return false;
286 return true;
287 }
288
289 @Override
290 public int compareTo(ResourceRequest other) {
291 int priorityComparison = this.getPriority().compareTo(other.getPriority());
292 if (priorityComparison == 0) {
293 int hostNameComparison =
294 this.getResourceName().compareTo(other.getResourceName());
295 if (hostNameComparison == 0) {
296 int capabilityComparison =
297 this.getCapability().compareTo(other.getCapability());
298 if (capabilityComparison == 0) {
299 return this.getNumContainers() - other.getNumContainers();
300 } else {
301 return capabilityComparison;
302 }
303 } else {
304 return hostNameComparison;
305 }
306 } else {
307 return priorityComparison;
308 }
309 }
310 }