|
14 | 14 | import org.elasticsearch.common.unit.ByteSizeValue; |
15 | 15 | import org.elasticsearch.core.AbstractRefCounted; |
16 | 16 | import org.elasticsearch.core.IOUtils; |
| 17 | +import org.elasticsearch.core.Streams; |
17 | 18 | import org.elasticsearch.core.SuppressForbidden; |
18 | 19 | import org.elasticsearch.env.Environment; |
19 | 20 | import org.elasticsearch.env.NodeEnvironment; |
@@ -184,6 +185,37 @@ public static void copyToCacheFileAligned( |
184 | 185 | } |
185 | 186 | } |
186 | 187 |
|
| 188 | + /** |
| 189 | + * Copy all bytes from {@code input} to {@code fc}, only doing writes aligned along {@link #PAGE_SIZE}. |
| 190 | + * |
| 191 | + * @param fc output cache file reference |
| 192 | + * @param input stream to read from |
| 193 | + * @param fileChannelPos position in {@code fc} to write to |
| 194 | + * @param progressUpdater callback to invoke with the number of copied bytes as they are copied |
| 195 | + * @param buffer bytebuffer to use for writing |
| 196 | + * @return the number of bytes copied |
| 197 | + * @throws IOException on failure |
| 198 | + */ |
| 199 | + public static int copyToCacheFileAligned(IO fc, InputStream input, int fileChannelPos, IntConsumer progressUpdater, ByteBuffer buffer) |
| 200 | + throws IOException { |
| 201 | + int bytesCopied = 0; |
| 202 | + while (true) { |
| 203 | + final int bytesRead = Streams.read(input, buffer, buffer.remaining()); |
| 204 | + if (bytesRead <= 0) { |
| 205 | + break; |
| 206 | + } |
| 207 | + if (buffer.hasRemaining()) { |
| 208 | + // ensure that last write is aligned on 4k boundaries (= page size) |
| 209 | + final int remainder = buffer.position() % PAGE_SIZE; |
| 210 | + final int adjustment = remainder == 0 ? 0 : PAGE_SIZE - remainder; |
| 211 | + buffer.position(buffer.position() + adjustment); |
| 212 | + } |
| 213 | + bytesCopied += positionalWrite(fc, fileChannelPos + bytesCopied, buffer); |
| 214 | + progressUpdater.accept(bytesCopied); |
| 215 | + } |
| 216 | + return bytesCopied; |
| 217 | + } |
| 218 | + |
187 | 219 | private static int positionalWrite(IO fc, int start, ByteBuffer byteBuffer) throws IOException { |
188 | 220 | byteBuffer.flip(); |
189 | 221 | int written = fc.write(byteBuffer, start); |
|
0 commit comments