Skip to content

Commit 44162be

Browse files
Lowered maximum transaction object count in memory at once by not keeping every child transaction around until the parent is complete
1 parent 6843e8c commit 44162be

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

Sources/CodableDatastore/Persistence/Disk Persistence/Transaction/Transaction.swift

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extension DiskPersistence {
1414
unowned let persistence: DiskPersistence
1515

1616
unowned let parent: Transaction?
17-
var childTransactions: [Transaction] = []
17+
weak var lastReadWriteChildTransaction: Transaction?
1818

1919
private(set) var task: Task<Void, Error>!
2020
let options: UnsafeTransactionOptions
@@ -133,7 +133,6 @@ extension DiskPersistence {
133133
deletedRootObjects.removeAll()
134134
deletedIndexes.removeAll()
135135
deletedPages.removeAll()
136-
childTransactions.removeAll()
137136
}
138137

139138
if let parent {
@@ -231,28 +230,30 @@ extension DiskPersistence {
231230
@_inheritActorContext handler: @Sendable @escaping (_ transaction: Transaction, _ isDurable: Bool) async throws -> T
232231
) async -> (Transaction, Task<T, Error>) {
233232
assert(!self.options.contains(.readOnly) || options.contains(.readOnly), "A child transaction was declared read-write, even though its parent was read-only!")
234-
let transaction = Transaction(
233+
let childTransaction = Transaction(
235234
persistence: persistence,
236235
parent: self,
237236
actionName: nil,
238237
options: options
239238
)
240239

241240
/// Get the last non-concurrent transaction from the list. Note that disk persistence currently does not support concurrent idempotent transactions.
242-
let lastChild = childTransactions.last { !$0.options.contains(.readOnly) }
243-
childTransactions.append(transaction)
241+
let lastChild = lastReadWriteChildTransaction
242+
if !childTransaction.options.contains(.readOnly) {
243+
lastReadWriteChildTransaction = childTransaction
244+
}
244245

245-
let task = await transaction.attachTask(options: options) {
246+
let task = await childTransaction.attachTask(options: options) {
246247
try self.checkIsActive()
247248

248249
/// If the transaction is not read only, wait for the last transaction to properly finish before starting the next one.
249250
if !options.contains(.readOnly) {
250251
_ = try? await lastChild?.task.value
251252
}
252-
return try await handler(transaction, false)
253+
return try await handler(childTransaction, false)
253254
}
254255

255-
return (transaction, task)
256+
return (childTransaction, task)
256257
}
257258

258259
func rootObject(for datastoreKey: DatastoreKey) async throws -> Datastore.RootObject? {

0 commit comments

Comments
 (0)