Respond to CR.

pull/1/head
Matthew Chen 7 years ago
parent 5c3bc74d06
commit 34d79265a1

@ -239,10 +239,7 @@ import CloudKit
success: @escaping (()) -> Void, success: @escaping (()) -> Void,
failure: @escaping (Error) -> Void) { failure: @escaping (Error) -> Void) {
var recordIDs = [CKRecordID]() let recordIDs = recordNames.map { CKRecordID(recordName: $0) }
for recordName in recordNames {
recordIDs.append(CKRecordID(recordName: recordName))
}
let deleteOperation = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: recordIDs) let deleteOperation = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: recordIDs)
deleteOperation.modifyRecordsCompletionBlock = { (records, recordIds, error) in deleteOperation.modifyRecordsCompletionBlock = { (records, recordIds, error) in

@ -65,7 +65,7 @@ NS_ASSUME_NONNULL_BEGIN
// Writes db entities using protobufs into snapshot fragments. // Writes db entities using protobufs into snapshot fragments.
// Snapshot fragments are compressed (they compress _very well_, // Snapshot fragments are compressed (they compress _very well_,
// around 20x smaller) then encrypted. Ordering matters in // around 20x smaller) then encrypted. Ordering matters in
// snapshot contents (entities should we restored in the same // snapshot contents (entities should be restored in the same
// order they are serialized), so we are always careful to preserve // order they are serialized), so we are always careful to preserve
// ordering of entities within a snapshot AND ordering of snapshot // ordering of entities within a snapshot AND ordering of snapshot
// fragments within a bakckup. // fragments within a bakckup.
@ -80,7 +80,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) NSMutableArray<OWSBackupExportItem *> *exportItems; @property (nonatomic) NSMutableArray<OWSBackupExportItem *> *exportItems;
@property (nonatomic, nullable) OWSSignalServiceProtosBackupSnapshotBuilder *backupSnapshotBuilder; @property (nonatomic, nullable) OWSSignaliOSProtosBackupSnapshotBuilder *backupSnapshotBuilder;
@property (nonatomic) NSUInteger cachedItemCount; @property (nonatomic) NSUInteger cachedItemCount;
@ -113,7 +113,7 @@ NS_ASSUME_NONNULL_BEGIN
// use this state), but I think it'll be helpful to have around to future-proof // use this state), but I think it'll be helpful to have around to future-proof
// this work, help with debugging issue, etc. // this work, help with debugging issue, etc.
- (BOOL)writeObject:(TSYapDatabaseObject *)object - (BOOL)writeObject:(TSYapDatabaseObject *)object
entityType:(OWSSignalServiceProtosBackupSnapshotBackupEntityType)entityType entityType:(OWSSignaliOSProtosBackupSnapshotBackupEntityType)entityType
{ {
OWSAssert(object); OWSAssert(object);
@ -124,11 +124,11 @@ NS_ASSUME_NONNULL_BEGIN
} }
if (!self.backupSnapshotBuilder) { if (!self.backupSnapshotBuilder) {
self.backupSnapshotBuilder = [OWSSignalServiceProtosBackupSnapshotBuilder new]; self.backupSnapshotBuilder = [OWSSignaliOSProtosBackupSnapshotBuilder new];
} }
OWSSignalServiceProtosBackupSnapshotBackupEntityBuilder *entityBuilder = OWSSignaliOSProtosBackupSnapshotBackupEntityBuilder *entityBuilder =
[OWSSignalServiceProtosBackupSnapshotBackupEntityBuilder new]; [OWSSignaliOSProtosBackupSnapshotBackupEntityBuilder new];
[entityBuilder setType:entityType]; [entityBuilder setType:entityType];
[entityBuilder setEntityData:data]; [entityBuilder setEntityData:data];
@ -426,12 +426,12 @@ NS_ASSUME_NONNULL_BEGIN
NSString *, NSString *,
Class, Class,
EntityFilter _Nullable, EntityFilter _Nullable,
OWSSignalServiceProtosBackupSnapshotBackupEntityType); OWSSignaliOSProtosBackupSnapshotBackupEntityType);
ExportBlock exportEntities = ^(YapDatabaseReadTransaction *transaction, ExportBlock exportEntities = ^(YapDatabaseReadTransaction *transaction,
NSString *collection, NSString *collection,
Class expectedClass, Class expectedClass,
EntityFilter _Nullable filter, EntityFilter _Nullable filter,
OWSSignalServiceProtosBackupSnapshotBackupEntityType entityType) { OWSSignaliOSProtosBackupSnapshotBackupEntityType entityType) {
__block NSUInteger count = 0; __block NSUInteger count = 0;
[transaction [transaction
enumerateKeysAndObjectsInCollection:collection enumerateKeysAndObjectsInCollection:collection
@ -469,7 +469,7 @@ NS_ASSUME_NONNULL_BEGIN
[TSThread collection], [TSThread collection],
[TSThread class], [TSThread class],
nil, nil,
OWSSignalServiceProtosBackupSnapshotBackupEntityTypeThread); OWSSignaliOSProtosBackupSnapshotBackupEntityTypeThread);
if (aborted) { if (aborted) {
return; return;
} }
@ -499,7 +499,7 @@ NS_ASSUME_NONNULL_BEGIN
return YES; return YES;
}, },
OWSSignalServiceProtosBackupSnapshotBackupEntityTypeAttachment); OWSSignaliOSProtosBackupSnapshotBackupEntityTypeAttachment);
if (aborted) { if (aborted) {
return; return;
} }
@ -523,7 +523,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
return YES; return YES;
}, },
OWSSignalServiceProtosBackupSnapshotBackupEntityTypeInteraction); OWSSignaliOSProtosBackupSnapshotBackupEntityTypeInteraction);
if (aborted) { if (aborted) {
return; return;
} }
@ -532,7 +532,7 @@ NS_ASSUME_NONNULL_BEGIN
[OWSDatabaseMigration collection], [OWSDatabaseMigration collection],
[OWSDatabaseMigration class], [OWSDatabaseMigration class],
nil, nil,
OWSSignalServiceProtosBackupSnapshotBackupEntityTypeMigration); OWSSignaliOSProtosBackupSnapshotBackupEntityTypeMigration);
}]; }];
if (aborted || self.isComplete) { if (aborted || self.isComplete) {
@ -568,28 +568,36 @@ NS_ASSUME_NONNULL_BEGIN
self.savedDatabaseItems = [NSMutableArray new]; self.savedDatabaseItems = [NSMutableArray new];
self.savedAttachmentItems = [NSMutableArray new]; self.savedAttachmentItems = [NSMutableArray new];
unsigned long long totalFileSize = 0;
NSUInteger totalFileCount = 0;
{ {
unsigned long long totalFileSize = 0; unsigned long long databaseFileSize = 0;
for (OWSBackupExportItem *item in self.unsavedDatabaseItems) { for (OWSBackupExportItem *item in self.unsavedDatabaseItems) {
totalFileSize += [OWSFileSystem fileSizeOfPath:item.encryptedItem.filePath].unsignedLongLongValue; databaseFileSize += [OWSFileSystem fileSizeOfPath:item.encryptedItem.filePath].unsignedLongLongValue;
} }
DDLogInfo(@"%@ exporting %@: count: %zd, bytes: %llu.", DDLogInfo(@"%@ exporting %@: count: %zd, bytes: %llu.",
self.logTag, self.logTag,
@"database items", @"database items",
self.unsavedDatabaseItems.count, self.unsavedDatabaseItems.count,
totalFileSize); databaseFileSize);
totalFileSize += databaseFileSize;
totalFileCount += self.unsavedDatabaseItems.count;
} }
{ {
unsigned long long totalFileSize = 0; unsigned long long attachmentFileSize = 0;
for (OWSAttachmentExport *attachmentExport in self.unsavedAttachmentExports) { for (OWSAttachmentExport *attachmentExport in self.unsavedAttachmentExports) {
totalFileSize += [OWSFileSystem fileSizeOfPath:attachmentExport.attachmentFilePath].unsignedLongLongValue; attachmentFileSize +=
[OWSFileSystem fileSizeOfPath:attachmentExport.attachmentFilePath].unsignedLongLongValue;
} }
DDLogInfo(@"%@ exporting %@: count: %zd, bytes: %llu.", DDLogInfo(@"%@ exporting %@: count: %zd, bytes: %llu.",
self.logTag, self.logTag,
@"attachment items", @"attachment items",
self.unsavedAttachmentExports.count, self.unsavedAttachmentExports.count,
totalFileSize); attachmentFileSize);
totalFileSize += attachmentFileSize;
totalFileCount += self.unsavedAttachmentExports.count;
} }
DDLogInfo(@"%@ exporting %@: count: %zd, bytes: %llu.", self.logTag, @"all items", totalFileCount, totalFileSize);
[self saveNextFileToCloudWithCompletion:completion]; [self saveNextFileToCloudWithCompletion:completion];
} }

