1 /*
2 * Copyright (C) 2011, Google Inc. and others
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Distribution License v. 1.0 which is available at
6 * https://www.eclipse.org/org/documents/edl-v10.php.
7 *
8 * SPDX-License-Identifier: BSD-3-Clause
9 */
10
11 package org.eclipse.jgit.internal.storage.dfs;
12
13 import java.io.IOException;
14 import java.nio.channels.ReadableByteChannel;
15
16 /**
17 * Readable random access byte channel from a file.
18 */
19 public interface ReadableChannel extends ReadableByteChannel {
20 /**
21 * Get the current position of the channel.
22 *
23 * @return r current offset.
24 * @throws java.io.IOException
25 * the channel's current position cannot be obtained.
26 */
27 long position() throws IOException;
28
29 /**
30 * Seek the current position of the channel to a new offset.
31 *
32 * @param newPosition
33 * position to move the channel to. The next read will start from
34 * here. This should be a multiple of the {@link #blockSize()}.
35 * @throws java.io.IOException
36 * the position cannot be updated. This may be because the
37 * channel only supports block aligned IO and the current
38 * position is not block aligned.
39 */
40 void position(long newPosition) throws IOException;
41
42 /**
43 * Get the total size of the channel.
44 * <p>
45 * Prior to reading from a channel the size might not yet be known.
46 * Implementors may return -1 until after the first read method call. Once a
47 * read has been completed, the underlying file size should be available.
48 *
49 * @return r total size of the channel; -1 if not yet available.
50 * @throws java.io.IOException
51 * the size cannot be determined.
52 */
53 long size() throws IOException;
54
55 /**
56 * Get the recommended alignment for reads.
57 * <p>
58 * Starting a read at multiples of the blockSize is more efficient than
59 * starting a read at any other position. If 0 or -1 the channel does not
60 * have any specific block size recommendation.
61 * <p>
62 * Channels should not recommend large block sizes. Sizes up to 1-4 MiB may
63 * be reasonable, but sizes above that may be horribly inefficient. The
64 * {@link org.eclipse.jgit.internal.storage.dfs.DfsBlockCache} favors the
65 * alignment suggested by the channel rather than the configured size under
66 * the assumption that reads are very expensive and the channel knows what
67 * size is best to access it with.
68 *
69 * @return recommended alignment size for randomly positioned reads. Does
70 * not need to be a power of 2.
71 */
72 int blockSize();
73
74 /**
75 * Recommend the channel maintain a read-ahead buffer.
76 * <p>
77 * A read-ahead buffer of approximately {@code bufferSize} in bytes may be
78 * allocated and used by the channel to smooth out latency for read.
79 * <p>
80 * Callers can continue to read in smaller than {@code bufferSize} chunks.
81 * With read-ahead buffering enabled read latency may fluctuate in a pattern
82 * of one slower read followed by {@code (bufferSize / readSize) - 1} fast
83 * reads satisfied by the read-ahead buffer. When summed up overall time to
84 * read the same contiguous range should be lower than if read-ahead was not
85 * enabled, as the implementation can combine reads to increase throughput.
86 * <p>
87 * To avoid unnecessary IO callers should only enable read-ahead if the
88 * majority of the channel will be accessed in order.
89 * <p>
90 * Implementations may chose to read-ahead using asynchronous APIs or
91 * background threads, or may simply aggregate reads using a buffer.
92 * <p>
93 * This read ahead stays in effect until the channel is closed or the buffer
94 * size is set to 0.
95 *
96 * @param bufferSize
97 * requested size of the read ahead buffer, in bytes.
98 * @throws java.io.IOException
99 * if the read ahead cannot be adjusted.
100 */
101 void setReadAheadBytes(int bufferSize) throws IOException;
102 }