Skip to content

Commit b29e1e7

Browse files
committed
Observe both newly unmaterialised and newly materialised items
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
1 parent 2bd288c commit b29e1e7

2 files changed

Lines changed: 46 additions & 30 deletions

File tree

Sources/NextcloudFileProviderKit/Enumeration/MaterialisedEnumerationObserver.swift

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ public class MaterialisedEnumerationObserver: NSObject, NSFileProviderEnumeratio
2121
static let logger = Logger(subsystem: Logger.subsystem, category: "materialisedobservation")
2222
public let ncKitAccount: String
2323
let dbManager: FilesDatabaseManager
24-
private let completionHandler: (_ deletedOcIds: Set<String>) -> Void
25-
private var allEnumeratedItemIds: Set<String> = .init()
24+
private let completionHandler: (
25+
_ materialisedIds: Set<String>, _ unmaterialisedIds: Set<String>
26+
) -> Void
27+
private var allEnumeratedItemIds = Set<String>()
2628

2729
public required init(
2830
ncKitAccount: String,
2931
dbManager: FilesDatabaseManager,
30-
completionHandler: @escaping (_ deletedOcIds: Set<String>) -> Void
32+
completionHandler: @escaping (
33+
_ materialisedIds: Set<String>, _ unmaterialisedIds: Set<String>
34+
) -> Void
3135
) {
3236
self.ncKitAccount = ncKitAccount
3337
self.dbManager = dbManager
@@ -36,11 +40,7 @@ public class MaterialisedEnumerationObserver: NSObject, NSFileProviderEnumeratio
3640
}
3741

3842
public func didEnumerate(_ updatedItems: [NSFileProviderItemProtocol]) {
39-
let updatedItemsIds = Array(updatedItems.map(\.itemIdentifier.rawValue))
40-
41-
for updatedItemsId in updatedItemsIds {
42-
allEnumeratedItemIds.insert(updatedItemsId)
43-
}
43+
updatedItems.map(\.itemIdentifier.rawValue).forEach { allEnumeratedItemIds.insert($0) }
4444
}
4545

4646
public func finishEnumerating(upTo _: NSFileProviderPage?) {
@@ -69,34 +69,50 @@ public class MaterialisedEnumerationObserver: NSObject, NSFileProviderEnumeratio
6969
_ itemIds: Set<String>,
7070
account: String,
7171
dbManager: FilesDatabaseManager,
72-
completionHandler: @escaping (_ deletedOcIds: Set<String>) -> Void
72+
completionHandler: @escaping (
73+
_ materialisedIds: Set<String>, _ unmaterialisedIds: Set<String>
74+
) -> Void
7375
) {
74-
let databaseLocalFileMetadatas = dbManager
75-
.itemMetadatas
76-
.where({ $0.account == account && $0.downloaded })
77-
.toUnmanagedResults()
78-
var noLongerMaterialisedIds = Set<String>()
76+
let materialisedMetadatas = dbManager.materialisedItemMetadatas(account: account)
77+
var materialisedMetadatasMap = [String: SendableItemMetadata]()
78+
var unmaterialisedIds = Set<String>()
79+
var newMaterialisedIds = Set<String>()
7980

80-
DispatchQueue.global(qos: .background).async {
81-
for localFile in databaseLocalFileMetadatas {
82-
let localFileOcId = localFile.ocId
81+
materialisedMetadatas.forEach {
82+
materialisedMetadatasMap[$0.ocId] = $0
83+
unmaterialisedIds.insert($0.ocId)
84+
}
8385

84-
guard itemIds.contains(localFileOcId) else {
85-
noLongerMaterialisedIds.insert(localFileOcId)
86+
for enumeratedId in itemIds {
87+
if unmaterialisedIds.contains(enumeratedId) {
88+
unmaterialisedIds.remove(enumeratedId)
89+
} else {
90+
newMaterialisedIds.insert(enumeratedId)
91+
guard var metadata = dbManager.itemMetadata(ocId: enumeratedId) else {
92+
Self.logger.error("No metadata for \(enumeratedId, privacy: .public) found")
8693
continue
8794
}
88-
}
89-
90-
DispatchQueue.main.async {
91-
Self.logger.info("Cleaning up local file metadatas for unmaterialised items")
92-
for itemId in noLongerMaterialisedIds {
93-
guard var itemMetadata = dbManager.itemMetadata(ocId: itemId) else { continue }
94-
itemMetadata.downloaded = false
95-
dbManager.addItemMetadata(itemMetadata)
95+
if metadata.directory {
96+
metadata.visitedDirectory = true
97+
} else {
98+
metadata.downloaded = true
9699
}
100+
dbManager.addItemMetadata(metadata)
101+
}
102+
}
97103

98-
completionHandler(noLongerMaterialisedIds)
104+
for unmaterialisedId in unmaterialisedIds {
105+
guard var metadata = materialisedMetadatasMap[unmaterialisedId] else {
106+
Self.logger.error("No materialised for \(unmaterialisedId, privacy: .public) found")
107+
continue
99108
}
109+
metadata.downloaded = false
110+
metadata.visitedDirectory = false
111+
dbManager.addItemMetadata(metadata)
100112
}
113+
114+
// TODO: Do we need to signal the working set now? Unclear
115+
116+
completionHandler(newMaterialisedIds, unmaterialisedIds)
101117
}
102118
}

Tests/NextcloudFileProviderKitTests/MaterialisedEnumerationObserverTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ final class MaterialisedEnumerationObserverTests: XCTestCase {
3131
let expect = XCTestExpectation(description: "Enumerator")
3232
let observer = MaterialisedEnumerationObserver(
3333
ncKitAccount: Self.account.ncKitAccount, dbManager: dbManager
34-
) { deletedOcIds in
34+
) { _, deletedOcIds in
3535
XCTAssertTrue(deletedOcIds.isEmpty)
3636
expect.fulfill()
3737
}
@@ -63,7 +63,7 @@ final class MaterialisedEnumerationObserverTests: XCTestCase {
6363
let expect = XCTestExpectation(description: "Enumerator")
6464
let observer = MaterialisedEnumerationObserver(
6565
ncKitAccount: Self.account.ncKitAccount, dbManager: dbManager
66-
) { deletedOcIds in
66+
) { _, deletedOcIds in
6767
// itemA is downloaded, itemB is not, itemC is (and is new). Only the local copy of
6868
// itemA should come up as deleted
6969
XCTAssertEqual(deletedOcIds.count, 1) // Item B deleted

0 commit comments

Comments
 (0)