From 34ae27bb3a9499520cbffde84ea83e2ad14b48b3 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Tue, 30 Jan 2024 15:27:16 -0800 Subject: [PATCH] [Caching] Add CAS size management APIs rdar://121944849 --- Sources/CSwiftScan/include/swiftscan_header.h | 7 ++++++ Sources/SwiftDriver/SwiftScan/SwiftScan.swift | 14 +++++++++++ .../SwiftDriver/SwiftScan/SwiftScanCAS.swift | 23 +++++++++++++++++++ .../SwiftDriverTests/CachingBuildTests.swift | 23 +++++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/Sources/CSwiftScan/include/swiftscan_header.h b/Sources/CSwiftScan/include/swiftscan_header.h index 377de2bec..9408f3fd5 100644 --- a/Sources/CSwiftScan/include/swiftscan_header.h +++ b/Sources/CSwiftScan/include/swiftscan_header.h @@ -274,6 +274,13 @@ typedef struct { //=== Scanner CAS Operations ----------------------------------------------===// swiftscan_cas_options_t (*swiftscan_cas_options_create)(void); + int64_t (*swiftscan_cas_get_ondisk_size)(swiftscan_cas_t, + swiftscan_string_ref_t *error); + bool (*swiftscan_cas_set_ondisk_size_limit)(swiftscan_cas_t, + int64_t size_limit, + swiftscan_string_ref_t *error); + bool (*swiftscan_cas_prune_ondisk_data)(swiftscan_cas_t, + swiftscan_string_ref_t *error); void (*swiftscan_cas_options_dispose)(swiftscan_cas_options_t options); void (*swiftscan_cas_options_set_ondisk_path)(swiftscan_cas_options_t options, const char *path); diff --git a/Sources/SwiftDriver/SwiftScan/SwiftScan.swift b/Sources/SwiftDriver/SwiftScan/SwiftScan.swift index 8ebe9e041..6d7b7f471 100644 --- a/Sources/SwiftDriver/SwiftScan/SwiftScan.swift +++ b/Sources/SwiftDriver/SwiftScan/SwiftScan.swift @@ -300,6 +300,17 @@ internal extension swiftscan_diagnostic_severity_t { #endif } + @_spi(Testing) public var supportsCASSizeManagement : Bool { +#if os(Windows) + // CAS is currently not supported on Windows hosts. + return false +#else + return api.swiftscan_cas_get_ondisk_size != nil && + api.swiftscan_cas_set_ondisk_size_limit != nil && + api.swiftscan_cas_prune_ondisk_data != nil +#endif + } + @_spi(Testing) public var supportsBridgingHeaderPCHCommand : Bool { return api.swiftscan_swift_textual_detail_get_bridging_pch_command_line != nil } @@ -511,6 +522,9 @@ private extension swiftscan_functions_t { self.swiftscan_cas_options_set_plugin_option = try loadOptional("swiftscan_cas_options_set_plugin_option") self.swiftscan_cas_options_dispose = try loadOptional("swiftscan_cas_options_dispose") self.swiftscan_cas_create_from_options = try loadOptional("swiftscan_cas_create_from_options") + self.swiftscan_cas_get_ondisk_size = try loadOptional("swiftscan_cas_get_ondisk_size") + self.swiftscan_cas_set_ondisk_size_limit = try loadOptional("swiftscan_cas_set_ondisk_size_limit") + self.swiftscan_cas_prune_ondisk_data = try loadOptional("swiftscan_cas_prune_ondisk_data") self.swiftscan_cas_dispose = try loadOptional("swiftscan_cas_dispose") self.swiftscan_cache_compute_key = try loadOptional("swiftscan_cache_compute_key") self.swiftscan_cache_compute_key_from_input_index = try loadOptional("swiftscan_cache_compute_key_from_input_index") diff --git a/Sources/SwiftDriver/SwiftScan/SwiftScanCAS.swift b/Sources/SwiftDriver/SwiftScan/SwiftScanCAS.swift index 668e269a3..c245d643b 100644 --- a/Sources/SwiftDriver/SwiftScan/SwiftScanCAS.swift +++ b/Sources/SwiftDriver/SwiftScan/SwiftScanCAS.swift @@ -198,6 +198,29 @@ public final class SwiftScanCAS { return try scanner.toSwiftString(casid) } + public var supportsSizeManagement: Bool { + scanner.supportsCASSizeManagement + } + + public func getStorageSize() throws -> Int64? { + let size = try scanner.handleCASError { err_msg in + scanner.api.swiftscan_cas_get_ondisk_size(cas, &err_msg) + } + return size == -1 ? nil : size + } + + public func setSizeLimit(_ size: Int64) throws { + _ = try scanner.handleCASError { err_msg in + scanner.api.swiftscan_cas_set_ondisk_size_limit(cas, size, &err_msg) + } + } + + public func prune() throws { + _ = try scanner.handleCASError { err_msg in + scanner.api.swiftscan_cas_prune_ondisk_data(cas, &err_msg) + } + } + @available(*, deprecated) public func computeCacheKey(commandLine: [String], input: String) throws -> String { let casid = try scanner.handleCASError { err_msg in diff --git a/Tests/SwiftDriverTests/CachingBuildTests.swift b/Tests/SwiftDriverTests/CachingBuildTests.swift index fea29a1eb..8ed718e95 100644 --- a/Tests/SwiftDriverTests/CachingBuildTests.swift +++ b/Tests/SwiftDriverTests/CachingBuildTests.swift @@ -849,4 +849,27 @@ final class CachingBuildTests: XCTestCase { } } } + + func testCASManagement() throws { + try withTemporaryDirectory { path in + let casPath = path.appending(component: "cas") + let driver = try Driver(args: ["swiftc", "-v"]) + let scanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath()) + try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem, + swiftScanLibPath: scanLibPath) + let cas = try dependencyOracle.getOrCreateCAS(pluginPath: nil, onDiskPath: casPath, pluginOptions: []) + guard cas.supportsSizeManagement else { + throw XCTSkip("CAS size management is not supported") + } + let preSize = try XCTUnwrap(try cas.getStorageSize()) + let dataToStore = Data(count: 1000) + _ = try cas.store(data: dataToStore) + let postSize = try XCTUnwrap(try cas.getStorageSize()) + XCTAssertTrue(postSize > preSize) + + // Try prune. + try cas.setSizeLimit(100) + try cas.prune() + } + } }