Skip to content

Commit 0a86a46

Browse files
committed
Reimplement Buffer.snapshot to use bulk append
1 parent 2908ead commit 0a86a46

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
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 & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,12 +254,11 @@ public object UnsafeBufferOperations {
254254
public inline fun writeToTail(
255255
buffer: Buffer,
256256
minimumCapacity: Int,
257-
writeAction: (SegmentWriteContext, Segment) -> Int
257+
writeAction: (context: SegmentWriteContext, tail: Segment) -> Int
258258
): Int {
259259
contract {
260260
callsInPlace(writeAction, EXACTLY_ONCE)
261261
}
262-
263262
val tail = buffer.writableSegment(minimumCapacity)
264263
val bytesWritten = writeAction(SegmentWriteContextImpl, tail)
265264

@@ -304,7 +303,10 @@ public object UnsafeBufferOperations {
304303
* @sample kotlinx.io.samples.unsafe.UnsafeReadWriteSamplesJvm.messageDigest
305304
* @sample kotlinx.io.samples.unsafe.UnsafeBufferOperationsSamples.crc32Unsafe
306305
*/
307-
public inline fun iterate(buffer: Buffer, iterationAction: (BufferIterationContext, Segment?) -> Unit) {
306+
public inline fun iterate(
307+
buffer: Buffer,
308+
iterationAction: (context: BufferIterationContext, head: Segment?) -> Unit
309+
) {
308310
contract {
309311
callsInPlace(iterationAction, EXACTLY_ONCE)
310312
}
@@ -335,7 +337,7 @@ public object UnsafeBufferOperations {
335337
*/
336338
public inline fun iterate(
337339
buffer: Buffer, offset: Long,
338-
iterationAction: (BufferIterationContext, Segment?, Long) -> Unit
340+
iterationAction: (context: BufferIterationContext, segment: Segment?, startOfTheSegmentOffset: Long) -> Unit
339341
) {
340342
contract {
341343
callsInPlace(iterationAction, EXACTLY_ONCE)
@@ -393,7 +395,10 @@ public interface SegmentReadContext {
393395
@UnsafeIoApi
394396
@JvmSynthetic
395397
@OptIn(ExperimentalContracts::class)
396-
public inline fun SegmentReadContext.withData(segment: Segment, readAction: (ByteArray, Int, Int) -> Unit) {
398+
public inline fun SegmentReadContext.withData(
399+
segment: Segment,
400+
readAction: (bytes: ByteArray, startIndexInclusive: Int, endIndexExclusive: Int) -> Unit
401+
) {
397402
contract {
398403
callsInPlace(readAction, EXACTLY_ONCE)
399404
}

0 commit comments

Comments
 (0)