Skip to content

Commit

Permalink
Merge pull request #4755 from realm/jp-compact-on-launch
Browse files Browse the repository at this point in the history
Expose a block to determine if the Realm should be compacted on launch
  • Loading branch information
jpsim authored Apr 17, 2017
2 parents 8f13f40 + 39020f4 commit 5f102a3
Show file tree
Hide file tree
Showing 13 changed files with 462 additions and 32 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ x.x.x Release notes (yyyy-MM-dd)
background thread before dispatching to the given queue. In addition,
synchronized Realms wait for all remote content available at the time the
operation began to be downloaded and available locally.
* Add `shouldCompactOnLaunch` block property when configuring a Realm to
determine if it should be compacted before being returned.
* Speed up case-insensitive queries on indexed string properties.
* Add RLMResults's collection aggregate methods to RLMArray.
* Add support for calling the aggregate methods on unmanaged Lists.
Expand Down
10 changes: 10 additions & 0 deletions Realm.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,12 @@
E86E61241D91E4E200DC2419 /* RLMTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = E81A1FC51955FE0100FDED82 /* RLMTestCase.m */; };
E8917598197A1B350068ACC6 /* UnicodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E8917597197A1B350068ACC6 /* UnicodeTests.m */; };
E8917599197A1B350068ACC6 /* UnicodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E8917597197A1B350068ACC6 /* UnicodeTests.m */; };
E8AE7C261EA436F800CDFF9A /* CompactionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8AE7C251EA436F800CDFF9A /* CompactionTests.swift */; };
E8BF67FC1C24D07100E591CD /* SwiftVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8BF67FB1C24D07100E591CD /* SwiftVersion.swift */; };
E8C6EAF41DD66C0C00EC1A03 /* RLMSyncUtil_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A1C6E241D3FFCF70077B6E7 /* RLMSyncUtil_Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
E8C6EAF51DD66C0C00EC1A03 /* RLMSyncUtil_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A1C6E241D3FFCF70077B6E7 /* RLMSyncUtil_Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
E8DA16F81E81210D0055141C /* CompactionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E8DA16F71E81210D0055141C /* CompactionTests.m */; };
E8DA16F91E81210D0055141C /* CompactionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E8DA16F71E81210D0055141C /* CompactionTests.m */; };
E8FD2E381D93345100569F10 /* keychain_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A64CA891D8763B400BC0F9B /* keychain_helper.cpp */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -902,10 +905,12 @@
E8917597197A1B350068ACC6 /* UnicodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UnicodeTests.m; sourceTree = "<group>"; };
E891759A197A1B600068ACC6 /* SwiftUnicodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftUnicodeTests.swift; sourceTree = "<group>"; };
E8951F01196C96DE00D6461C /* RLMRealm_Dynamic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RLMRealm_Dynamic.h; sourceTree = "<group>"; };
E8AE7C251EA436F800CDFF9A /* CompactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompactionTests.swift; sourceTree = "<group>"; };
E8BF67FB1C24D07100E591CD /* SwiftVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftVersion.swift; sourceTree = "<group>"; };
E8C6EAEF1DD65B8C00EC1A03 /* RLMSyncPermissionChange_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RLMSyncPermissionChange_Private.h; sourceTree = "<group>"; };
E8D89B9D1955FC6D00CF2B9A /* Realm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Realm.h; sourceTree = "<group>"; };
E8D89BA31955FC6D00CF2B9A /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
E8DA16F71E81210D0055141C /* CompactionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CompactionTests.m; sourceTree = "<group>"; };
E8F8D90B196CB8DD00475368 /* SwiftTestObjects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftTestObjects.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -1235,6 +1240,7 @@
isa = PBXGroup;
children = (
5D6610291BE98DAA0021E04F /* Supporting Files */,
E8AE7C251EA436F800CDFF9A /* CompactionTests.swift */,
5D660FFF1BE98D880021E04F /* KVOTests.swift */,
5D6610001BE98D880021E04F /* ListTests.swift */,
5D6610011BE98D880021E04F /* MigrationTests.swift */,
Expand Down Expand Up @@ -1310,6 +1316,7 @@
children = (
E81A1FB81955FE0100FDED82 /* ArrayPropertyTests.m */,
3F7556731BE95A050058BC7E /* AsyncTests.mm */,
E8DA16F71E81210D0055141C /* CompactionTests.m */,
E81A1FBA1955FE0100FDED82 /* DynamicTests.m */,
021A882F1AAFB5BE00EEAC84 /* EncryptionTests.mm */,
E81A1FBB1955FE0100FDED82 /* EnumeratorTests.m */,
Expand Down Expand Up @@ -2267,6 +2274,7 @@
5D6610211BE98D880021E04F /* RealmTests.swift in Sources */,
5D6610221BE98D880021E04F /* SchemaTests.swift in Sources */,
5D6610231BE98D880021E04F /* SortDescriptorTests.swift in Sources */,
E8AE7C261EA436F800CDFF9A /* CompactionTests.swift in Sources */,
5D6610241BE98D880021E04F /* SwiftLinkTests.swift in Sources */,
5D6610251BE98D880021E04F /* SwiftTestObjects.swift in Sources */,
5D6610261BE98D880021E04F /* SwiftUnicodeTests.swift in Sources */,
Expand Down Expand Up @@ -2406,6 +2414,7 @@
3F8DCA7719930FCB0008BD7F /* SwiftArrayTests.swift in Sources */,
3F8DCA7819930FCB0008BD7F /* SwiftDynamicTests.swift in Sources */,
3F8DCA7919930FCB0008BD7F /* SwiftLinkTests.swift in Sources */,
E8DA16F91E81210D0055141C /* CompactionTests.m in Sources */,
3F8DCA7B19930FCB0008BD7F /* SwiftObjectInterfaceTests.swift in Sources */,
3F8DCA7C19930FCB0008BD7F /* SwiftPropertyTypeTest.swift in Sources */,
3F8DCA7D19930FCB0008BD7F /* SwiftRealmTests.swift in Sources */,
Expand Down Expand Up @@ -2434,6 +2443,7 @@
3F2E66641CA0BA11004761D5 /* NotificationTests.m in Sources */,
3FEB383F1E70AC8800F22712 /* ObjectCreationTests.mm in Sources */,
E81A1FE11955FE0100FDED82 /* ObjectInterfaceTests.m in Sources */,
E8DA16F81E81210D0055141C /* CompactionTests.m in Sources */,
021A88361AAFB5CD00EEAC84 /* ObjectSchemaTests.m in Sources */,
E81A1FE31955FE0100FDED82 /* ObjectTests.m in Sources */,
5D03FB1F1E0DAFBA007D53EA /* PredicateUtilTests.mm in Sources */,
Expand Down
14 changes: 14 additions & 0 deletions Realm/ObjectServerTests/RLMObjectServerTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1716,4 +1716,18 @@ - (void)testPermissionOfferResponseTokenNotExist {
[token stop];
}

#pragma mark - Validation

- (void)testCompactOnLaunchCannotBeSet {
RLMSyncUser *user = [self logInUserForCredentials:[RLMObjectServerTests basicCredentialsWithName:ACCOUNT_NAME()
register:YES]
server:[RLMObjectServerTests authServerURL]];
RLMSyncConfiguration *syncConfig = [[RLMSyncConfiguration alloc] initWithUser:user realmURL:REALM_URL()];

RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
configuration.syncConfiguration = syncConfig;
RLMAssertThrowsWithReasonMatching(configuration.shouldCompactOnLaunch = ^BOOL(NSUInteger, NSUInteger){ return NO; },
@"Cannot set `shouldCompactOnLaunch` when `syncConfiguration` is set.");
}

@end
2 changes: 1 addition & 1 deletion Realm/ObjectStore
3 changes: 3 additions & 0 deletions Realm/RLMRealmConfiguration+Sync.mm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ @implementation RLMRealmConfiguration (Sync)
#pragma mark - API

- (void)setSyncConfiguration:(RLMSyncConfiguration *)syncConfiguration {
if (self.config.should_compact_on_launch_function) {
@throw RLMException(@"Cannot set `syncConfiguration` when `shouldCompactOnLaunch` is set.");
}
RLMSyncUser *user = syncConfiguration.user;
if (user.state == RLMSyncUserStateError) {
@throw RLMException(@"Cannot set a sync configuration which has an errored-out user.");
Expand Down
22 changes: 22 additions & 0 deletions Realm/RLMRealmConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@

NS_ASSUME_NONNULL_BEGIN

/**
A block called when opening a Realm for the first time during the life
of a process to determine if it should be compacted before being returned
to the user. It is passed the total file size (data + free space) and the total
bytes used by data in the file.
Return `YES` to indicate that an attempt to compact the file should be made.
The compaction will be skipped if another process is accessing it.
*/
typedef BOOL (^RLMShouldCompactOnLaunchBlock)(NSUInteger totalBytes, NSUInteger bytesUsed);

/**
An `RLMRealmConfiguration` instance describes the different options used to
create an instance of a Realm.
Expand Down Expand Up @@ -91,6 +102,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic) BOOL deleteRealmIfMigrationNeeded;

/**
A block called when opening a Realm for the first time during the life
of a process to determine if it should be compacted before being returned
to the user. It is passed the total file size (data + free space) and the total
bytes used by data in the file.
Return `YES` to indicate that an attempt to compact the file should be made.
The compaction will be skipped if another process is accessing it.
*/
@property (nonatomic, copy, nullable) RLMShouldCompactOnLaunchBlock shouldCompactOnLaunch;

/// The classes managed by the Realm.
@property (nonatomic, copy, nullable) NSArray *objectClasses;

Expand Down
21 changes: 21 additions & 0 deletions Realm/RLMRealmConfiguration.mm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@"schemaVersion",
@"migrationBlock",
@"deleteRealmIfMigrationNeeded",
@"shouldCompactOnLaunch",
@"dynamic",
@"customSchema",
};
Expand Down Expand Up @@ -113,6 +114,7 @@ - (instancetype)copyWithZone:(NSZone *)zone {
configuration->_cache = _cache;
configuration->_dynamic = _dynamic;
configuration->_migrationBlock = _migrationBlock;
configuration->_shouldCompactOnLaunch = _shouldCompactOnLaunch;
configuration->_customSchema = _customSchema;
return configuration;
}
Expand Down Expand Up @@ -207,6 +209,8 @@ - (void)setReadOnly:(BOOL)readOnly {
if (readOnly) {
if (self.deleteRealmIfMigrationNeeded) {
@throw RLMException(@"Cannot set `readOnly` when `deleteRealmIfMigrationNeeded` is set.");
} else if (self.shouldCompactOnLaunch) {
@throw RLMException(@"Cannot set `readOnly` when `shouldCompactOnLaunch` is set.");
}
_config.schema_mode = realm::SchemaMode::ReadOnly;
}
Expand Down Expand Up @@ -275,4 +279,21 @@ - (NSString *)pathOnDisk {
return @(_config.path.c_str());
}

- (void)setShouldCompactOnLaunch:(RLMShouldCompactOnLaunchBlock)shouldCompactOnLaunch {
if (shouldCompactOnLaunch) {
if (self.readOnly) {
@throw RLMException(@"Cannot set `shouldCompactOnLaunch` when `readOnly` is set.");
} else if (_config.sync_config) {
@throw RLMException(@"Cannot set `shouldCompactOnLaunch` when `syncConfiguration` is set.");
}
_config.should_compact_on_launch_function = [=](size_t totalBytes, size_t usedBytes) {
return shouldCompactOnLaunch(totalBytes, usedBytes);
};
}
else {
_config.should_compact_on_launch_function = nullptr;
}
_shouldCompactOnLaunch = shouldCompactOnLaunch;
}

@end
Loading

0 comments on commit 5f102a3

Please sign in to comment.