public async Task ObjectForPrimaryKey_Parallel_SingleRealmThread() { await GeneratePerfRangesForBlock2(async (cache, size, keys) => { var st = new Stopwatch(); var toFetch = Enumerable.Range(0, size) .Select(_ => keys[prng.Next(0, keys.Count - 1)]) .ToArray(); await Task.Run(() => { st.Start(); using (var realmThread = new RealmThread(cache.Config)) { Parallel.ForEach( toFetch, key => { realmThread.BeginInvoke(threadSafeRealm => { var record = threadSafeRealm.ObjectForPrimaryKey <KeyValueRecord>(key); Assert.NotNull(record); }); }); } st.Stop(); }); return(st.ElapsedMilliseconds); }); }
public async Task Manage_OneTrans_BeginInvoke() { await GeneratePerfRangesForRealm(async (cache, size) => { var toWrite = PerfHelper.GenerateRandomDatabaseContents(size); var st = new Stopwatch(); st.Start(); await Task.Run(() => { using (var realmThread = new RealmThread(cache.Config)) { realmThread.BeginTransaction(); realmThread.BeginInvoke((threadSafeRealm) => { foreach (var kvp in toWrite) { var obj = new KeyValueRecord(); obj.Key = kvp.Key; obj.Value = kvp.Value; threadSafeRealm.Add(obj); } }); realmThread.CommitTransaction(); } }); st.Stop(); return(st.ElapsedMilliseconds); }); }
public async Task Manage_updateTrue_OneTrans() { await GeneratePerfRangesForRealm(async (cache, size) => { var toWrite = PerfHelper.GenerateRandomDatabaseContents(size); var st = new Stopwatch(); st.Start(); using (var realmThread = new RealmThread(cache.Config)) { realmThread.Invoke((realm) => { realm.Write(() => { foreach (var kvp in toWrite) { var c = new KeyValueRecord { Key = kvp.Key, Value = kvp.Value }; realm.Add(c, update: true); } }); }); } st.Stop(); await Task.Delay(1); // cheap hack return(st.ElapsedMilliseconds); }); }
public void ThreadInvoke_Transaction_ViaCapturedVariable() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { Transaction trans = null; t.Invoke(r => { trans = r.BeginWrite(); }); t.Invoke(r => { var obj = new KeyValueRecord(); obj.Key = "key"; r.Add(obj); }); fixture.Refresh(); Assert.Null(fixture.Find <KeyValueRecord>("key")); // Should not be available yet t.Invoke(r => { if (trans != null) { trans.Commit(); } }); fixture.Refresh(); Assert.NotNull(fixture.Find <KeyValueRecord>("key")); // Should now be available } }
public async Task ThreadInvokeAsync() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { await t.InvokeAsync(async r => { await r.WriteAsync((aNewRealm) => { var obj = new KeyValueRecord(); obj.Key = "key"; aNewRealm.Add(obj); }); }); t.Invoke(r => { Assert.NotNull(r.Find <KeyValueRecord>("key")); }); fixture.Refresh(); Assert.NotNull(fixture.Find <KeyValueRecord>("key")); } }
public async Task Manage_OneTrans_InvokeAsync() { await GeneratePerfRangesForRealm(async (cache, size) => { var toWrite = PerfHelper.GenerateRandomDatabaseContents(size); var st = new Stopwatch(); st.Start(); using (var realmThread = new RealmThread(cache.Config)) { await realmThread.InvokeAsync(async(threadSafeRealm) => { // Mock something using an await in this lamba await Task.FromResult(true); threadSafeRealm.Write(() => { foreach (var kvp in toWrite) { var obj = new KeyValueRecord(); obj.Key = kvp.Key; obj.Value = kvp.Value; threadSafeRealm.Add(obj); } }); }); } st.Stop(); return(st.ElapsedMilliseconds); }); }
public async Task ObjectForPrimaryKey_Sequential_MultiInstance_Via_Task() { await GeneratePerfRangesForBlock2(async (cache, size, keys) => { var st = new Stopwatch(); var toFetch = Enumerable.Range(0, size) .Select(_ => keys[prng.Next(0, keys.Count - 1)]) .ToArray(); await Task.Run(async() => { st.Start(); foreach (var key in toFetch) { await Task.Run(() => { using (var localRealm = RealmThread.GetInstance(cache.Config)) { localRealm.Refresh(); var obj = localRealm.Find <KeyValueRecord>(key); Assert.NotNull(obj); Assert.Equal(key, obj.Key); } }); } st.Stop(); }); return(st.ElapsedMilliseconds); }); }
public async Task ThreadInvokeAsync_SingleContinuation() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { await t.InvokeAsync(async r => { await Task.FromResult(true); // Simulate some Task, i.e. a httpclient request.... r.Write(() => { var obj = new KeyValueRecord(); obj.Key = "key"; r.Add(obj); }); }); t.Invoke(r => { Assert.NotNull(r.Find <KeyValueRecord>("key")); }); fixture.Refresh(); Assert.NotNull(fixture.Find <KeyValueRecord>("key")); } }
protected static async Task <List <string> > GenerateRealmDB(Realms.Realm targetCache, int size) { var ret = new List <string>(); // Write out in groups of 4096 while (size > 0) { var toWriteSize = Math.Min(4096, size); var toWrite = PerfHelper.GenerateRandomDatabaseContents(toWriteSize); using (var rt = new RealmThread(targetCache.Config)) { await rt.InvokeAsync(async(Realms.Realm arg) => { await arg.WriteAsync((r) => { foreach (var item in toWrite) { var c = new KeyValueRecord { Key = item.Key, Value = item.Value }; r.Add(c); // update: false } }); }); } foreach (var k in toWrite.Keys) { ret.Add(k); } size -= toWrite.Count; } return(ret); }
protected async Task GeneratePerfRangesForRealm(Func <Realms.Realm, int, Task <long> > block) { results = new Dictionary <int, long>(); dbName = default(string); var dirPath = default(string); using (Utility.WithEmptyDirectory(out dirPath)) using (var cache = RealmThread.GetInstance(Path.Combine(dirPath, "realm.db"))) { using (var realmThread = new RealmThread(cache.Config)) { realmThread.Invoke((obj) => { obj.Write(() => { obj.RemoveAll(); }); }); } dbName = "Realm"; foreach (var size in PerfHelper.GetPerfRanges()) { results[size] = await block(cache, size); } } }
async Task <Realms.Realm> GenerateRealmDB(string path) { path = path ?? IntegrationTestHelper.GetIntegrationTestRootDirectory(); var giantDbSize = PerfHelper.GetPerfRanges().Last(); var config = new RealmConfiguration(Path.Combine(path, "realm.db")) { ObjectClasses = new Type[] { typeof(KeyValueRecord) } }; var cache = RealmThread.GetInstance(config); var keys = cache.All <KeyValueRecord>().Count(); if (keys == giantDbSize) { return(cache); } using (var realmThread = new RealmThread(cache.Config)) { realmThread.Invoke((obj) => { obj.Write(() => { obj.RemoveAll(); }); }); } await GenerateRealmDB(cache, giantDbSize); return(cache); }
public async Task GeneratePerfRangesForBlock2(Func <Realms.Realm, int, List <string>, Task <long> > block) { results = new Dictionary <int, long>(); dbName = default(string); var dirPath = default(string); using (Utility.WithEmptyDirectory(out dirPath)) using (var cache = await GenerateRealmDB(dirPath)) { List <string> keys = null; using (var realmThread = new RealmThread(cache.Config)) { realmThread.Invoke((r) => { r.Write(() => { keys = r.All <KeyValueRecord>().ToList().Select(x => x.Key).ToList(); }); }); } dbName = dbName ?? cache.GetType().Name; foreach (var size in PerfHelper.GetPerfRanges()) { results[size] = await block(cache, size, keys.ToList()); } } }
public async Task LinqWhereKey_Sequential_MultiInstance_Via_Task() { await GeneratePerfRangesForBlock2(async (cache, size, keys) => { var st = new Stopwatch(); var toFetch = Enumerable.Range(0, size) .Select(_ => keys[prng.Next(0, keys.Count - 1)]) .ToArray(); await Task.Run(async() => { st.Start(); foreach (var key in toFetch) { await Task.Run(() => { using (var localRealm = RealmThread.GetInstance(cache.Config)) { var objs = localRealm.All <KeyValueRecord>().Where((KeyValueRecord c) => c.Key == key); Assert.Equal(1, objs.Count()); } }); } st.Stop(); }); return(st.ElapsedMilliseconds); }); }
public void ThreadInvoke_InTransaction_AutoCommit() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) { using (var realmThread = new RealmThread(fixture.Config, true)) { realmThread.BeginTransaction(); var keyValueRecord = new KeyValueRecord(); // a captured variable realmThread.Invoke(r => { var obj = new KeyValueRecord(); obj.Key = "key"; r.Add(obj); keyValueRecord.Key = obj.Key; }); Console.WriteLine($"{keyValueRecord.Key}:{keyValueRecord.Value}"); Assert.Equal("key", keyValueRecord.Key); } fixture.Refresh(); Assert.NotNull(fixture.Find <KeyValueRecord>("key")); } }
public async Task ObjectForPrimaryKey_Sequential() { await GeneratePerfRangesForBlock2(async (cache, size, keys) => { var st = new Stopwatch(); var toFetch = Enumerable.Range(0, size) .Select(_ => keys[prng.Next(0, keys.Count - 1)]) .ToArray(); await Task.Run(() => { st.Start(); var realmThread = new RealmThread(cache.Config); realmThread.BeginInvoke(threadSafeRealm => { foreach (var v in toFetch) { threadSafeRealm.ObjectForPrimaryKey <KeyValueRecord>(v); } }); realmThread.Dispose(); st.Stop(); }); return(st.ElapsedMilliseconds); }); }
public async Task Write_Read_Parallel_On_Different_Threads() { await GeneratePerfRangesForRealm(async (cache, size) => { await cache.WriteAsync((obj) => { obj.RemoveAll(); }); var toWrite = PerfHelper.GenerateRandomDatabaseContents(size); var st = new Stopwatch(); st.Start(); await Task.Run(() => { using (var blockingQueue = new BlockingCollection <string>()) using (var realmThreadWrite = new RealmThread(cache.Config)) using (var realmThreadRead = new RealmThread(cache.Config)) { Parallel.Invoke(() => { realmThreadWrite.Invoke(threadSafeWriteRealm => { foreach (var kvp in toWrite) { // Individual record write transactions so the other RealmThread can read asap threadSafeWriteRealm.Write(() => { var obj = threadSafeWriteRealm.CreateObject(typeof(KeyValueRecord).Name); obj.Key = kvp.Key; obj.Value = kvp.Value; }); blockingQueue.Add(kvp.Key); } blockingQueue.CompleteAdding(); }); }, () => { realmThreadRead.Invoke((threadSafeReadRealm) => { foreach (var key in blockingQueue.GetConsumingEnumerable()) { // Refresh() is automatically called at the beginning of each BeginInvoke, // so if we are within the RealmPump block and need to see the latest changes // from other Realm instances, call Refresh manually threadSafeReadRealm.Refresh(); var record = threadSafeReadRealm.ObjectForPrimaryKey <KeyValueRecord>(key); Assert.NotNull(record); Assert.Equal(key, record.Key); } }); }); } }); st.Stop(); return(st.ElapsedMilliseconds); }); }
public void ThreadCreate() { var callingThread = Thread.CurrentThread.ManagedThreadId; string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { Assert.NotEqual(callingThread, t.ManagedThreadId); } }
public void ThreadInvoke_InTransaction() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { Assert.False(t.InTransaction); t.BeginTransaction(); Assert.True(t.InTransaction); } }
public async Task ObjectForPrimaryKey_Parallel() { await GeneratePerfRangesForBlock2(async (cache, size, keys) => { var st = new Stopwatch(); var toFetch = Enumerable.Range(0, size) .Select(_ => keys[prng.Next(0, keys.Count - 1)]) .ToArray(); st.Start(); // The following code crashes with "Invalid IL code" on iOS(?), Android not tested... // Invalid IL code in Tests.Performance.RealmRead ///< Sequential_ObjectForPrimaryKey_Parallel > c__async22 ///< Sequential_ObjectForPrimaryKey_Parallel > c__AnonStorey23:<> m__1(string): IL_0008: stfld 0x04000443 //at System.Reactive.Linq.ObservableImpl.Select`2 + _[TSource, TResult].OnNext(TSource value)[0x00008] in < d0067ed104ac455987b6feb85f80156b >:0 //var scheduler = System.Reactive.Concurrency.TaskPoolScheduler.Default; //await toFetch // .ToObservable(scheduler) // .Select(key => Observable.Defer(() => GetRecordViaPrimaryKey(cache, key))) // .ToArray(); await Task.Run(() => { Parallel.ForEach( toFetch, new ParallelOptions { MaxDegreeOfParallelism = 4 }, key => { using (var localRealm = RealmThread.GetInstance(cache.Config)) { localRealm.Refresh(); var obj = localRealm.Find <KeyValueRecord>(key); Assert.NotNull(obj); Assert.Equal(key, obj.Key); } } ); }); st.Stop(); return(st.ElapsedMilliseconds); }); }
protected async Task GeneratePerfRangesForRealm(Func <Realms.Realm, int, Task <long> > block) { results = new Dictionary <int, long>(); dbName = default(string); var dirPath = default(string); using (Utility.WithEmptyDirectory(out dirPath)) using (var cache = RealmThread.GetInstance(Path.Combine(dirPath, "perf.realm"))) { dbName = "Realm"; foreach (var size in PerfHelper.GetPerfRanges()) { results[size] = await block(cache, size); } } }
public void ThreadInvoke_InTransaction_AutoRollback() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) { using (var t = new RealmThread(fixture.Config, false)) { t.BeginTransaction(); t.Invoke(r => { var obj = r.CreateObject <KeyValueRecord>(); obj.Key = "key"; }); } fixture.Refresh(); Assert.Null(fixture.ObjectForPrimaryKey <KeyValueRecord>("key")); } }
public void ThreadInvoke_Transaction_Begin_RollBack() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { t.BeginTransaction(); t.Invoke(r => { var obj = r.CreateObject <KeyValueRecord>(); obj.Key = "key"; }); fixture.Refresh(); Assert.Null(fixture.ObjectForPrimaryKey <KeyValueRecord>("key")); // Should not be available yet t.RollbackTransaction(); fixture.Refresh(); Assert.Null(fixture.ObjectForPrimaryKey <KeyValueRecord>("key")); // Should not be available } }
public void ThreadInvoke_AutoRefresh() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { // Add a record on the current thread fixture.Write(() => { var obj = fixture.CreateObject <KeyValueRecord>(); obj.Key = "key"; }); t.Invoke(r => { // Before each action a Refresh is performed so the record should be automaticially available to this thread Assert.NotNull(r.ObjectForPrimaryKey <KeyValueRecord>("key")); }); } }
public void ThreadInvoke() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { // Add a record on a thread t.Invoke(r => { r.Write(() => { var obj = r.CreateObject <KeyValueRecord>(); obj.Key = "key"; }); }); fixture.Refresh(); Assert.NotNull(fixture.ObjectForPrimaryKey <KeyValueRecord>("key")); } }
public async Task ThreadInvokeAsync_MultipleContinuations() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { await t.InvokeAsync(async r => { await Task.FromResult(true); // Simulate some Task, i.e. a httpclient request.... r.Write(() => { var obj = r.CreateObject <KeyValueRecord>(); obj.Key = "key"; }); await Task.Delay(1); r.Write(() => { var obj = r.CreateObject <KeyValueRecord>(); obj.Key = "key2"; }); await Task.Delay(1); r.Write(() => { var obj = r.CreateObject <KeyValueRecord>(); obj.Key = "key3"; }); }); t.Invoke(r => { Assert.NotNull(r.ObjectForPrimaryKey <KeyValueRecord>("key")); }); fixture.Refresh(); Assert.NotNull(fixture.ObjectForPrimaryKey <KeyValueRecord>("key")); } }
public void ThreadBeginInvoke() { string path; using (Utility.WithEmptyDirectory(out path)) using (var fixture = CreateRealmsInstance(path)) using (var t = new RealmThread(fixture.Config)) { t.BeginInvoke(r => { r.Write(() => { var obj = new KeyValueRecord(); obj.Key = "key"; r.Add(obj); }); }); t.Invoke(r => { Assert.NotNull(r.Find <KeyValueRecord>("key")); }); } }