Containerization: Reduce allocations for image subsystems (#152)

Continue the allocations journey for anything that is in the codepaths
for pulling images. This time there's a couple spots in archive and ext4
we can get rid of some copies.
This commit is contained in:
Danny Canter
2025-06-18 16:11:46 -07:00
committed by GitHub
parent 35a821f041
commit 1992cfe779
3 changed files with 23 additions and 8 deletions
+4 -4
View File
@@ -101,9 +101,9 @@ extension ArchiveReader: Sequence {
internal func readDataForEntry(_ entry: WriteEntry) -> Data {
let bufferSize = Int(Swift.min(entry.size ?? 4096, 4096))
var data = Data()
var entry = Data()
var part = Data(count: bufferSize)
while true {
var part = Data(count: bufferSize)
let c = part.withUnsafeMutableBytes { buffer in
guard let baseAddress = buffer.baseAddress else {
return 0
@@ -112,9 +112,9 @@ extension ArchiveReader: Sequence {
}
guard c > 0 else { break }
part.count = c
data.append(part)
entry.append(part)
}
return data
return entry
}
}
@@ -130,14 +130,14 @@ extension EXT4.EXT4Reader {
entry.fileType = .symbolicLink
if size < 60 {
let linkBytes = EXT4.tupleToArray(inode.block)
entry.symlinkTarget = String(data: Data(linkBytes), encoding: .utf8) ?? ""
entry.symlinkTarget = String(bytes: linkBytes, encoding: .utf8) ?? ""
} else {
if let block = item.blocks {
try self.seek(block: block.start)
guard let linkBytes = try self.handle.read(upToCount: Int(size)) else {
throw EXT4.Error.couldNotReadBlock(block.start)
}
entry.symlinkTarget = String(data: Data(linkBytes), encoding: .utf8) ?? ""
entry.symlinkTarget = String(bytes: linkBytes, encoding: .utf8) ?? ""
}
}
try writer.writeEntry(entry: entry, data: nil)
@@ -260,12 +260,27 @@ public final class RegistryClient: ContentClient {
}
}
internal func requestBuffer(
components: URLComponents,
headers: [(String, String)]? = nil
) async throws -> ByteBuffer {
try await request(components: components, method: .GET, headers: headers) { response in
guard response.status == .ok else {
let url = components.url?.absoluteString ?? "unknown"
let reason = await ErrorResponse.fromResponseBody(response.body)?.jsonString
throw Error.invalidStatus(url: url, response.status, reason: reason)
}
return try await response.body.collect(upTo: self.bufferSize)
}
}
internal func requestJSON<T: Decodable>(
components: URLComponents,
headers: [(String, String)]? = nil
) async throws -> T {
let data = try await self.requestData(components: components, headers: headers)
return try JSONDecoder().decode(T.self, from: data)
let buffer = try await self.requestBuffer(components: components, headers: headers)
return try JSONDecoder().decode(T.self, from: buffer)
}
/// A minimal endpoint, mounted at /v2/ will provide version support information based on its response statuses.