Skip to content

Commit 23aaaab

Browse files
committed
Reimplement Buffer.snapshot to use bulk append
1 parent 7da32e9 commit 23aaaab

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

core/common/src/Buffers.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,28 @@ package kotlinx.io
77

88
import kotlinx.io.bytestring.ByteString
99
import kotlinx.io.bytestring.buildByteString
10+
import kotlinx.io.unsafe.UnsafeBufferOperations
11+
import kotlinx.io.unsafe.withData
1012

1113
/**
1214
* Creates a byte string containing a copy of all the data from this buffer.
1315
*
1416
* This call doesn't consume data from the buffer, but instead copies it.
1517
*/
18+
@OptIn(UnsafeIoApi::class)
1619
public fun Buffer.snapshot(): ByteString {
1720
if (size == 0L) return ByteString()
1821

1922
check(size <= Int.MAX_VALUE) { "Buffer is too long ($size) to be converted into a byte string." }
2023

2124
return buildByteString(size.toInt()) {
22-
var curr = head
23-
do {
24-
check(curr != null) { "Current segment is null" }
25-
for (idx in 0 until curr.size) {
26-
append(curr.getUnchecked(idx))
25+
UnsafeBufferOperations.iterate(this@snapshot) { ctx, head ->
26+
var curr = head
27+
while (curr != null) {
28+
ctx.withData(curr, this::append)
29+
curr = ctx.next(curr)
2730
}
28-
curr = curr.next
29-
} while (curr != null)
31+
}
3032
}
3133
}
3234

core/common/src/unsafe/UnsafeBufferOperations.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public object UnsafeBufferOperations {
220220
public inline fun writeToTail(
221221
buffer: Buffer,
222222
minimumCapacity: Int,
223-
writeAction: (SegmentWriteContext, Segment) -> Int
223+
writeAction: (context: SegmentWriteContext, tail: Segment) -> Int
224224
) {
225225
val tail = buffer.writableSegment(minimumCapacity)
226226
val bytesWritten = writeAction(SegmentWriteContextImpl, tail)
@@ -265,7 +265,10 @@ public object UnsafeBufferOperations {
265265
* @sample kotlinx.io.samples.unsafe.UnsafeReadWriteSamplesJvm.messageDigest
266266
* @sample kotlinx.io.samples.unsafe.UnsafeBufferOperationsSamples.crc32Unsafe
267267
*/
268-
public inline fun iterate(buffer: Buffer, iterationAction: (BufferIterationContext, Segment?) -> Unit) {
268+
public inline fun iterate(
269+
buffer: Buffer,
270+
iterationAction: (context: BufferIterationContext, head: Segment?) -> Unit
271+
) {
269272
iterationAction(BufferIterationContextImpl, buffer.head)
270273
}
271274

@@ -293,7 +296,7 @@ public object UnsafeBufferOperations {
293296
*/
294297
public inline fun iterate(
295298
buffer: Buffer, offset: Long,
296-
iterationAction: (BufferIterationContext, Segment?, Long) -> Unit
299+
iterationAction: (context: BufferIterationContext, segment: Segment?, startOfTheSegmentOffset: Long) -> Unit
297300
) {
298301
require(offset >= 0) { "Offset must be non-negative: $offset" }
299302
if (offset >= buffer.size) {
@@ -346,7 +349,10 @@ public interface SegmentReadContext {
346349
*/
347350
@UnsafeIoApi
348351
@JvmSynthetic
349-
public inline fun SegmentReadContext.withData(segment: Segment, readAction: (ByteArray, Int, Int) -> Unit) {
352+
public inline fun SegmentReadContext.withData(
353+
segment: Segment,
354+
readAction: (bytes: ByteArray, startIndexInclusive: Int, endIndexExclusive: Int) -> Unit
355+
) {
350356
readAction(segment.dataAsByteArray(true), segment.pos, segment.limit)
351357
}
352358

0 commit comments

Comments
 (0)