Bgerstle has submitted this change and it was merged.

Change subject: Core data performance improvements. Bug T99260
......................................................................


Core data performance improvements. Bug T99260

Separate core data fetches into batches.
Reset context in-between fetches to reduce memory.
Move to async operations to allow UI to update progress during saves.

Change-Id: Iffdb31166dacde1caef5d89f2050f11b404a85c7
---
M Wikipedia/Data/OldDataSchemaMigrator.m
1 file changed, 98 insertions(+), 36 deletions(-)

Approvals:
  Bgerstle: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/Wikipedia/Data/OldDataSchemaMigrator.m 
b/Wikipedia/Data/OldDataSchemaMigrator.m
index 616cb07..609bb32 100644
--- a/Wikipedia/Data/OldDataSchemaMigrator.m
+++ b/Wikipedia/Data/OldDataSchemaMigrator.m
@@ -105,48 +105,110 @@
 }
 
 - (void)migrateData {
-    [self.context performBlock:^{
-        NSFetchRequest* req = [NSFetchRequest 
fetchRequestWithEntityName:@"Saved"];
-        req.sortDescriptors = @[[[NSSortDescriptor alloc] 
initWithKey:@"dateSaved" ascending:YES]];
-        NSError* err;
-        NSArray* savedEntries = [self.context executeFetchRequest:req 
error:&err];
-
-        if (err) {
-            NSLog(@"Error reading old Saved entries: %@", err);
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 
0), ^{
+        if (![self migrateHistory]) {
         }
 
-        NSFetchRequest* req2 = [NSFetchRequest 
fetchRequestWithEntityName:@"History"];
-        req2.sortDescriptors = @[[[NSSortDescriptor alloc] 
initWithKey:@"dateVisited" ascending:YES]];
-        NSError* err2;
-        NSArray* historyEntries = [self.context executeFetchRequest:req2 
error:&err2];
-
-        if (err2) {
-            NSLog(@"Error reading old History entries: %@", err2);
-        }
-
-        NSUInteger totalArticlesToMigrate = [savedEntries count];
-        __block NSUInteger numberOfArticlesMigrated = 0;
-
-        void (^ incrementAndNotify)(void) = ^void (void) {
-            numberOfArticlesMigrated++;
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [self.progressDelegate oldDataSchema:self 
didUpdateProgressWithArticlesCompleted:numberOfArticlesMigrated 
total:totalArticlesToMigrate];
-            });
-        };
-
-        for (History* history in historyEntries) {
-            [self migrateHistory:history];
-        }
-
-        for (Saved* saved in savedEntries) {
-            [self migrateSaved:saved];
-            [self migrateArticle:saved.article];
-            incrementAndNotify();
+        if (![self migrateSavedPages]) {
         }
 
         [self moveOldDataToBackupLocation];
-        [self.progressDelegate oldDataSchemaDidFinishMigration:self];
+
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [self.progressDelegate oldDataSchemaDidFinishMigration:self];
+        });
+    });
+}
+
+- (BOOL)migrateHistory {
+    __block NSError* error;
+
+    [self.context performBlockAndWait:^{
+        NSFetchRequest* req2 = [NSFetchRequest 
fetchRequestWithEntityName:@"History"];
+        req2.sortDescriptors = @[[[NSSortDescriptor alloc] 
initWithKey:@"dateVisited" ascending:YES]];
+        NSArray* historyEntries = [self.context executeFetchRequest:req2 
error:&error];
+
+        if (error) {
+            NSLog(@"Error reading old History entries: %@", error);
+        }
+
+        for (History* history in historyEntries) {
+            @autoreleasepool {
+                [self migrateHistory:history];
+            }
+        }
+
+        [self.context reset];
     }];
+
+
+    return error == nil;
+}
+
+- (BOOL)migrateSavedPages {
+    __block NSError* error;
+    __block NSUInteger totalArticlesToMigrate   = 0;
+    __block NSUInteger numberOfArticlesMigrated = 0;
+
+    [self.context performBlockAndWait:^{
+        NSFetchRequest* req = [NSFetchRequest 
fetchRequestWithEntityName:@"Saved"];
+        req.sortDescriptors = @[[[NSSortDescriptor alloc] 
initWithKey:@"dateSaved" ascending:YES]];
+        totalArticlesToMigrate = [self.context countForFetchRequest:req 
error:&error];
+        NSLog(@"total articles: %lu", totalArticlesToMigrate);
+    }];
+
+    NSUInteger fetchSize                   = 25;
+    __block BOOL moreSavedEntriesToProcess = YES;
+    __block NSUInteger fetchOffset         = 0;
+
+    if (totalArticlesToMigrate > 0) {
+        while (moreSavedEntriesToProcess) {
+            NSFetchRequest* req = [NSFetchRequest 
fetchRequestWithEntityName:@"Saved"];
+            req.sortDescriptors = @[[[NSSortDescriptor alloc] 
initWithKey:@"dateSaved" ascending:YES]];
+            req.fetchLimit      = fetchSize;
+            req.fetchOffset     = fetchOffset;
+
+            [self.context performBlock:^{
+                NSError* innerError;
+                NSArray* savedEntries = [self.context executeFetchRequest:req 
error:&innerError];
+
+                if (savedEntries) {
+                    for (Saved* saved in savedEntries) {
+                        @autoreleasepool {
+                            [self migrateSaved:saved];
+                            [self migrateArticle:saved.article];
+                            numberOfArticlesMigrated++;
+                            dispatch_async(dispatch_get_main_queue(), ^{
+                                [self.progressDelegate oldDataSchema:self 
didUpdateProgressWithArticlesCompleted:numberOfArticlesMigrated 
total:totalArticlesToMigrate];
+                            });
+                        }
+                    }
+                } else {
+                    error = innerError;
+                    NSLog(@"Error reading old Saved entries: %@", error);
+                }
+
+                [self.context reset];
+            }];
+
+            NSUInteger indexOfLastArticleMigrated = fetchOffset + fetchSize - 
1;
+            NSUInteger indexOfLastArticle         = totalArticlesToMigrate - 1;
+
+            if (indexOfLastArticleMigrated < indexOfLastArticle) {
+                fetchOffset += fetchSize;
+            } else {
+                moreSavedEntriesToProcess = NO;
+            }
+        }
+    }
+
+    //Wait on the context to finish the above operations.
+    //We need to do this because we need the above calls to be async so we can
+    //call back to the main thread to update the UI
+    [self.context performBlockAndWait:^{
+    }];
+
+    return error == nil;
 }
 
 - (MWKSite*)migrateArticleSite:(Article*)article {

-- 
To view, visit https://gerrit.wikimedia.org/r/211717
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Iffdb31166dacde1caef5d89f2050f11b404a85c7
Gerrit-PatchSet: 2
Gerrit-Project: apps/ios/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Fjalapeno <cfl...@wikimedia.org>
Gerrit-Reviewer: Bgerstle <bgers...@wikimedia.org>
Gerrit-Reviewer: Mhurd <mh...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to