@ -13,6 +13,10 @@ NS_ASSUME_NONNULL_BEGIN
// TODO: // TODO:
static const NSUInteger kOWSBackupKeyLength = 32; static const NSUInteger kOWSBackupKeyLength = 32;
// LZMA algorithm significantly outperforms the other compressionlib options
// for our database snapshots and is a widely adopted standard.
static const compression_algorithm SignalCompressionAlgorithm = COMPRESSION_LZMA;
@implementation OWSBackupEncryptedItem @implementation OWSBackupEncryptedItem
@end @end
@ -196,9 +200,8 @@ static const NSUInteger kOWSBackupKeyLength = 32;
if (!dstBuffer) { if (!dstBuffer) {
return nil; return nil;
} }
// TODO: Should we use COMPRESSION_LZFSE? size_t dstLength = compression_encode_buffer(
size_t dstLength dstBuffer, dstBufferLength, srcBuffer, srcLength, NULL, SignalCompressionAlgorithm);
= compression_encode_buffer(dstBuffer, dstBufferLength, srcBuffer, srcLength, NULL, COMPRESSION_LZFSE);
NSData *compressedData = [NSData dataWithBytesNoCopy:dstBuffer length:dstLength freeWhenDone:YES]; NSData *compressedData = [NSData dataWithBytesNoCopy:dstBuffer length:dstLength freeWhenDone:YES];
DDLogVerbose(@"%@ compressed %zd -> %zd = %0.2f", DDLogVerbose(@"%@ compressed %zd -> %zd = %0.2f",
@ -233,9 +236,8 @@ static const NSUInteger kOWSBackupKeyLength = 32;
if (!dstBuffer) { if (!dstBuffer) {
return nil; return nil;
} }
// TODO: Should we use COMPRESSION_LZFSE? size_t dstLength = compression_decode_buffer(
size_t dstLength dstBuffer, dstBufferLength, srcBuffer, srcLength, NULL, SignalCompressionAlgorithm);
= compression_decode_buffer(dstBuffer, dstBufferLength, srcBuffer, srcLength, NULL, COMPRESSION_LZFSE);
NSData *decompressedData = [NSData dataWithBytesNoCopy:dstBuffer length:dstLength freeWhenDone:YES]; NSData *decompressedData = [NSData dataWithBytesNoCopy:dstBuffer length:dstLength freeWhenDone:YES];
OWSAssert(decompressedData.length == uncompressedDataLength); OWSAssert(decompressedData.length == uncompressedDataLength);
DDLogVerbose(@"%@ decompressed %zd -> %zd = %0.2f", DDLogVerbose(@"%@ decompressed %zd -> %zd = %0.2f",

@ -515,15 +515,15 @@ NSString *const kOWSBackup_ImportDatabaseKeySpec = @"kOWSBackup_ImportDatabaseKe
aborted = YES; aborted = YES;
return completion(NO); return completion(NO);
} }
OWSSignalServiceProtosBackupSnapshot *_Nullable entities = OWSSignaliOSProtosBackupSnapshot *_Nullable entities =
[OWSSignalServiceProtosBackupSnapshot parseFromData:uncompressedData]; [OWSSignaliOSProtosBackupSnapshot parseFromData:uncompressedData];
if (!entities || entities.entity.count < 1) { if (!entities || entities.entity.count < 1) {
DDLogError(@"%@ missing entities.", self.logTag); DDLogError(@"%@ missing entities.", self.logTag);
// Database-related errors are unrecoverable. // Database-related errors are unrecoverable.
aborted = YES; aborted = YES;
return completion(NO); return completion(NO);
} }
for (OWSSignalServiceProtosBackupSnapshotBackupEntity *entity in entities.entity) { for (OWSSignaliOSProtosBackupSnapshotBackupEntity *entity in entities.entity) {
NSData *_Nullable entityData = entity.entityData; NSData *_Nullable entityData = entity.entityData;
if (entityData.length < 1) { if (entityData.length < 1) {
DDLogError(@"%@ missing entity data.", self.logTag); DDLogError(@"%@ missing entity data.", self.logTag);

Loading…
Cancel
Save