@@ -190,161 +190,155 @@ extension Datastore {
190190 handler ( . evaluating)
191191 }
192192
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 ( )
196195
197196 var rebuildPrimaryIndex = false
198197 var directIndexesToBuild : Set < IndexName > = [ ]
199198 var secondaryIndexesToBuild : Set < IndexName > = [ ]
200199 var index = 0
201200
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+ }
203206
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)
215215 }
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)
252237 }
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 }
253265
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) )
259269 }
260270
261- /// Remove any direct indexes from the secondary ones we may have requested.
262- secondaryIndexesToBuild. subtract ( directIndexesToBuild)
271+ let instanceData = try await encoder ( instance)
263272
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+ )
267283 }
268284
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 > = [ ]
282286
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)
312296
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 )
339323
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+ }
348342 }
349343 }
350344 }
0 commit comments