@@ -190,161 +190,155 @@ extension Datastore {
190
190
handler ( . evaluating)
191
191
}
192
192
193
- var newDescriptor : DatastoreDescriptor ?
194
-
195
- let primaryIndex = _load ( IndexRange ( ) , order: . ascending, awaitWarmup: false )
193
+ /// Grab an up-to-date descriptor and check the indexes against it
194
+ let updatedDescriptor = try generateUpdatedDescriptor ( )
196
195
197
196
var rebuildPrimaryIndex = false
198
197
var directIndexesToBuild : Set < IndexName > = [ ]
199
198
var secondaryIndexesToBuild : Set < IndexName > = [ ]
200
199
var index = 0
201
200
202
- let versionData = try Data ( self . version)
201
+ /// Check the primary index for compatibility.
202
+ if persistedDescriptor. identifierType != updatedDescriptor. identifierType {
203
+ try await transaction. resetPrimaryIndex ( datastoreKey: key)
204
+ rebuildPrimaryIndex = true
205
+ }
203
206
204
- for try await (idenfifier, instance) in primaryIndex {
205
- defer { index += 1 }
206
- /// Use the first index to grab an up-to-date descriptor
207
- if newDescriptor == nil {
208
- let updatedDescriptor = try generateUpdatedDescriptor ( )
209
- newDescriptor = updatedDescriptor
210
-
211
- /// Check the primary index for compatibility.
212
- if persistedDescriptor. identifierType != updatedDescriptor. identifierType {
213
- try await transaction. resetPrimaryIndex ( datastoreKey: key)
214
- rebuildPrimaryIndex = true
207
+ /// Check existing direct indexes for compatibility
208
+ for (_, persistedIndex) in persistedDescriptor. directIndexes {
209
+ if let updatedIndex = updatedDescriptor. directIndexes [ persistedIndex. name] {
210
+ /// If the index still exists, make sure it is compatible by checking their types, or checking if the primary index must be re-built.
211
+ if persistedIndex. type != updatedIndex. type || rebuildPrimaryIndex {
212
+ /// They were not compatible, so delete the bad index, and queue it to be re-built.
213
+ try await transaction. deleteDirectIndex ( indexName: persistedIndex. name, datastoreKey: key)
214
+ directIndexesToBuild. insert ( persistedIndex. name)
215
215
}
216
-
217
- /// Check existing direct indexes for compatibility
218
- for (_, persistedIndex) in persistedDescriptor. directIndexes {
219
- if let updatedIndex = updatedDescriptor. directIndexes [ persistedIndex. name] {
220
- /// If the index still exists, make sure it is compatible by checking their types, or checking if the primary index must be re-built.
221
- if persistedIndex. type != updatedIndex. type || rebuildPrimaryIndex {
222
- /// They were not compatible, so delete the bad index, and queue it to be re-built.
223
- try await transaction. deleteDirectIndex ( indexName: persistedIndex. name, datastoreKey: key)
224
- directIndexesToBuild. insert ( persistedIndex. name)
225
- }
226
- } else {
227
- /// The index is no longer needed, delete it.
228
- try await transaction. deleteDirectIndex ( indexName: persistedIndex. name, datastoreKey: key)
229
- }
230
- }
231
-
232
- /// Check for new direct indexes to build
233
- for (_, updatedIndex) in updatedDescriptor. directIndexes {
234
- guard persistedDescriptor. directIndexes [ updatedIndex. name] == nil else { continue }
235
- /// The index does not yet exist, so queue it to be built.
236
- directIndexesToBuild. insert ( updatedIndex. name)
237
- }
238
-
239
- /// Check existing secondary indexes for compatibility
240
- for (_, persistedIndex) in persistedDescriptor. referenceIndexes {
241
- if let updatedIndex = updatedDescriptor. referenceIndexes [ persistedIndex. name] {
242
- /// If the index still exists, make sure it is compatible
243
- if persistedIndex. type != updatedIndex. type {
244
- /// They were not compatible, so delete the bad index, and queue it to be re-built.
245
- try await transaction. deleteDirectIndex ( indexName: persistedIndex. name, datastoreKey: key)
246
- secondaryIndexesToBuild. insert ( persistedIndex. name)
247
- }
248
- } else {
249
- /// The index is no longer needed, delete it.
250
- try await transaction. deleteDirectIndex ( indexName: persistedIndex. name, datastoreKey: key)
251
- }
216
+ } else {
217
+ /// The index is no longer needed, delete it.
218
+ try await transaction. deleteDirectIndex ( indexName: persistedIndex. name, datastoreKey: key)
219
+ }
220
+ }
221
+
222
+ /// Check for new direct indexes to build
223
+ for (_, updatedIndex) in updatedDescriptor. directIndexes {
224
+ guard persistedDescriptor. directIndexes [ updatedIndex. name] == nil else { continue }
225
+ /// The index does not yet exist, so queue it to be built.
226
+ directIndexesToBuild. insert ( updatedIndex. name)
227
+ }
228
+
229
+ /// Check existing reference indexes for compatibility
230
+ for (_, persistedIndex) in persistedDescriptor. referenceIndexes {
231
+ if let updatedIndex = updatedDescriptor. referenceIndexes [ persistedIndex. name] {
232
+ /// If the index still exists, make sure it is compatible
233
+ if persistedIndex. type != updatedIndex. type {
234
+ /// They were not compatible, so delete the bad index, and queue it to be re-built.
235
+ try await transaction. deleteSecondaryIndex ( indexName: persistedIndex. name, datastoreKey: key)
236
+ secondaryIndexesToBuild. insert ( persistedIndex. name)
252
237
}
238
+ } else {
239
+ /// The index is no longer needed, delete it.
240
+ try await transaction. deleteSecondaryIndex ( indexName: persistedIndex. name, datastoreKey: key)
241
+ }
242
+ }
243
+
244
+ /// Check for new reference indexes to build
245
+ for (_, updatedIndex) in updatedDescriptor. referenceIndexes {
246
+ guard persistedDescriptor. referenceIndexes [ updatedIndex. name] == nil else { continue }
247
+ /// The index does not yet exist, so queue it to be built.
248
+ secondaryIndexesToBuild. insert ( updatedIndex. name)
249
+ }
250
+
251
+ /// Remove any direct indexes from the secondary ones we may have requested.
252
+ secondaryIndexesToBuild. subtract ( directIndexesToBuild)
253
+
254
+ /// Only perform work if we need to rebuild anything.
255
+ if rebuildPrimaryIndex || !directIndexesToBuild. isEmpty || !secondaryIndexesToBuild. isEmpty {
256
+ /// Create any missing indexes and prime the datastore for writing.
257
+ try await transaction. apply ( descriptor: updatedDescriptor, for: key)
258
+
259
+ let primaryIndex = _load ( IndexRange ( ) , order: . ascending, awaitWarmup: false )
260
+
261
+ let versionData = try Data ( self . version)
262
+
263
+ for try await (idenfifier, instance) in primaryIndex {
264
+ defer { index += 1 }
253
265
254
- /// Check for new secondary indexes to build
255
- for (_, updatedIndex) in updatedDescriptor. referenceIndexes {
256
- guard persistedDescriptor. referenceIndexes [ updatedIndex. name] == nil else { continue }
257
- /// The index does not yet exist, so queue it to be built.
258
- secondaryIndexesToBuild. insert ( updatedIndex. name)
266
+ /// Notify progress handlers we are starting an entry.
267
+ for handler in warmupProgressHandlers {
268
+ handler ( . working( current: index, total: persistedDescriptor. size) )
259
269
}
260
270
261
- /// Remove any direct indexes from the secondary ones we may have requested.
262
- secondaryIndexesToBuild. subtract ( directIndexesToBuild)
271
+ let instanceData = try await encoder ( instance)
263
272
264
- /// If we don't need to migrate anything, stop here.
265
- if rebuildPrimaryIndex == false , directIndexesToBuild. isEmpty, secondaryIndexesToBuild. isEmpty {
266
- break
273
+ if rebuildPrimaryIndex {
274
+ let insertionCursor = try await transaction. primaryIndexCursor ( inserting: idenfifier, datastoreKey: key)
275
+
276
+ try await transaction. persistPrimaryIndexEntry (
277
+ versionData: versionData,
278
+ identifierValue: idenfifier,
279
+ instanceData: instanceData,
280
+ cursor: insertionCursor,
281
+ datastoreKey: key
282
+ )
267
283
}
268
284
269
- /// Create any missing indexes and prime the datastore for writing.
270
- try await transaction. apply ( descriptor: updatedDescriptor, for: key)
271
- }
272
-
273
- /// Notify progress handlers we are starting an entry.
274
- for handler in warmupProgressHandlers {
275
- handler ( . working( current: index, total: persistedDescriptor. size) )
276
- }
277
-
278
- let instanceData = try await encoder ( instance)
279
-
280
- if rebuildPrimaryIndex {
281
- let insertionCursor = try await transaction. primaryIndexCursor ( inserting: idenfifier, datastoreKey: key)
285
+ var queriedIndexes : Set < IndexName > = [ ]
282
286
283
- try await transaction. persistPrimaryIndexEntry (
284
- versionData: versionData,
285
- identifierValue: idenfifier,
286
- instanceData: instanceData,
287
- cursor: insertionCursor,
288
- datastoreKey: key
289
- )
290
- }
291
-
292
- var queriedIndexes : Set < IndexName > = [ ]
293
-
294
- for (_, generatedRepresentation) in indexRepresentations {
295
- let indexName = generatedRepresentation. indexName
296
- switch generatedRepresentation. storage {
297
- case . direct:
298
- guard
299
- directIndexesToBuild. contains ( indexName) ,
300
- !queriedIndexes. contains ( indexName)
301
- else { return }
302
- queriedIndexes. insert ( indexName)
303
-
304
- for updatedValue in instance [ index: generatedRepresentation. index] {
305
- /// Grab a cursor to insert the new value in the index.
306
- let updatedValueCursor = try await transaction. directIndexCursor (
307
- inserting: updatedValue. indexed,
308
- identifier: idenfifier,
309
- indexName: indexName,
310
- datastoreKey: key
311
- )
287
+ for (_, generatedRepresentation) in indexRepresentations {
288
+ let indexName = generatedRepresentation. indexName
289
+ switch generatedRepresentation. storage {
290
+ case . direct:
291
+ guard
292
+ directIndexesToBuild. contains ( indexName) ,
293
+ !queriedIndexes. contains ( indexName)
294
+ else { return }
295
+ queriedIndexes. insert ( indexName)
312
296
313
- /// Insert it.
314
- try await transaction . persistDirectIndexEntry (
315
- versionData : versionData ,
316
- indexValue : updatedValue. indexed,
317
- identifierValue : idenfifier,
318
- instanceData : instanceData ,
319
- cursor : updatedValueCursor ,
320
- indexName : indexName ,
321
- datastoreKey : key
322
- )
323
- }
324
- case . reference :
325
- guard
326
- secondaryIndexesToBuild . contains ( indexName ) ,
327
- !queriedIndexes . contains ( indexName )
328
- else { return }
329
- queriedIndexes . insert ( indexName)
330
-
331
- for updatedValue in instance [ index : generatedRepresentation . index ] {
332
- /// Grab a cursor to insert the new value in the index.
333
- let updatedValueCursor = try await transaction . secondaryIndexCursor (
334
- inserting : updatedValue . indexed ,
335
- identifier : idenfifier ,
336
- indexName: indexName ,
337
- datastoreKey : self . key
338
- )
297
+ for updatedValue in instance [ index : generatedRepresentation . index ] {
298
+ /// Grab a cursor to insert the new value in the index.
299
+ let updatedValueCursor = try await transaction . directIndexCursor (
300
+ inserting : updatedValue. indexed,
301
+ identifier : idenfifier,
302
+ indexName : indexName ,
303
+ datastoreKey : key
304
+ )
305
+
306
+ /// Insert it.
307
+ try await transaction . persistDirectIndexEntry (
308
+ versionData : versionData ,
309
+ indexValue : updatedValue . indexed ,
310
+ identifierValue : idenfifier ,
311
+ instanceData : instanceData ,
312
+ cursor : updatedValueCursor ,
313
+ indexName: indexName ,
314
+ datastoreKey : key
315
+ )
316
+ }
317
+ case . reference :
318
+ guard
319
+ secondaryIndexesToBuild . contains ( indexName ) ,
320
+ !queriedIndexes . contains ( indexName)
321
+ else { return }
322
+ queriedIndexes . insert ( indexName )
339
323
340
- /// Insert it.
341
- try await transaction. persistSecondaryIndexEntry (
342
- indexValue: updatedValue. indexed,
343
- identifierValue: idenfifier,
344
- cursor: updatedValueCursor,
345
- indexName: indexName,
346
- datastoreKey: self . key
347
- )
324
+ for updatedValue in instance [ index: generatedRepresentation. index] {
325
+ /// Grab a cursor to insert the new value in the index.
326
+ let updatedValueCursor = try await transaction. secondaryIndexCursor (
327
+ inserting: updatedValue. indexed,
328
+ identifier: idenfifier,
329
+ indexName: indexName,
330
+ datastoreKey: self . key
331
+ )
332
+
333
+ /// Insert it.
334
+ try await transaction. persistSecondaryIndexEntry (
335
+ indexValue: updatedValue. indexed,
336
+ identifierValue: idenfifier,
337
+ cursor: updatedValueCursor,
338
+ indexName: indexName,
339
+ datastoreKey: self . key
340
+ )
341
+ }
348
342
}
349
343
}
350
344
}
0 commit comments