Skip to content

Commit

Permalink
Issue-2734 - Clamp on readable bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
ali-ahsan-ali committed Jun 26, 2024
1 parent 6a1c4f0 commit 735a357
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 24 deletions.
9 changes: 5 additions & 4 deletions Sources/NIOCore/ByteBuffer-core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -832,12 +832,13 @@ public struct ByteBuffer {
return true
}

/// Reset capacity of the buffer to the specified amount.
/// Clamps the buffers capacity to either the maximum of the `desiredCapacity` or the buffer's `readableBytes`.
///
/// - returns: `true` if one or more bytes have been discarded, `false` if there are no bytes to discard.
/// - returns: A boolean indicating if the capacity of the buffer has changed.
@inlinable
@discardableResult public mutating func clampBufferCapacity(to maxRetainedCapacity: Int) -> Bool {
guard maxRetainedCapacity >= readableBytes && maxRetainedCapacity < capacity else {
@discardableResult public mutating func clampBufferCapacity(to desiredCapacity: Int) -> Bool {
let maxRetainedCapacity = max(self.readableBytes, desiredCapacity)
guard maxRetainedCapacity < capacity else {
return false
}

Expand Down
34 changes: 14 additions & 20 deletions Tests/NIOCoreTests/ByteBufferTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1839,34 +1839,28 @@ class ByteBufferTest: XCTestCase {
}

func testRestoreBufferCapacity() {
let maxBufferCapacityToBeRetained = 1024
let desiredCapacity = 1024
var buffer = self.allocator.buffer(capacity: 512)

// For an item equal to the maximum specified buffer capacity it should not clamp buffer capacity
// If readable capacity and desired capacity are less than or equal to buffer capacity, should not clamp
buffer.clear()
buffer.writeString(String(repeating: "x", count: maxBufferCapacityToBeRetained))
XCTAssertFalse(buffer.clampBufferCapacity(to: maxBufferCapacityToBeRetained))
XCTAssertEqual(buffer.capacity, 1024)
buffer.writeString(String(repeating: "x", count: desiredCapacity))
XCTAssertEqual(buffer.capacity, 1024) // Before
XCTAssertFalse(buffer.clampBufferCapacity(to: desiredCapacity))
XCTAssertEqual(buffer.capacity, 1024) // After

// For an item with readable bytes above the maximum specified buffer capacity it should not clamp
// If readable capacity is greater less than to buffer capacity, should clamp to readable bytes
buffer.clear()
buffer.writeString(String(repeating: "x", count: maxBufferCapacityToBeRetained + 1))
XCTAssertFalse(buffer.clampBufferCapacity(to: maxBufferCapacityToBeRetained))
XCTAssertEqual(buffer.capacity, 2048)
buffer.writeString(String(repeating: "x", count: desiredCapacity + 1))
XCTAssertTrue(buffer.clampBufferCapacity(to: desiredCapacity))
XCTAssertEqual(buffer.capacity, 1025)

// For a subsequent item smaller than buffer capacity it should clamp if the maximum specified buffer capacity is equal to, or less than readable bytes
// If desiredCapacity capacity is less than buffer capacity and larger than readable bytes, should clamp to desiredCapacity bytes
buffer.clear()
buffer.writeString(String(repeating: "x", count: maxBufferCapacityToBeRetained))
XCTAssertTrue(buffer.clampBufferCapacity(to: maxBufferCapacityToBeRetained))
buffer.writeString(String(repeating: "x", count: 512))
XCTAssertTrue(buffer.clampBufferCapacity(to: desiredCapacity))
XCTAssertEqual(buffer.capacity, 1024)

// For a small item smaller than maxBufferCapacityToBeRetained, it should not clamp further.
// This is to avoid flip-flopping between clamping and expansion during buffer lifecycle
buffer.clear()
buffer.writeString("Small item")
XCTAssertFalse(buffer.clampBufferCapacity(to: maxBufferCapacityToBeRetained))
XCTAssertEqual(buffer.capacity, 1024)

// For any item, it should not clamp buffer capacity to a value larger than the current buffer capacity
buffer.clear()
buffer.writeString("Any item")
Expand Down

0 comments on commit 735a357

Please sign in to comment.