Skip to content

Commit f88a215

Browse files
committed
Add code comments
1 parent a5dc930 commit f88a215

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

Sources/PackageCollections/Storage/SQLitePackageCollectionsStorage.swift

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
4141
private let cache = ThreadSafeKeyValueStore<Model.CollectionIdentifier, Model.Collection>()
4242
private let cacheLock = Lock()
4343

44+
// Lock helps prevent concurrency errors with transaction statements during e.g. `refreshCollections`,
45+
// since only one transaction is allowed per SQLite connection. We need transactions to speed up bulk updates.
46+
// TODO: we could potentially optimize this with db connection pool
4447
private let ftsLock = Lock()
4548

49+
// Targets have in-memory trie in addition to SQLite FTS as optimization
4650
private let targetTrie = Trie<CollectionPackage>()
4751
private var targetTrieReady = ThreadSafeBox<Bool>(false)
4852

@@ -97,24 +101,23 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
97101
try statement.step()
98102
}
99103

100-
// Update search indices
101104
try self.ftsLock.withLock {
102-
// Lock helps prevent "SQL logic error" thrown by transaction statements during `refreshCollections`,
103-
// since only one transaction is allowed per connection. Bulk updates are faster with transaction.
105+
// Update search indices
104106
try self.withDB { db in
105107
try db.exec(query: "BEGIN TRANSACTION;")
106108

107109
// First delete existing data
108110
try self.removeFromSearchIndices(identifier: collection.identifier)
109111

110-
// Then insert new data
111112
let packagesStatement = try db.prepare(query: "INSERT INTO \(Self.packagesFTSName) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);")
112113
let targetsStatement = try db.prepare(query: "INSERT INTO \(Self.targetsFTSName) VALUES (?, ?, ?);")
113114

115+
// Then insert new data
114116
try collection.packages.forEach { package in
115117
var targets = Set<String>()
116118

117119
try package.versions.forEach { version in
120+
// Packages FTS
118121
let packagesBindings: [SQLite.SQLiteValue] = [
119122
.string(try self.encoder.encode(collection.identifier).base64EncodedString()),
120123
.string(package.reference.identity.description),
@@ -137,8 +140,10 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
137140

138141
let collectionPackage = CollectionPackage(collection: collection.identifier, package: package.reference.identity)
139142
try targets.forEach { target in
143+
// Targets in-memory trie
140144
self.targetTrie.insert(word: target.lowercased(), foundIn: collectionPackage)
141145

146+
// Targets FTS
142147
let targetsBindings: [SQLite.SQLiteValue] = [
143148
.string(try self.encoder.encode(collection.identifier).base64EncodedString()),
144149
.string(package.repository.url),
@@ -338,6 +343,7 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
338343
result[collection.identifier] = collection
339344
}
340345

346+
// For each package, find the containing collections
341347
let packageCollections = matches.filter { collectionDict.keys.contains($0.collection) }
342348
.reduce(into: [PackageIdentity: (package: Model.Package, collections: Set<Model.CollectionIdentifier>)]()) { result, match in
343349
var entry = result.removeValue(forKey: match.package)
@@ -435,35 +441,28 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
435441
}
436442
}
437443
} catch is NotFoundError {
438-
// do nothing if no matches
444+
// Do nothing if no matches found
439445
} catch {
440446
return callback(.failure(error))
441447
}
442448
} else {
443449
do {
444450
let targetQuery = "SELECT collection_id_blob_base64, package_repository_url, name FROM \(Self.targetsFTSName) WHERE name LIKE ?;"
445451
try self.executeStatement(targetQuery) { statement in
446-
try statement.bind([.string("\(query)%")])
447-
452+
switch type {
453+
case .exactMatch:
454+
try statement.bind([.string("\(query)")])
455+
case .prefix:
456+
try statement.bind([.string("\(query)%")])
457+
}
458+
448459
while let row = try statement.step() {
449-
let targetName = row.string(at: 2)
450-
let match: Bool
451-
switch type {
452-
case .exactMatch:
453-
// Cannot do case-insensitive exact-match with FTS
454-
match = query.lowercased() == targetName.lowercased()
455-
case .prefix:
456-
// FTS LIKE and MATCH are case-insensitive
457-
match = true
458-
}
459-
460-
if match,
461-
let collectionData = Data(base64Encoded: row.string(at: 0)),
460+
if let collectionData = Data(base64Encoded: row.string(at: 0)),
462461
let collection = try? self.decoder.decode(Model.CollectionIdentifier.self, from: collectionData) {
463462
matches.append((
464463
collection: collection,
465464
package: PackageIdentity(url: row.string(at: 1)),
466-
targetName: targetName
465+
targetName: row.string(at: 2)
467466
))
468467
}
469468
}
@@ -477,6 +476,7 @@ final class SQLitePackageCollectionsStorage: PackageCollectionsStorage, Closable
477476
result[collection.identifier] = collection
478477
}
479478

479+
// For each package, find the containing collections
480480
var packageCollections = [PackageIdentity: (package: Model.Package, collections: Set<Model.CollectionIdentifier>)]()
481481
// For each matching target, find the containing package version(s)
482482
var targetPackageVersions = [Model.Target: [PackageIdentity: Set<Model.TargetListResult.PackageVersion>]]()

Sources/PackageCollections/Storage/Trie.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct Trie<Document: Hashable> {
6060
removeInSubTrie(root: self.root, document: document)
6161
}
6262

63-
/// Removes word occurrences found in the given document.
63+
/// Removes word occurrences found in matching document(s).
6464
func remove(where predicate: @escaping (Document) -> Bool) {
6565
func removeInSubTrie(root: Node, where predicate: @escaping (Document) -> Bool) {
6666
if root.isTerminating {

0 commit comments

Comments
 (0)