Skip to content

Commit 0637922

Browse files
authored
Merge f5b6ec3 into master-4.0
2 parents 1244255 + f5b6ec3 commit 0637922

4 files changed

Lines changed: 61 additions & 36 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ and `SyncUser#retrieveInfoForUserAsync` which returns a `SyncUserInfo` with mode
5959

6060
### Bug Fixes
6161

62+
* The `compactOnLaunch` callback is no longer invoked if the Realm at that path is already open on other threads.
63+
6264
### Internal
6365

6466
* [ObjectServer] removed `ObjectServerUser` and its inner classes, in a step to reduce `SyncUser` complexity (#3741).

realm/realm-library/src/androidTest/java/io/realm/RealmTests.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
import java.util.concurrent.atomic.AtomicLong;
6565
import java.util.concurrent.atomic.AtomicReference;
6666

67+
import javax.annotation.Nullable;
68+
6769
import io.realm.entities.AllJavaTypes;
6870
import io.realm.entities.AllTypes;
6971
import io.realm.entities.AllTypesPrimaryKey;
@@ -1060,15 +1062,24 @@ public void compactRealm_onExternalStorage() {
10601062
Realm.deleteRealm(config);
10611063
}
10621064

1065+
private void populateTestRealmForCompact(Realm realm, int sizeInMB) {
1066+
byte[] oneMBData = new byte[1024 * 1024];
1067+
realm.beginTransaction();
1068+
for (int i = 0; i < sizeInMB; i++) {
1069+
realm.createObject(AllTypes.class).setColumnBinary(oneMBData);
1070+
}
1071+
realm.commitTransaction();
1072+
}
1073+
10631074
private Pair<Long, Long> populateTestRealmAndCompactOnLaunch(CompactOnLaunchCallback compactOnLaunch) {
1064-
return populateTestRealmAndCompactOnLaunch(compactOnLaunch, 100);
1075+
return populateTestRealmAndCompactOnLaunch(compactOnLaunch, 1);
10651076
}
10661077

1067-
private Pair<Long, Long> populateTestRealmAndCompactOnLaunch(CompactOnLaunchCallback compactOnLaunch, int objects) {
1078+
private Pair<Long, Long> populateTestRealmAndCompactOnLaunch(CompactOnLaunchCallback compactOnLaunch, int sizeInMB) {
10681079
final String REALM_NAME = "test.realm";
10691080
RealmConfiguration realmConfig = configFactory.createConfiguration(REALM_NAME);
10701081
Realm realm = Realm.getInstance(realmConfig);
1071-
populateTestRealm(realm, objects);
1082+
populateTestRealmForCompact(realm, sizeInMB);
10721083
realm.beginTransaction();
10731084
realm.deleteAll();
10741085
realm.commitTransaction();
@@ -1131,12 +1142,23 @@ public boolean shouldCompact(long totalBytes, long usedBytes) {
11311142
})
11321143
.build();
11331144
Realm realm = Realm.getInstance(realmConfig);
1145+
realm.close();
1146+
// WARNING: We need to init the schema first and close the Realm to make sure the relevant logic works in Object
1147+
// Store. See https://github.com/realm/realm-object-store/blob/master/src/shared_realm.cpp#L58
1148+
// Called once.
1149+
assertEquals(1, compactOnLaunchCount.get());
1150+
1151+
realm = Realm.getInstance(realmConfig);
1152+
// Called 2 more times. The PK table migration logic (the old PK bug) needs to open/close the Realm once.
1153+
assertEquals(3, compactOnLaunchCount.get());
11341154

11351155
Thread thread = new Thread(new Runnable() {
11361156
@Override
11371157
public void run() {
11381158
Realm bgRealm = Realm.getInstance(realmConfig);
11391159
bgRealm.close();
1160+
// compactOnLaunch should not be called anymore!
1161+
assertEquals(3, compactOnLaunchCount.get());
11401162
}
11411163
});
11421164
thread.start();
@@ -1149,8 +1171,6 @@ public void run() {
11491171

11501172
realm.close();
11511173

1152-
// FIXME: It should be 1. Current compactOnLaunch is called each time a Realm is opened on a new thread.
1153-
assertNotEquals(1, compactOnLaunchCount.get());
11541174
assertEquals(3, compactOnLaunchCount.get());
11551175
}
11561176

@@ -1162,7 +1182,7 @@ public boolean shouldCompact(long totalBytes, long usedBytes) {
11621182
final long thresholdSize = 50 * 1024 * 1024;
11631183
return (totalBytes > thresholdSize) && (((double) usedBytes / (double) totalBytes) < 0.5);
11641184
}
1165-
}, 100);
1185+
}, 1);
11661186
final long thresholdSize = 50 * 1024 * 1024;
11671187
assertTrue(results.first < thresholdSize);
11681188
assertEquals(results.first, results.second);
@@ -1195,7 +1215,7 @@ public boolean shouldCompact(long totalBytes, long usedBytes) {
11951215

11961216
@Test
11971217
public void defaultCompactOnLaunch() throws IOException {
1198-
Pair<Long, Long> results = populateTestRealmAndCompactOnLaunch(null, 30000);
1218+
Pair<Long, Long> results = populateTestRealmAndCompactOnLaunch(null, 50);
11991219
final long thresholdSize = 50 * 1024 * 1024;
12001220
assertTrue(results.first > thresholdSize);
12011221
assertTrue(results.first > results.second);
@@ -1215,7 +1235,7 @@ public void defaultCompactOnLaunch_onlyCallback() {
12151235

12161236
@Test
12171237
public void defaultCompactOnLaunch_insufficientAmount() throws IOException {
1218-
Pair<Long, Long> results = populateTestRealmAndCompactOnLaunch(null, 100);
1238+
Pair<Long, Long> results = populateTestRealmAndCompactOnLaunch(null, 1);
12191239
final long thresholdSize = 50 * 1024 * 1024;
12201240
assertTrue(results.first < thresholdSize);
12211241
assertEquals(results.first, results.second);

realm/realm-library/src/main/java/io/realm/DefaultCompactOnLaunchCallback.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package io.realm;
1818

19-
import io.realm.log.RealmLog;
20-
2119
/**
2220
* The default implementation for determining if a file should be compacted or not. This implementation will only
2321
* trigger if the file is above 50 MB and more than 50% can be reclaimed.

realm/realm-library/src/main/java/io/realm/RealmCache.java

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -292,35 +292,40 @@ private synchronized <E extends BaseRealm> E doCreateRealmOrGetFromCache(RealmCo
292292

293293
SharedRealm sharedRealm = null;
294294
try {
295-
sharedRealm = SharedRealm.getInstance(configuration);
296-
297-
// If waitForInitialRemoteData() was enabled, we need to make sure that all data is downloaded
298-
// before proceeding. We need to open the Realm instance first to start any potential underlying
299-
// SyncSession so this will work. TODO: This needs to be decoupled.
300-
if (!fileExists) {
301-
try {
302-
ObjectServerFacade.getSyncFacadeIfPossible().downloadRemoteChanges(configuration);
303-
} catch (Throwable t) {
304-
// If an error happened while downloading initial data, we need to reset the file so we can
305-
// download it again on the next attempt.
306-
// Realm.deleteRealm() is under the same lock as this method and globalCount is still 0, so
307-
// this should be safe.
308-
sharedRealm.close();
309-
sharedRealm = null;
310-
Realm.deleteRealm(configuration);
311-
throw t;
295+
if (configuration.isSyncConfiguration()) {
296+
// If waitForInitialRemoteData() was enabled, we need to make sure that all data is downloaded
297+
// before proceeding. We need to open the Realm instance first to start any potential underlying
298+
// SyncSession so this will work. TODO: This needs to be decoupled.
299+
if (!fileExists) {
300+
sharedRealm = SharedRealm.getInstance(configuration);
301+
try {
302+
ObjectServerFacade.getSyncFacadeIfPossible().downloadRemoteChanges(configuration);
303+
} catch (Throwable t) {
304+
// If an error happened while downloading initial data, we need to reset the file so we can
305+
// download it again on the next attempt.
306+
// Realm.deleteRealm() is under the same lock as this method and globalCount is still 0, so
307+
// this should be safe.
308+
sharedRealm.close();
309+
sharedRealm = null;
310+
Realm.deleteRealm(configuration);
311+
throw t;
312+
}
312313
}
313-
}
314-
315-
if (Table.primaryKeyTableNeedsMigration(sharedRealm)) {
316-
sharedRealm.beginTransaction();
317-
if (Table.migratePrimaryKeyTableIfNeeded(sharedRealm)) {
318-
sharedRealm.commitTransaction();
319-
} else {
320-
sharedRealm.cancelTransaction();
314+
} else {
315+
if (fileExists) {
316+
// Primary key problem only exists before we release sync.
317+
sharedRealm = SharedRealm.getInstance(configuration);
318+
319+
if (Table.primaryKeyTableNeedsMigration(sharedRealm)) {
320+
sharedRealm.beginTransaction();
321+
if (Table.migratePrimaryKeyTableIfNeeded(sharedRealm)) {
322+
sharedRealm.commitTransaction();
323+
} else {
324+
sharedRealm.cancelTransaction();
325+
}
326+
}
321327
}
322328
}
323-
324329
} finally {
325330
if (sharedRealm != null) {
326331
sharedRealm.close();

0 commit comments

Comments
 (0)