Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions Sources/DataCacheKit/Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,19 @@ public actor Cache<Key: Hashable & Sendable, Value: Codable & Sendable>: Caching
return try decoder.decode(Value.self, from: data)
}()

await onMemery.store(value, for: key)
await onMemery.store(value, for: key).value
return value
}

@discardableResult
public func store(_ value: Value, for key: Key) -> Task<Void, Never> {
public nonisolated func store(_ value: Value, for key: Key) -> Task<Void, Never> {
return Task {
let task = await _store(value, for: key)
await task.value
}
}

private func _store(_ value: Value, for key: Key) -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
async let memory: Void = await onMemery.store(value, for: key).value
Expand All @@ -70,7 +77,14 @@ public actor Cache<Key: Hashable & Sendable, Value: Codable & Sendable>: Caching
}

@discardableResult
public func remove(for key: Key) -> Task<Void, Never> {
public nonisolated func remove(for key: Key) -> Task<Void, Never> {
return Task {
let task = await _remove(for: key)
await task.value
}
}

private func _remove(for key: Key) -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
async let memory: Void = await onMemery.remove(for: key).value
Expand All @@ -82,7 +96,14 @@ public actor Cache<Key: Hashable & Sendable, Value: Codable & Sendable>: Caching
}

@discardableResult
public func removeAll() -> Task<Void, Never> {
public nonisolated func removeAll() -> Task<Void, Never> {
return Task {
let task = await _removeAll()
await task.value
}
}

private func _removeAll() -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
async let memory: Void = await onMemery.removeAll().value
Expand Down
6 changes: 3 additions & 3 deletions Sources/DataCacheKit/Caching.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ public protocol Caching<Key, Value>: Actor {
func value(for key: Key) async throws -> Value?

@discardableResult
func store(_ value: Value, for key: Key) -> Task<Void, Never>
nonisolated func store(_ value: Value, for key: Key) -> Task<Void, Never>

@discardableResult
func remove(for key: Key) -> Task<Void, Never>
nonisolated func remove(for key: Key) -> Task<Void, Never>

@discardableResult
func removeAll() -> Task<Void, Never>
nonisolated func removeAll() -> Task<Void, Never>
}
28 changes: 25 additions & 3 deletions Sources/DataCacheKit/DiskCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,24 +117,46 @@ public actor DiskCache<Key: Hashable & Sendable>: Caching, @unchecked Sendable {
return try await task.value
}


@discardableResult
public func store(_ data: Data, for key: Key) -> Task<Void, Never> {
public nonisolated func store(_ value: Value, for key: Key) -> Task<Void, Never> {
return Task {
let task = await _store(value, for: key)
await task.value
}
}

private func _store(_ data: Data, for key: Key) -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
await _storeData(data, for: key)
}
}

@discardableResult
public func remove(for key: Key) -> Task<Void, Never> {
public nonisolated func remove(for key: Key) -> Task<Void, Never> {
return Task {
let task = await _remove(for: key)
await task.value
}
}

private func _remove(for key: Key) -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
await _removeData(for: key)
}
}

@discardableResult
public func removeAll() -> Task<Void, Never> {
public nonisolated func removeAll() -> Task<Void, Never> {
return Task {
let task = await _removeAll()
await task.value
}
}

private func _removeAll() -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
await _removeDataAll()
Expand Down
27 changes: 24 additions & 3 deletions Sources/DataCacheKit/MemoryCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,44 @@ public actor MemoryCache<Key: Hashable & Sendable, Value: Sendable>: Caching {
}

@discardableResult
public func store(_ value: Value, for key: Key) -> Task<Void, Never> {
public nonisolated func store(_ value: Value, for key: Key) -> Task<Void, Never> {
return Task {
let task = await _store(value, for: key)
await task.value
}
}

private func _store(_ value: Value, for key: Key) -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
lruCache.setValue(value, forKey: key, cost: (value as? Data)?.count ?? 0)
}
}

@discardableResult
public func remove(for key: Key) -> Task<Void, Never> {
public nonisolated func remove(for key: Key) -> Task<Void, Never> {
return Task {
let task = await _remove(for: key)
await task.value
}
}

private func _remove(for key: Key) -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
lruCache.removeValue(forKey: key)
}
}

@discardableResult
public func removeAll() -> Task<Void, Never> {
public nonisolated func removeAll() -> Task<Void, Never> {
return Task {
let task = await _removeAll()
await task.value
}
}

private func _removeAll() -> Task<Void, Never> {
queueingTask.enqueueAndReplacing { [weak self] in
guard let self else { return }
lruCache.removeAllValues()
Expand Down
22 changes: 11 additions & 11 deletions Tests/DataCacheKitTests/DiskCacheTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class DiskCacheTests {
let clock = ManualClock()
let cache = DiskCache<String>(options: cacheOptions(), clock: clock, logger: .init(.default))

await cache.store(Data(), for: "empty")
cache.store(Data(), for: "empty")

try await yield(until: await cache.isFlushScheduled)

Expand Down Expand Up @@ -81,8 +81,8 @@ final class DiskCacheTests {
let clock = ManualClock()
let cache = DiskCache<String>(options: cacheOptions(), clock: clock, logger: .init(.default))

await cache.store(Data([1]), for: "item0")
await cache.store(Data([1, 2]), for: "item1")
cache.store(Data([1]), for: "item0")
cache.store(Data([1, 2]), for: "item1")

try await yield(until: await cache.isFlushScheduled)

Expand All @@ -104,9 +104,9 @@ final class DiskCacheTests {
let clock = ManualClock()
let cache = DiskCache<String>(options: cacheOptions(), clock: clock, logger: .init(.default))

await cache.store(Data([1]), for: "item0")
await cache.store(Data([1, 2]), for: "item1")
await cache.remove(for: "item0")
cache.store(Data([1]), for: "item0")
cache.store(Data([1, 2]), for: "item1")
cache.remove(for: "item0")

try await yield(until: await cache.isFlushScheduled)

Expand Down Expand Up @@ -138,7 +138,7 @@ final class DiskCacheTests {
let clock = ManualClock()
let cache = DiskCache<String>(options: cacheOptions(), clock: clock, logger: .init(.default))

await cache.store(Data([1]), for: "item0")
cache.store(Data([1]), for: "item0")
try await yield(until: await cache.isFlushScheduled)

clock.advance(by: .milliseconds(1000))
Expand All @@ -153,7 +153,7 @@ final class DiskCacheTests {
#expect(isEmpty)
}

await cache.removeAll()
cache.removeAll()
try await yield(until: await cache.isFlushScheduled)

clock.advance(by: .milliseconds(1000))
Expand Down Expand Up @@ -181,9 +181,9 @@ final class DiskCacheTests {
let clock = ManualClock()
let cache = DiskCache<String>(options: options, clock: clock)

await cache.store(Data([1]), for: "item0")
await cache.store(Data([1, 2]), for: "item1")
await cache.store(Data([1, 2, 3]), for: "item2")
cache.store(Data([1]), for: "item0")
cache.store(Data([1, 2]), for: "item1")
cache.store(Data([1, 2, 3]), for: "item2")

try await yield(until: await cache.isFlushScheduled)

Expand Down