|
18 | 18 |
|
19 | 19 | package org.apache.hadoop.io.wrappedio; |
20 | 20 |
|
| 21 | +import java.io.EOFException; |
21 | 22 | import java.io.IOException; |
22 | 23 | import java.io.Serializable; |
23 | 24 | import java.io.UncheckedIOException; |
| 25 | +import java.nio.ByteBuffer; |
24 | 26 | import java.util.HashMap; |
25 | 27 | import java.util.Map; |
26 | 28 | import javax.annotation.Nullable; |
27 | 29 |
|
28 | 30 | import org.apache.hadoop.classification.InterfaceAudience; |
29 | 31 | import org.apache.hadoop.classification.InterfaceStability; |
| 32 | +import org.apache.hadoop.fs.ByteBufferPositionedReadable; |
30 | 33 | import org.apache.hadoop.fs.FSDataInputStream; |
31 | 34 | import org.apache.hadoop.fs.FileStatus; |
32 | 35 | import org.apache.hadoop.fs.FileSystem; |
33 | 36 | import org.apache.hadoop.fs.FutureDataInputStreamBuilder; |
34 | 37 | import org.apache.hadoop.fs.Path; |
| 38 | +import org.apache.hadoop.fs.StreamCapabilities; |
35 | 39 | import org.apache.hadoop.fs.statistics.IOStatistics; |
36 | 40 | import org.apache.hadoop.fs.statistics.IOStatisticsContext; |
37 | 41 | import org.apache.hadoop.fs.statistics.IOStatisticsLogging; |
@@ -60,6 +64,28 @@ public final class WrappedOperations { |
60 | 64 | private WrappedOperations() { |
61 | 65 | } |
62 | 66 |
|
| 67 | + public static boolean hasPathCapability(FileSystem fs, Path path, String capability) { |
| 68 | + try { |
| 69 | + return fs.hasPathCapability(path, capability); |
| 70 | + } catch (IOException e) { |
| 71 | + return false; |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * Does an object implement {@link StreamCapabilities} and, if so, |
| 77 | + * what is the result of the probe for the capability. |
| 78 | + * @param o object to probe |
| 79 | + * @param capability capability string |
| 80 | + * @return true iff the capability is declared available. |
| 81 | + */ |
| 82 | + public static boolean hasStreamCapability(Object o, String capability) { |
| 83 | + if (o instanceof StreamCapabilities) { |
| 84 | + return false; |
| 85 | + } |
| 86 | + return ((StreamCapabilities) o).hasCapability(capability); |
| 87 | + } |
| 88 | + |
63 | 89 | /** |
64 | 90 | * OpenFile assistant, easy reflection-based access to |
65 | 91 | * {@link FileSystem#openFile(Path)}. |
@@ -251,31 +277,76 @@ public static Map<String, Long> iostatisticsSnapshotToMap(@Nullable Object sourc |
251 | 277 | * This is either a thread-local value or a global empty context. |
252 | 278 | * @return instance of {@link IOStatisticsContext} |
253 | 279 | */ |
254 | | - public Object iostatisticsContextGetCurrent() { |
| 280 | + public static Object iostatisticsContextGetCurrent() { |
255 | 281 | return getCurrentIOStatisticsContext(); |
256 | 282 | } |
257 | 283 |
|
258 | 284 | /** |
259 | 285 | * Static probe to check if the thread-level IO statistics enabled. |
260 | 286 | * @return true if the thread-level IO statistics are enabled. |
261 | 287 | */ |
262 | | - public boolean iostatisticsContextEnabled() { |
| 288 | + public static boolean iostatisticsContextEnabled() { |
263 | 289 | return IOStatisticsContext.enabled(); |
264 | 290 | } |
265 | 291 |
|
266 | 292 | /** |
267 | 293 | * Reset the context's IOStatistics. |
268 | 294 | */ |
269 | | - public void iostatisticsContextReset() { |
| 295 | + public static void iostatisticsContextReset() { |
270 | 296 | getCurrentIOStatisticsContext().reset(); |
271 | 297 | } |
272 | 298 |
|
273 | 299 | /** |
274 | 300 | * Take a snapshot of the context IOStatistics. |
275 | 301 | * @return an instance of {@link IOStatisticsSnapshot}. |
276 | 302 | */ |
277 | | - public Serializable iostatisticsContextSnapshot() { |
| 303 | + public static Serializable iostatisticsContextSnapshot() { |
278 | 304 | return getCurrentIOStatisticsContext().snapshot(); |
279 | 305 | } |
280 | 306 |
|
| 307 | + /** |
| 308 | + * Delegate to {@link ByteBufferPositionedReadable#read(long, ByteBuffer)}. |
| 309 | + * @param in input stream |
| 310 | + * @param position position within file |
| 311 | + * @param buf the ByteBuffer to receive the results of the read operation. |
| 312 | + * @throws IOException if there is some error performing the read |
| 313 | + * @throws EOFException the end of the data was reached before |
| 314 | + * the read operation completed |
| 315 | + * @throws UnsupportedOperationException if the input doesn't implement |
| 316 | + * the interface or, if when invoked, it is raised. |
| 317 | + * Note: that is the default behaviour of {@link FSDataInputStream#readFully(long, ByteBuffer)}. |
| 318 | + */ |
| 319 | + public static void byteBufferPositionedReadableReadFully( |
| 320 | + Object in, |
| 321 | + long position, |
| 322 | + ByteBuffer buf) |
| 323 | + throws IOException { |
| 324 | + if (!(in instanceof ByteBufferPositionedReadable)) { |
| 325 | + throw new UnsupportedOperationException("Not a ByteBufferPositionedReadable: " + in); |
| 326 | + } |
| 327 | + |
| 328 | + ((ByteBufferPositionedReadable) in).readFully(position, buf); |
| 329 | + } |
| 330 | + |
| 331 | + /** |
| 332 | + * Probe to see if the input stream is an instance of ByteBufferPositionedReadable. |
| 333 | + * If the stream is an FSDataInputStream, the wrapped stream is checked. |
| 334 | + * @param in input stream |
| 335 | + * @return true if the stream implements the interface (including a wrapped stream) |
| 336 | + * and that it declares the stream capability. |
| 337 | + */ |
| 338 | + public static boolean byteBufferPositionedReadableReadFullyAvailable( |
| 339 | + Object in) { |
| 340 | + if (!(in instanceof ByteBufferPositionedReadable)) { |
| 341 | + return false; |
| 342 | + } |
| 343 | + if (in instanceof FSDataInputStream) { |
| 344 | + // ask the wrapped stream. |
| 345 | + return byteBufferPositionedReadableReadFullyAvailable( |
| 346 | + ((FSDataInputStream) in).getWrappedStream()); |
| 347 | + } |
| 348 | + // now rely on the input stream implementing path capabilities, which |
| 349 | + // all the Hadoop FS implementations do. |
| 350 | + return hasStreamCapability(in, StreamCapabilities.PREADBYTEBUFFER); |
| 351 | + } |
281 | 352 | } |
0 commit comments