public void TestPerformance() { var jsonData = File.ReadAllBytes(JsonFilePath); FLError error; var unmanagedData = Marshal.AllocHGlobal(jsonData.Length); Marshal.Copy(jsonData, 0, unmanagedData, jsonData.Length); var slice = new FLSlice(unmanagedData.ToPointer(), (ulong)jsonData.Length); var fleeceData = NativeRaw.FLData_ConvertJSON(slice, &error); var root = Native.FLValue_AsArray(NativeRaw.FLValue_FromData(fleeceData)); RunTestVariants(() => { uint numDocs; { var st = Stopwatch.StartNew(); numDocs = InsertDocs(root); numDocs.Should().Be(12188, "because otherwise an incorrect number of documents was inserted"); st.PrintReport("Writing docs", numDocs, "doc"); } { var st = Stopwatch.StartNew(); IndexViews(); st.PrintReport("Indexing Albums/Artists views", numDocs, "doc"); } { var st = Stopwatch.StartNew(); IndexTracksView(); st.PrintReport("Indexing Tracks view", numDocs, "doc"); } { var st = Stopwatch.StartNew(); var context = new TotalContext(); var reduce = new C4ManagedReduceFunction(TotalAccumulate, TotalReduce, context); var numArtists = QueryGrouped(_artistsView, reduce.Native); reduce.Dispose(); numArtists.Should().Be(1141, "because otherwise the query returned incorrect information"); st.PrintReport("Grouped query of Artist view", numDocs, "doc"); } }); Marshal.FreeHGlobal(unmanagedData); }
protected uint ImportJSONFile(string path, string idPrefix, TimeSpan timeout, bool verbose) { WriteLine($"Reading {path} ..."); var st = Stopwatch.StartNew(); #if WINDOWS_UWP var url = $"ms-appx:///Assets/{path}"; var file = Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri(url)) .AsTask() .ConfigureAwait(false) .GetAwaiter() .GetResult(); var buffer = Windows.Storage.FileIO.ReadBufferAsync(file).AsTask().ConfigureAwait(false).GetAwaiter() .GetResult(); var jsonData = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(buffer); #elif __ANDROID__ var ctx = global::Couchbase.Lite.Tests.Android.MainActivity.ActivityContext; byte[] jsonData; using (var stream = ctx.Assets.Open(path)) using (var ms = new MemoryStream()) { stream.CopyTo(ms); jsonData = ms.ToArray(); } #elif __IOS__ var bundlePath = ios::Foundation.NSBundle.MainBundle.PathForResource(Path.GetFileNameWithoutExtension(path), Path.GetExtension(path)); byte[] jsonData; using (var stream = File.Open(bundlePath, FileMode.Open, FileAccess.Read)) using (var ms = new MemoryStream()) { stream.CopyTo(ms); jsonData = ms.ToArray(); } #else var jsonData = File.ReadAllBytes(path); #endif FLError error; FLSliceResult fleeceData; fixed(byte *jsonData_ = jsonData) { fleeceData = NativeRaw.FLData_ConvertJSON(new FLSlice(jsonData_, (ulong)jsonData.Length), &error); } ((long)fleeceData.buf).Should().NotBe(0, "because otherwise the conversion failed"); var root = Native.FLValue_AsArray(NativeRaw.FLValue_FromTrustedData((FLSlice)fleeceData)); ((long)root).Should().NotBe(0, "because otherwise the value is not of the expected type"); LiteCoreBridge.Check(err => Native.c4db_beginTransaction(Db, err)); try { FLArrayIterator iter; FLValue * item; uint numDocs = 0; for (Native.FLArrayIterator_Begin(root, &iter); null != (item = Native.FLArrayIterator_GetValue(&iter)); Native.FLArrayIterator_Next(&iter)) { var docID = idPrefix != null ? $"{idPrefix}{numDocs + 1:D7}" : $"doc{numDocs + 1:D7}"; var enc = Native.c4db_getSharedFleeceEncoder(Db); Native.FLEncoder_WriteValue(enc, item); var body = NativeRaw.FLEncoder_Finish(enc, &error); var rq = new C4DocPutRequest { docID = C4Slice.Allocate(docID), body = (C4Slice)body, save = true }; var doc = (C4Document *)LiteCoreBridge.Check(err => { var localPut = rq; return(Native.c4doc_put(Db, &localPut, null, err)); }); Native.c4doc_free(doc); Native.FLSliceResult_Free(body); C4Slice.Free(rq.docID); ++numDocs; if ((numDocs % 1000) == 0 && st.Elapsed > timeout) { WriteLine($"WARNING: Stopping JSON import after {st.Elapsed}"); return(numDocs); } if (verbose && (numDocs % 100000) == 0) { WriteLine($"{numDocs} "); } } if (verbose) { st.PrintReport("Importing", numDocs, "doc", _output); } return(numDocs); } finally { Native.FLSliceResult_Free(fleeceData); LiteCoreBridge.Check(err => Native.c4db_endTransaction(Db, true, err)); } }