* Prevent race conditions in DatastoreTest
Previously it was possible for tasks on the async queue to outlive the
instance of the DatastoreTest which could crash or cause TSAN
violations.
This fixes a flake that appeared in the AuthOutlivesDatastore test case.
* Improve readability of the error classification tests
* Move FSTQueryCacheTests files to Firestore/core
* Rewrite QueryCache tests in C++
* Fix test flake in local store tests
This doesn't affect production because we always set the additional
references pointer there, but it's technically optional and some tests
don't do this.
* Fix field initialization order
* Reduce dependencies in objc_compatibility_apple_test
This makes it possible to build and test util without having to build
everything
* Add a lint check for CMake files
* Find XCTest, if available
* Fix CMakeLists.txt to include all sources
* Fix test flake in local store tests
This doesn't affect production because we always set the additional
references pointer there, but it's technically optional and some tests
don't do this.
* Move component container to GoogleUtilities.
This will allow non-Firebase SDKs to take advantage of the component
system. Note: Firebase Core will eventually move over to use this, but
more investigation is needed about how this can be done with the least
amount of churn for other SDKs.
* Fix dependency on Logger.
* Add CHANGELOG entry.
* Fix selector name.
* Move ComponentContainer subspec to new pod.
* Rename to GoogleUtilitiesComponents.
* Style, make public headers.
* Update travis with new name.
* Add project to if_changed.sh
* Review comments.
* Enabled static framework, changed homepage.
* Fix missing quote.
There are more sources that can be `.cc` now (e.g., in API); these are left for a follow-up PR.
The dependency on Objective-C proto library cannot be removed just yet due to current lack of pretty-printing support for Nanopb.
* FIRInstallationsSingleOperationPromiseCache: a failing test for race condition added.
* ./scripts/style.sh
* FIRInstallationsSingleOperationPromiseCache: synchronize entire code blocks not relying on `atomic` property. The atomic property synchronization was insufficient to synchronize `newOperationHandler()`.
* ./scripts/style.sh
After this PR is merged, the Objective-C serializers can be completely removed from the project. Also, this PR changes the `Message` class quite a bit; it's probably in its final form now.
I did some performance testing locally and came to the conclusion that replacing Objective-C serializers with their C++ versions brings no performance downgrade; actually, there seems to be a very slight improvement. I tested writing large batches and reading large collections:
* both are network-dominated; wall time is about twice longer than CPU time;
* serialization represents a pretty small percentage of the total CPU time;
* for writing, C++ serialization is a little more efficient, taking ~6% of total CPU time, compared to ~8% in the Objective-C version. I've seen similar results for reading.
All integration tests pass, under Address Sanitizer as well.
* Move FSTPersistenceHelpers to core/test/.../local
* Rewrite persistence_testing in C++
* Migrate from FSTPersistenceTestHelpers to C++ persistence_testing
* Rename .mm to .cc where possible in IndexManager tests
* Remove Objective-C gunk from index_manager_test.h
This came up while I was investigating the effect of new C++ serializers on performance. When writing large batches, one of the hottest functions turned out to be `firebase::firestore::util::operator==(const DocumentKey& lhs, const DocumentKey& rhs)`, accounting for 15-20% of total CPU time. There are two reasons why comparing keys is currently not very efficient:
* `BasePath::CompareTo`, to which this comparison eventually resolves, mistakenly uses the general-purpose `util::Compare` function rather than the more efficient `util::CompareContainer`;
* the default implementation of `Comparable::operator==` results in two comparisons per element ("less-than" followed by "greater-than"), even though one would be sufficient.
Fixing these issues results in 8-10% CPU time improvement when writing large batches.
To work around the latter, this PR defines a new mixin `InequalityComparable` that is exactly the same as `Comparable`, except it doesn't define `operator==`, forcing the inheriting class to implement it manually.
Some measurements (all done on the emulator in release mode with no logging) follow; the test case was to write 10 batches of 500 very small documents. Note that I found wall clock to fluctuate too much to be reliable and instead use the measurements from XCode's Time Profiler, which (presumably) shows CPU time. Each measurement shows total CPU time spent on `firebase::firestore::util::operator==` (all instantiations, not just for `DocumentKey`), followed by the percentage of time spent in this function compared to total runtime:
* no optimization:
* 275ms/18.8%;
* 245ms/16.9%;
* 252ms/18.5%.
* `CompareContainer` optimization:
* 124ms/9.7%;
* 110ms/8.5%;
* 128ms/10.0%.
* `CompareContainer` + `ComparableWithEqual` optimizations:
* 95ms/7.3%;
* 100ms/8.0%;
* 112ms/9.2%.
Replace all uses of `FSTSerializerBeta` in `remote_objc_bridge.{h,mm}` with the C++ `Serializer`. Also, make most of `remote/` sources pure C++ and remove no-longer-used methods in `FSTSerializerBeta`. All integration tests pass, under Address Sanitizer as well.
Unfortunately, pretty-printing is still delegated to Objective-C, so that `remote_objc_bridge.mm` still has to be an Objective-C++ source (and which prevents inlining `remote_objc_bridge` into the streams).
#no-changelog Will add a changelog entry when local serializer is ported, too.
* Rationalize input validation exceptions and assertions
... under a single ThrowHandler concept. This makes it possible to set
an alternative ThrowHandler in our C# bindings that properly translates
input validation exceptions to the correct .NET exception types.
* Rename api/input_validation.h to util/exception.h
* Reimplement util/hard_assert.h in terms of util/exception.h