diff --git a/Firestore/CHANGELOG.md b/Firestore/CHANGELOG.md index 8c44ca3695e..51e98c78ef8 100644 --- a/Firestore/CHANGELOG.md +++ b/Firestore/CHANGELOG.md @@ -1,3 +1,9 @@ +# Unreleased +- [feature] Implemented an optimization in the local cache synchronization logic + that reduces the number of billed document reads when documents were deleted + on the server while the client was not actively listening to the query + (e.g. while the client was offline). (#INSERT_PR_NUMBER_HERE) + # 10.11.0 - [feature] Expose MultiDb API for public preview. (#10465) - [fixed] Fixed a compilation warning related to integer casting. (#11332) diff --git a/Firestore/Example/Firestore.xcodeproj/project.pbxproj b/Firestore/Example/Firestore.xcodeproj/project.pbxproj index 3740ccb83e3..4c284bd08e2 100644 --- a/Firestore/Example/Firestore.xcodeproj/project.pbxproj +++ b/Firestore/Example/Firestore.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 009CDC5D8C96F54A229F462F /* local_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F8043813A5D16963EC02B182 /* local_serializer_test.cc */; }; 009CDC6F03AC92F3E345085E /* collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129C1F315EE100DD57A1 /* collection_spec_test.json */; }; 009F5174BD172716AFE9F20A /* string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EE5300F8233D14025EF0456 /* string_apple_test.mm */; }; + 00A5761CD97E26A0EF4D47ED /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */; }; 00B7AFE2A7C158DD685EB5EE /* FIRCollectionReferenceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E045202154AA00B64F25 /* FIRCollectionReferenceTests.mm */; }; 00F1CB487E8E0DA48F2E8FEC /* message_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CE37875365497FFA8687B745 /* message_test.cc */; }; 0131DEDEF2C3CCAB2AB918A5 /* nanopb_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6F5B6C1399F92FD60F2C582B /* nanopb_util_test.cc */; }; @@ -24,9 +25,11 @@ 02B83EB79020AE6CBA60A410 /* FIRTimestampTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */; }; 02C953A7B0FA5EF87DB0361A /* FSTIntegrationTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5491BC711FB44593008B3588 /* FSTIntegrationTestCase.mm */; }; 02EB33CC2590E1484D462912 /* annotations.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9520B89AAC00B5BCE7 /* annotations.pb.cc */; }; + 035034AB3797D1E5E0112EC3 /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */; }; 035DE410628A8F804F6F2790 /* target_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 526D755F65AC676234F57125 /* target_test.cc */; }; 03AEB9E07A605AE1B5827548 /* field_index_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BF76A8DA34B5B67B4DD74666 /* field_index_test.cc */; }; 041CF73F67F6A22BF317625A /* FIRTimestampTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */; }; + 043C7B3DECB94F69F28BB798 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */; }; 0455FC6E2A281BD755FD933A /* precondition_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5520A36E1F00BCEB75 /* precondition_test.cc */; }; 04887E378B39FB86A8A5B52B /* leveldb_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5FF903AEFA7A3284660FA4C5 /* leveldb_local_store_test.cc */; }; 048A55EED3241ABC28752F86 /* memory_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74FBEFA4FE4B12C435011763 /* memory_mutation_queue_test.cc */; }; @@ -45,6 +48,9 @@ 06485D6DA8F64757D72636E1 /* leveldb_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E76F0CDF28E5FA62D21DE648 /* leveldb_target_cache_test.cc */; }; 06A3926F89C847846BE4D6BE /* http.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9720B89AAC00B5BCE7 /* http.pb.cc */; }; 06BCEB9C65DFAA142F3D3F0B /* view_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5466E7809AD2871FFDE6C76 /* view_testing.cc */; }; + 06D76CC82E034658BF7D4BE4 /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */; }; + 06E0914D76667F1345EC17F5 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */; }; + 070B9CCDD759E66E6E10CC68 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */; }; 072D805A94E767DE4D371881 /* FSTSyncEngineTestDriver.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02E20213FFC00B64F25 /* FSTSyncEngineTestDriver.mm */; }; 076465DFEEEAA4CAF5A0595A /* leveldb_overlay_migration_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D8A6D52723B1BABE1B7B8D8F /* leveldb_overlay_migration_manager_test.cc */; }; 077292C9797D97D3851F15CE /* leveldb_snappy_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D9D94300B9C02F7069523C00 /* leveldb_snappy_test.cc */; }; @@ -53,6 +59,8 @@ 07A64E6C4EB700E3AF3FD496 /* document_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB6B908320322E4D00CC290A /* document_test.cc */; }; 07ADEF17BFBC07C0C2E306F6 /* FSTMockDatastore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02D20213FFC00B64F25 /* FSTMockDatastore.mm */; }; 07B1E8C62772758BC82FEBEE /* field_mask_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5320A36E1F00BCEB75 /* field_mask_test.cc */; }; + 07F1F1FA00CE7B55E3476FD4 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */; }; + 0869E4C03A4648B67A719349 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */; }; 086A8CEDD4C4D5C858498C2D /* settings_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DD12BC1DB2480886D2FB0005 /* settings_test.cc */; }; 086E10B1B37666FB746D56BC /* FSTHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E03A2021401F00B64F25 /* FSTHelpers.mm */; }; 08839E1CEAAC07E350257E9D /* collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129C1F315EE100DD57A1 /* collection_spec_test.json */; }; @@ -81,10 +89,12 @@ 0C10A73586C704EB8361D3BD /* filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F02F734F272C3C70D1307076 /* filter_test.cc */; }; 0C18678CE7E355B17C34F2EE /* grpc_stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6BBE42F21262CF400C6A53E /* grpc_stream_test.cc */; }; 0C4219F37CC83614F1FD44ED /* local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 307FF03D0297024D59348EBD /* local_store_test.cc */; }; + 0C9887A2F6728CB9E8A4C3CA /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */; }; 0CEE93636BA4852D3C5EC428 /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; }; 0D124ED1B567672DD1BCEF05 /* memory_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2286F308EFB0534B1BDE05B9 /* memory_target_cache_test.cc */; }; 0D2D25522A94AA8195907870 /* status.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9920B89AAC00B5BCE7 /* status.pb.cc */; }; 0D6AE96565603226DB2E6838 /* logic_utils_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 28B45B2104E2DAFBBF86DBB7 /* logic_utils_test.cc */; }; + 0D8395F9244C191BF8D9F666 /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */; }; 0D88B4CB916A4752B08E5B42 /* query_listener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7C3F995E040E9E9C5E8514BB /* query_listener_test.cc */; }; 0DAA255C2FEB387895ADEE12 /* bits_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D01201BC69F00D97691 /* bits_test.cc */; }; 0DBD29A16030CDCD55E38CAB /* mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3068AA9DFBBA86C1FE2A946E /* mutation_queue_test.cc */; }; @@ -120,6 +130,7 @@ 129A369B28CA555B005AE7E2 /* FIRCountTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 129A369928CA555B005AE7E2 /* FIRCountTests.mm */; }; 129A369C28CA555B005AE7E2 /* FIRCountTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 129A369928CA555B005AE7E2 /* FIRCountTests.mm */; }; 12A3FB93C06C8EEB3971289A /* firebase_app_check_credentials_provider_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F119BDDF2F06B3C0883B8297 /* firebase_app_check_credentials_provider_test.mm */; }; + 12A611A85D59ED2742EEE187 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */; }; 12BB9ED1CA98AA52B92F497B /* log_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54C2294E1FECABAE007D065B /* log_test.cc */; }; 12DB753599571E24DCED0C2C /* FIRValidationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06D202154D600B64F25 /* FIRValidationTests.mm */; }; 12E04A12ABD5533B616D552A /* maybe_document.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE7E20B89AAC00B5BCE7 /* maybe_document.pb.cc */; }; @@ -127,20 +138,25 @@ 1357806B4CD3A62A8F5DE86D /* http.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9720B89AAC00B5BCE7 /* http.pb.cc */; }; 13D8F4196528BAB19DBB18A7 /* snapshot_version_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */; }; 13E264F840239C8C99865921 /* document_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB6B908320322E4D00CC290A /* document_test.cc */; }; + 13ED75EFC2F6917951518A4B /* md5_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D050936A2D52257FD17FB6E /* md5_test.cc */; }; + 143FBD21E02C709E3E6E8993 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */; }; 1465E362F7BA7A3D063E61C7 /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; }; 146C140B254F3837A4DD7AE8 /* bits_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D01201BC69F00D97691 /* bits_test.cc */; }; 152543FD706D5E8851C8DA92 /* precondition_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5520A36E1F00BCEB75 /* precondition_test.cc */; }; 153DBBCAF6D4FFA8ABC2EBDF /* leveldb_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB1F1E1B1ED15E8D042144B1 /* leveldb_query_engine_test.cc */; }; 153F3E4E9E3A0174E29550B4 /* mutation.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE8220B89AAC00B5BCE7 /* mutation.pb.cc */; }; + 15576E9A23A1C6678D5D7DE1 /* bloom_filter.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */; }; 156429A2993B86A905A42D96 /* aggregation_result.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = D872D754B8AD88E28AF28B28 /* aggregation_result.pb.cc */; }; 15A5DEC8430E71D64424CBFD /* target_index_matcher_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */; }; 15A5F95DA733FD89A1E4147D /* limit_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129F1F315EE100DD57A1 /* limit_spec_test.json */; }; 15BF63DFF3A7E9A5376C4233 /* transform_operation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 33607A3AE91548BD219EC9C6 /* transform_operation_test.cc */; }; 15F54E9538839D56A40C5565 /* watch_change_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2D7472BC70C024D736FF74D9 /* watch_change_test.cc */; }; 160B8B6F32963E94CB70B14F /* leveldb_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB1F1E1B1ED15E8D042144B1 /* leveldb_query_engine_test.cc */; }; + 162291531D29B002F6872A7F /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */; }; 163C0D0E65EB658E3B6070BC /* settings_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DD12BC1DB2480886D2FB0005 /* settings_test.cc */; }; 167659CDCA47B450F2441454 /* index_backfiller_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1F50E872B3F117A674DA8E94 /* index_backfiller_test.cc */; }; 16791B16601204220623916C /* status_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352C20A3B3D7003E0143 /* status_test.cc */; }; + 169EDCF15637580BA79B61AD /* md5_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = E2E39422953DE1D3C7B97E77 /* md5_testing.cc */; }; 16FE432587C1B40AF08613D2 /* objc_type_traits_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A0CF41BA5AED6049B0BEB2C /* objc_type_traits_apple_test.mm */; }; 16FF9073CA381CA43CA9BF29 /* FIRTransactionOptionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF39ECA1293D21A0A2AB2626 /* FIRTransactionOptionsTests.mm */; }; 1733601ECCEA33E730DEAF45 /* autoid_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A521FC913E500713A1A /* autoid_test.cc */; }; @@ -151,16 +167,19 @@ 17DFF30CF61D87883986E8B6 /* executor_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4687208F9B9100554BA2 /* executor_std_test.cc */; }; 17ECB768DA44AE0F49647E22 /* memory_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6A33BC2D84233C355F1D0 /* memory_query_engine_test.cc */; }; 1817DEF8FF479D218381C541 /* FSTGoogleTestTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */; }; + 185B0DF3E9396AA218E7A460 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */; }; 18638EAED9E126FC5D895B14 /* common.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D221C2DDC800EFB9CC /* common.pb.cc */; }; 18CF41A17EA3292329E1119D /* FIRGeoPointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E048202154AA00B64F25 /* FIRGeoPointTests.mm */; }; 18F644E6AA98E6D6F3F1F809 /* executor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4688208F9B9100554BA2 /* executor_test.cc */; }; 190F9885BAA81587F08CD26C /* index.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 395E8B07639E69290A929695 /* index.pb.cc */; }; 1989623826923A9D5A7EFA40 /* create_noop_connectivity_monitor.cc in Sources */ = {isa = PBXBuildFile; fileRef = CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */; }; + 198C6B31EFAA230F7FF9B76F /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */; }; 198F193BD9484E49375A7BE7 /* FSTHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E03A2021401F00B64F25 /* FSTHelpers.mm */; }; 199B778D5820495797E0BE02 /* filesystem_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F51859B394D01C0C507282F1 /* filesystem_test.cc */; }; 1A1299107EFF68DA9DAB19BD /* leveldb_overlay_migration_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D8A6D52723B1BABE1B7B8D8F /* leveldb_overlay_migration_manager_test.cc */; }; 1A21C6A5AC8A153E96F91566 /* testing_hooks_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */; }; 1A3D8028303B45FCBB21CAD3 /* aggregation_result.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = D872D754B8AD88E28AF28B28 /* aggregation_result.pb.cc */; }; + 1AE27A46DC082F28D9494599 /* bloom_filter.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */; }; 1B4794A51F4266556CD0976B /* view_snapshot_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC572A9168BBEF7B83E4BBC5 /* view_snapshot_test.cc */; }; 1B6E74BA33B010D76DB1E2F9 /* FIRGeoPointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E048202154AA00B64F25 /* FIRGeoPointTests.mm */; }; 1B816F48012524939CA57CB3 /* user_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CCC9BD953F121B9E29F9AA42 /* user_test.cc */; }; @@ -173,6 +192,7 @@ 1B9F95F229FAD4E000EEC075 /* FIRAggregateQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1B9F95EC29FAD3F100EEC075 /* FIRAggregateQueryUnitTests.mm */; }; 1B9F95F329FAD4E100EEC075 /* FIRAggregateQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1B9F95EC29FAD3F100EEC075 /* FIRAggregateQueryUnitTests.mm */; }; 1BB0C34B2E8D8BCC5882430A /* garbage_collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = AAED89D7690E194EF3BA1132 /* garbage_collection_spec_test.json */; }; + 1BD772FABD69673BF5864110 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */; }; 1BF1F9A0CBB6B01654D3C2BE /* field_transform_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7515B47C92ABEEC66864B55C /* field_transform_test.cc */; }; 1C19D796DB6715368407387A /* annotations.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9520B89AAC00B5BCE7 /* annotations.pb.cc */; }; 1C4F88DDEFA6FA23E9E4DB4B /* mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3068AA9DFBBA86C1FE2A946E /* mutation_queue_test.cc */; }; @@ -183,12 +203,14 @@ 1CB8AEFBF3E9565FF9955B50 /* async_queue_libdispatch_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4680208EA0BE00554BA2 /* async_queue_libdispatch_test.mm */; }; 1CC56DCA513B98CE39A6ED45 /* memory_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F6CA0C5638AB6627CB5B4CF4 /* memory_local_store_test.cc */; }; 1CC9BABDD52B2A1E37E2698D /* mutation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C8522DE226C467C54E6788D8 /* mutation_test.cc */; }; + 1CEEB0E7FBBB974224BBA557 /* bloom_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */; }; 1D618761796DE311A1707AA2 /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; }; 1D71CA6BBA1E3433F243188E /* common.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D221C2DDC800EFB9CC /* common.pb.cc */; }; 1D76DDBE57A4D66C64C00B65 /* FIRFieldValueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04A202154AA00B64F25 /* FIRFieldValueTests.mm */; }; 1D7919CD2A05C15803F5FE05 /* leveldb_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5C7942B6244F4C416B11B86C /* leveldb_mutation_queue_test.cc */; }; 1DB3013C5FC736B519CD65A3 /* common.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D221C2DDC800EFB9CC /* common.pb.cc */; }; 1DCA68BB2EF7A9144B35411F /* leveldb_opener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 75860CD13AF47EB1EA39EC2F /* leveldb_opener_test.cc */; }; + 1DCDED1F94EBC7F72FDBFC98 /* md5_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = E2E39422953DE1D3C7B97E77 /* md5_testing.cc */; }; 1E194F1CFDFE0265DF1CD5E6 /* garbage_collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = AAED89D7690E194EF3BA1132 /* garbage_collection_spec_test.json */; }; 1E2AE064CF32A604DC7BFD4D /* to_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B696858D2214B53900271095 /* to_string_test.cc */; }; 1E41BEEDB1F7F23D8A7C47E6 /* bundle_reader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6ECAF7DE28A19C69DF386D88 /* bundle_reader_test.cc */; }; @@ -202,10 +224,12 @@ 1F4930A8366F74288121F627 /* create_noop_connectivity_monitor.cc in Sources */ = {isa = PBXBuildFile; fileRef = CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */; }; 1F56F51EB6DF0951B1F4F85B /* lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 277EAACC4DD7C21332E8496A /* lru_garbage_collector_test.cc */; }; 1F998DDECB54A66222CC66AA /* string_format_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54131E9620ADE678001DF3FF /* string_format_test.cc */; }; + 1FE23E911F0761AA896FAD67 /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */; }; 2045517602D767BD01EA71D9 /* overlay_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E1459FA70B8FC18DE4B80D0D /* overlay_test.cc */; }; 205601D1C6A40A4DD3BBAA04 /* target_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 526D755F65AC676234F57125 /* target_test.cc */; }; 20814A477D00EA11D0E76631 /* FIRDocumentSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04B202154AA00B64F25 /* FIRDocumentSnapshotTests.mm */; }; 20A26E9D0336F7F32A098D05 /* Pods_Firestore_IntegrationTests_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2220F583583EFC28DE792ABE /* Pods_Firestore_IntegrationTests_tvOS.framework */; }; + 211A60ECA3976D27C0BF59BB /* md5_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D050936A2D52257FD17FB6E /* md5_test.cc */; }; 21836C4D9D48F962E7A3A244 /* ordered_code_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D03201BC6E400D97691 /* ordered_code_test.cc */; }; 21A2A881F71CB825299DF06E /* hard_assert_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 444B7AB3F5A2929070CB1363 /* hard_assert_test.cc */; }; 21C17F15579341289AD01051 /* persistence_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9113B6F513D0473AEABBAF1F /* persistence_testing.cc */; }; @@ -217,6 +241,7 @@ 22A00AC39CAB3426A943E037 /* query.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D621C2DDC800EFB9CC /* query.pb.cc */; }; 23C04A637090E438461E4E70 /* latlng.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9220B89AAC00B5BCE7 /* latlng.pb.cc */; }; 23EFC681986488B033C2B318 /* leveldb_opener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 75860CD13AF47EB1EA39EC2F /* leveldb_opener_test.cc */; }; + 2403890A78D7AB099754A18C /* bloom_filter.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */; }; 2428E92E063EBAEA44BA5913 /* target_index_matcher_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */; }; 248DE4F56DD938F4DBCCF39B /* bundle_reader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6ECAF7DE28A19C69DF386D88 /* bundle_reader_test.cc */; }; 24B75C63BDCD5551B2F69901 /* testing_hooks_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */; }; @@ -228,12 +253,14 @@ 25C167BAA4284FC951206E1F /* FIRFirestoreTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5467FAFF203E56F8009C9584 /* FIRFirestoreTests.mm */; }; 25DCB9BD1C681C6611A17164 /* testing_hooks_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */; }; 25FE27330996A59F31713A0C /* FIRDocumentReferenceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E049202154AA00B64F25 /* FIRDocumentReferenceTests.mm */; }; + 2618255E63631038B64DF3BB /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */; }; 2620644052E960310DADB298 /* FIRFieldValueTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04A202154AA00B64F25 /* FIRFieldValueTests.mm */; }; 2634E1C1971C05790B505824 /* resource_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2B02024FFD70028D6BE /* resource_path_test.cc */; }; 2639ABDA17EECEB7F62D1D83 /* pretty_printing_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB323F9553050F4F6490F9FF /* pretty_printing_test.cc */; }; 263BD3B99AC4965540235BA4 /* firebase_app_check_credentials_provider_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F119BDDF2F06B3C0883B8297 /* firebase_app_check_credentials_provider_test.mm */; }; 264AAB492E24318C5EEB0649 /* memory_lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9765D47FA12FA283F4EFAD02 /* memory_lru_garbage_collector_test.cc */; }; 26777815544F549DD18D87AF /* message_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CE37875365497FFA8687B745 /* message_test.cc */; }; + 2689EB821AC8083568EACFB8 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */; }; 268FC3360157A2DCAF89F92D /* snapshot_version_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */; }; 26B52236C9D049847042E1BD /* FSTMockDatastore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02D20213FFC00B64F25 /* FSTMockDatastore.mm */; }; 26B6F5D7571279F4FC06581A /* leveldb_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB1F1E1B1ED15E8D042144B1 /* leveldb_query_engine_test.cc */; }; @@ -241,6 +268,7 @@ 26C577D159CFFD73E24D543C /* memory_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74FBEFA4FE4B12C435011763 /* memory_mutation_queue_test.cc */; }; 26CB3D7C871BC56456C6021E /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; }; 276A563D546698B6AAC20164 /* annotations.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9520B89AAC00B5BCE7 /* annotations.pb.cc */; }; + 27AF4C4BAFE079892D4F5341 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */; }; 27E46C94AAB087C80A97FF7F /* FIRServerTimestampTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06E202154D600B64F25 /* FIRServerTimestampTests.mm */; }; 280A282BE9AF4DCF4E855EAB /* filesystem_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F51859B394D01C0C507282F1 /* filesystem_test.cc */; }; 2836CD14F6F0EA3B184E325E /* schedule_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B0B005A79E765AF02793DCE /* schedule_test.cc */; }; @@ -255,9 +283,11 @@ 2A0925323776AD50C1105BC0 /* counting_query_engine.cc in Sources */ = {isa = PBXBuildFile; fileRef = 99434327614FEFF7F7DC88EC /* counting_query_engine.cc */; }; 2A365DB6DF32631964FE690A /* stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5B5414D28802BC76FDADABD6 /* stream_test.cc */; }; 2A499CFB2831612A045977CD /* message_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CE37875365497FFA8687B745 /* message_test.cc */; }; + 2A86AB04B38DBB770A1D8B13 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */; }; 2AAEABFD550255271E3BAC91 /* to_string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = B68B1E002213A764008977EF /* to_string_apple_test.mm */; }; 2ABA80088D70E7A58F95F7D8 /* delayed_constructor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */; }; 2AD8EE91928AE68DF268BEDA /* limbo_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129E1F315EE100DD57A1 /* limbo_spec_test.json */; }; + 2AD98CD29CC6F820A74CDD5E /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */; }; 2AE3914BBC4EDF91BD852939 /* memory_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6A33BC2D84233C355F1D0 /* memory_query_engine_test.cc */; }; 2B4021C3E663DDDDD512E961 /* objc_type_traits_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A0CF41BA5AED6049B0BEB2C /* objc_type_traits_apple_test.mm */; }; 2B4234B962625F9EE68B31AC /* index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE4A9E38D65688EE000EE2A1 /* index_manager_test.cc */; }; @@ -267,12 +297,15 @@ 2C5E4D9FDE7615AD0F63909E /* async_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 872C92ABD71B12784A1C5520 /* async_testing.cc */; }; 2CBA4FA327C48B97D31F6373 /* watch_change_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2D7472BC70C024D736FF74D9 /* watch_change_test.cc */; }; 2CD379584D1D35AAEA271D21 /* sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA4E20A36DBB00BCEB75 /* sorted_map_test.cc */; }; + 2CDAAD6EC0BDAD9D929A59B5 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */; }; 2D220B9ABFA36CD7AC43D0A7 /* time_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5497CB76229DECDE000FB92F /* time_testing.cc */; }; + 2D361A44A8B8D57024B89F88 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */; }; 2D65D31D71A75B046C47B0EB /* view_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5466E7809AD2871FFDE6C76 /* view_testing.cc */; }; 2DB56B6DED2C93014AE5C51A /* write_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A51F315EE100DD57A1 /* write_spec_test.json */; }; 2E0BBA7E627EB240BA11B0D0 /* exponential_backoff_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D1B68420E2AB1A00B35856 /* exponential_backoff_test.cc */; }; 2E169CF1E9E499F054BB873A /* FSTEventAccumulator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E0392021401F00B64F25 /* FSTEventAccumulator.mm */; }; 2E373EA9D5FF8C6DE2507675 /* field_index_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BF76A8DA34B5B67B4DD74666 /* field_index_test.cc */; }; + 2E5758FE6CFE753B04D50F89 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */; }; 2E76BC76BBCE5FCDDCF5EEBE /* leveldb_bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8E9CD82E60893DDD7757B798 /* leveldb_bundle_cache_test.cc */; }; 2E7CAC076447970DE881E703 /* aggregate_query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AF924C79F49F793992A84879 /* aggregate_query_test.cc */; }; 2EAD77559EC654E6CA4D3E21 /* FIRSnapshotMetadataTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04D202154AA00B64F25 /* FIRSnapshotMetadataTests.mm */; }; @@ -282,6 +315,7 @@ 2F69187F601E00054469F4A5 /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3355BE9391CC4857AF0BDAE3 /* DatabaseTests.swift */; }; 2F8FDF35BBB549A6F4D2118E /* FSTMemorySpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02F20213FFC00B64F25 /* FSTMemorySpecTests.mm */; }; 2FA0BAE32D587DF2EA5EEB97 /* async_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB467B208E9A8200554BA2 /* async_queue_test.cc */; }; + 2FAE0BCBE559ED7214AEFEB7 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */; }; 3040FD156E1B7C92B0F2A70C /* ordered_code_benchmark.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0473AFFF5567E667A125347B /* ordered_code_benchmark.cc */; }; 3056418E81BC7584FBE8AD6C /* user_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CCC9BD953F121B9E29F9AA42 /* user_test.cc */; }; 306E762DC6B829CED4FD995D /* target_id_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CF82019382300D97691 /* target_id_generator_test.cc */; }; @@ -290,6 +324,7 @@ 31850B3D5232E8D3F8C4D90C /* memory_remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1CA9800A53669EFBFFB824E3 /* memory_remote_document_cache_test.cc */; }; 31A396C81A107D1DEFDF4A34 /* serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 61F72C5520BC48FD001A68CB /* serializer_test.cc */; }; 31BDB4CB0E7458C650A77ED0 /* FIRFirestoreTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5467FAFF203E56F8009C9584 /* FIRFirestoreTests.mm */; }; + 31C9186C5B8558361FACFD1F /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */; }; 31D8E3D925FA3F70AA20ACCE /* FSTMockDatastore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02D20213FFC00B64F25 /* FSTMockDatastore.mm */; }; 32030FA5B4BE6ABDFF2F974E /* bundle_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 79EAA9F7B1B9592B5F053923 /* bundle_spec_test.json */; }; 32A635B2EBF461CE7A7B5C31 /* resource.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1C3F7302BF4AE6CBC00ECDD0 /* resource.pb.cc */; }; @@ -297,6 +332,7 @@ 32B0739404FA588608E1F41A /* CodableTimestampTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B65C996438B84DBC7616640 /* CodableTimestampTests.swift */; }; 32F022CB75AEE48CDDAF2982 /* mutation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C8522DE226C467C54E6788D8 /* mutation_test.cc */; }; 32F8B4652010E8224E353041 /* persistence_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A31F315EE100DD57A1 /* persistence_spec_test.json */; }; + 330DE2A5AE6AF8D66C9C849F /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */; }; 336E415DD06E719F9C9E2A14 /* grpc_stream_tester.cc in Sources */ = {isa = PBXBuildFile; fileRef = 87553338E42B8ECA05BA987E /* grpc_stream_tester.cc */; }; 338DFD5BCD142DF6C82A0D56 /* cc_compilation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1B342370EAE3AA02393E33EB /* cc_compilation_test.cc */; }; 339CFFD1323BDCA61EAAFE31 /* query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B9C261C26C5D311E1E3C0CB9 /* query_test.cc */; }; @@ -305,7 +341,9 @@ 3409F2AEB7D6D95478D4344A /* random_access_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 014C60628830D95031574D15 /* random_access_queue_test.cc */; }; 34202A37E0B762386967AF3D /* grpc_stream_tester.cc in Sources */ = {isa = PBXBuildFile; fileRef = 87553338E42B8ECA05BA987E /* grpc_stream_tester.cc */; }; 342724CA250A65E23CB133AC /* async_queue_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4681208EA0BE00554BA2 /* async_queue_std_test.cc */; }; + 342DA187B53105640073658F /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */; }; 3451DC1712D7BF5D288339A2 /* view_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5466E7809AD2871FFDE6C76 /* view_testing.cc */; }; + 34B62A40BB56F9574B87B28B /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */; }; 34D69886DAD4A2029BFC5C63 /* precondition_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5520A36E1F00BCEB75 /* precondition_test.cc */; }; 34E866DB52AAB7DB76B69A91 /* recovery_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 9C1AFCC9E616EC33D6E169CF /* recovery_spec_test.json */; }; 353E47129584B8DDF10138BD /* stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5B5414D28802BC76FDADABD6 /* stream_test.cc */; }; @@ -315,14 +353,17 @@ 35C330499D50AC415B24C580 /* async_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 872C92ABD71B12784A1C5520 /* async_testing.cc */; }; 35DB74DFB2F174865BCCC264 /* leveldb_transaction_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */; }; 35FEB53E165518C0DE155CB0 /* target_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 526D755F65AC676234F57125 /* target_test.cc */; }; + 360EB1D691F9C19A21D0916F /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */; }; 36999FC1F37930E8C9B6DA25 /* stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5B5414D28802BC76FDADABD6 /* stream_test.cc */; }; 36E174A66C323891AEA16A2A /* FIRTimestampTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */; }; 36FD4CE79613D18BC783C55B /* string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EE5300F8233D14025EF0456 /* string_apple_test.mm */; }; 37286D731E432CB873354357 /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; }; + 37461AF1ACC2E64DF1709736 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */; }; 3783E25DFF9E5C0896D34FEF /* index_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 8C7278B604B8799F074F4E8C /* index_spec_test.json */; }; 37C4BF11C8B2B8B54B5ED138 /* string_apple_benchmark.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C73C0CC6F62A90D8573F383 /* string_apple_benchmark.mm */; }; 37EC6C6EA9169BB99078CA96 /* reference_set_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 132E32997D781B896672D30A /* reference_set_test.cc */; }; 380A137B785A5A6991BEDF4B /* leveldb_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5FF903AEFA7A3284660FA4C5 /* leveldb_local_store_test.cc */; }; + 380E543B7BC6F648BBB250B4 /* md5_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D050936A2D52257FD17FB6E /* md5_test.cc */; }; 38208AC761FF994BA69822BE /* async_queue_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4681208EA0BE00554BA2 /* async_queue_std_test.cc */; }; 3887E1635B31DCD7BC0922BD /* existence_filter_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129D1F315EE100DD57A1 /* existence_filter_spec_test.json */; }; 392966346DA5EB3165E16A22 /* bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F7FC06E0A47D393DE1759AE1 /* bundle_cache_test.cc */; }; @@ -332,6 +373,7 @@ 39CDC9EC5FD2E891D6D49151 /* secure_random_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A531FC913E500713A1A /* secure_random_test.cc */; }; 3A307F319553A977258BB3D6 /* view_snapshot_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC572A9168BBEF7B83E4BBC5 /* view_snapshot_test.cc */; }; 3A7CB01751697ED599F2D9A1 /* executor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4688208F9B9100554BA2 /* executor_test.cc */; }; + 3A93D8FB318C6491A6B654F5 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */; }; 3ABF84FC618016CA6E1D3C03 /* leveldb_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 332485C4DCC6BA0DBB5E31B7 /* leveldb_util_test.cc */; }; 3AC147E153D4A535B71C519E /* sorted_set_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA4C20A36DBB00BCEB75 /* sorted_set_test.cc */; }; 3AFBEF94A35034719477C066 /* random_access_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 014C60628830D95031574D15 /* random_access_queue_test.cc */; }; @@ -340,9 +382,11 @@ 3B256CCF6AEEE12E22F16BB8 /* hashing_test_apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = B69CF3F02227386500B281C8 /* hashing_test_apple.mm */; }; 3B37BD3C13A66625EC82CF77 /* hard_assert_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 444B7AB3F5A2929070CB1363 /* hard_assert_test.cc */; }; 3B47CC43DBA24434E215B8ED /* memory_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB5A1E760451189DA36028B3 /* memory_index_manager_test.cc */; }; + 3B5CEA04AC1627256A1AE8BA /* bloom_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */; }; 3B843E4C1F3A182900548890 /* remote_store_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 3B843E4A1F3930A400548890 /* remote_store_spec_test.json */; }; 3BA4EEA6153B3833F86B8104 /* writer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BC3C788D290A935C353CEAA1 /* writer_test.cc */; }; 3BAFCABA851AE1865D904323 /* to_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B696858D2214B53900271095 /* to_string_test.cc */; }; + 3C5D441E7D5C140F0FB14D91 /* bloom_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */; }; 3CFFA6F016231446367E3A69 /* listen_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A01F315EE100DD57A1 /* listen_spec_test.json */; }; 3D22F56C0DE7C7256C75DC06 /* tree_sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA4D20A36DBB00BCEB75 /* tree_sorted_map_test.cc */; }; 3D9619906F09108E34FF0C95 /* FSTSmokeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E07C202154EB00B64F25 /* FSTSmokeTests.mm */; }; @@ -350,23 +394,29 @@ 3DBBC644BE08B140BCC23BD5 /* string_apple_benchmark.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C73C0CC6F62A90D8573F383 /* string_apple_benchmark.mm */; }; 3DDC57212ADBA9AD498EAA4C /* bundle.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = A366F6AE1A5A77548485C091 /* bundle.pb.cc */; }; 3DFBA7413965F3E6F366E923 /* grpc_unary_call_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D964942163E63900EB9CFB /* grpc_unary_call_test.cc */; }; + 3E101CE56C70F06BA2FDD56C /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */; }; 3E38E4B33855DD6CF7526225 /* bundle_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C2A94EE24E60543F62CC35 /* bundle_serializer_test.cc */; }; + 3E5FD39FE7442883AB3CE1F2 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */; }; 3F3C2DAD9F9326BF789B1C96 /* serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 61F72C5520BC48FD001A68CB /* serializer_test.cc */; }; 3F4B6300198FD78E7B19BC5A /* strerror_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 358C3B5FE573B1D60A4F7592 /* strerror_test.cc */; }; 3F6C9F8A993CF4B0CD51E7F0 /* lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 277EAACC4DD7C21332E8496A /* lru_garbage_collector_test.cc */; }; 3FF88C11276449F00F79AF48 /* status_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3CAA33F964042646FDDAF9F9 /* status_testing.cc */; }; 3FFFC1FE083D8BE9C4D9A148 /* string_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CFC201A2EE200D97691 /* string_util_test.cc */; }; 40431BF2A368D0C891229F6E /* FSTMemorySpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02F20213FFC00B64F25 /* FSTMemorySpecTests.mm */; }; + 409B29C81132718B36BF2497 /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */; }; 409C0F2BFC2E1BECFFAC4D32 /* testutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352820A3B3BD003E0143 /* testutil.cc */; }; 412BE974741729A6683C386F /* aggregate_query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AF924C79F49F793992A84879 /* aggregate_query_test.cc */; }; 4173B61CB74EB4CD1D89EE68 /* latlng.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9220B89AAC00B5BCE7 /* latlng.pb.cc */; }; 4194B7BB8B0352E1AC5D69B9 /* precondition_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5520A36E1F00BCEB75 /* precondition_test.cc */; }; + 41C1C67BD1A10F2A8D1F5316 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */; }; 41EAC526C543064B8F3F7EDA /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; }; 42063E6AE9ADF659AA6D4E18 /* FSTSmokeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E07C202154EB00B64F25 /* FSTSmokeTests.mm */; }; 42208EDA18C500BC271B6E95 /* FSTSyncEngineTestDriver.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02E20213FFC00B64F25 /* FSTSyncEngineTestDriver.mm */; }; 4242808CF1CF732526F798CA /* memory_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6A33BC2D84233C355F1D0 /* memory_query_engine_test.cc */; }; + 42A98512D4C9EC6722334FE6 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */; }; 432056C4D1259F76C80FC2A8 /* FSTUserDataReaderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8D9892F204959C50613F16C8 /* FSTUserDataReaderTests.mm */; }; 433474A3416B76645FFD17BB /* hashing_test_apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = B69CF3F02227386500B281C8 /* hashing_test_apple.mm */; }; + 43B6A25A860337D21D933C29 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */; }; 444298A613D027AC67F7E977 /* memory_lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9765D47FA12FA283F4EFAD02 /* memory_lru_garbage_collector_test.cc */; }; 44A8B51C05538A8DACB85578 /* byte_stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 432C71959255C5DBDF522F52 /* byte_stream_test.cc */; }; 44C4244E42FFFB6E9D7F28BA /* byte_stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 432C71959255C5DBDF522F52 /* byte_stream_test.cc */; }; @@ -383,6 +433,7 @@ 46B104DEE6014D881F7ED169 /* collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129C1F315EE100DD57A1 /* collection_spec_test.json */; }; 46EAC2828CD942F27834F497 /* persistence_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9113B6F513D0473AEABBAF1F /* persistence_testing.cc */; }; 470A37727BBF516B05ED276A /* executor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4688208F9B9100554BA2 /* executor_test.cc */; }; + 47136EEB53CF80D7C8436F38 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */; }; 4747A986288114C2B7CD179E /* statusor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352D20A3B3D7003E0143 /* statusor_test.cc */; }; 474DF520B9859479845C8A4D /* bundle_builder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4F5B96F3ABCD2CA901DB1CD4 /* bundle_builder.cc */; }; 475FE2D34C6555A54D77A054 /* empty_credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8FA60B08D59FEA0D6751E87F /* empty_credentials_provider_test.cc */; }; @@ -391,6 +442,8 @@ 47B8ED6737A24EF96B1ED318 /* garbage_collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = AAED89D7690E194EF3BA1132 /* garbage_collection_spec_test.json */; }; 4809D7ACAA9414E3192F04FF /* FIRGeoPointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E048202154AA00B64F25 /* FIRGeoPointTests.mm */; }; 485CBA9F99771437BA1CB401 /* event_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6F57521E161450FAF89075ED /* event_manager_test.cc */; }; + 48720B5768AFA2B2F3E14C04 /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */; }; + 48926FF55484E996B474D32F /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */; }; 489D672CAA09B9BC66798E9F /* status.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9920B89AAC00B5BCE7 /* status.pb.cc */; }; 48BC5801432127A90CFF55E3 /* index.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 395E8B07639E69290A929695 /* index.pb.cc */; }; 48D1B38B93D34F1B82320577 /* view_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5466E7809AD2871FFDE6C76 /* view_testing.cc */; }; @@ -412,6 +465,7 @@ 4B54FA587C7107973FD76044 /* FIRBundlesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 776530F066E788C355B78457 /* FIRBundlesTests.mm */; }; 4B5FA86D9568ECE20C6D3AD1 /* bundle_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 79EAA9F7B1B9592B5F053923 /* bundle_spec_test.json */; }; 4BFEEB7FDD7CD5A693B5B5C1 /* index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE4A9E38D65688EE000EE2A1 /* index_manager_test.cc */; }; + 4C17393656A7D6255AA998B3 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */; }; 4C4D780CA9367DBA324D97FF /* load_bundle_task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8F1A7B4158D9DD76EE4836BF /* load_bundle_task_test.cc */; }; 4C5292BF643BF14FA2AC5DB1 /* settings_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DD12BC1DB2480886D2FB0005 /* settings_test.cc */; }; 4C66806697D7BCA730FA3697 /* common.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D221C2DDC800EFB9CC /* common.pb.cc */; }; @@ -447,6 +501,7 @@ 513D34C9964E8C60C5C2EE1C /* leveldb_bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8E9CD82E60893DDD7757B798 /* leveldb_bundle_cache_test.cc */; }; 5150E9F256E6E82D6F3CB3F1 /* bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F7FC06E0A47D393DE1759AE1 /* bundle_cache_test.cc */; }; 518BF03D57FBAD7C632D18F8 /* FIRQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = FF73B39D04D1760190E6B84A /* FIRQueryUnitTests.mm */; }; + 51A483DE202CC3E9FCD8FF6E /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */; }; 52967C3DD7896BFA48840488 /* byte_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5342CDDB137B4E93E2E85CCA /* byte_string_test.cc */; }; 529AB59F636060FEA21BD4FF /* garbage_collection_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = AAED89D7690E194EF3BA1132 /* garbage_collection_spec_test.json */; }; 5360D52DCAD1069B1E4B0B9D /* testing_hooks_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */; }; @@ -581,15 +636,21 @@ 55E84644D385A70E607A0F91 /* leveldb_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5FF903AEFA7A3284660FA4C5 /* leveldb_local_store_test.cc */; }; 568EC1C0F68A7B95E57C8C6C /* leveldb_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54995F6E205B6E12004EFFA0 /* leveldb_key_test.cc */; }; 56D85436D3C864B804851B15 /* string_format_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFD366B783AE27B9E79EE7A /* string_format_apple_test.mm */; }; + 57171BD004A1691B19A76453 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */; }; + 5778E5F1FABEFA450B8CF4BC /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */; }; + 5785C7190F8F8DDE879F16B7 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */; }; + 57F0E1A1F2B614BA74961D9A /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */; }; 583DF65751B7BBD0A222CAB4 /* byte_stream_cpp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 01D10113ECC5B446DB35E96D /* byte_stream_cpp_test.cc */; }; 58693C153EC597BC25EE9648 /* firebase_auth_credentials_provider_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F869D85E900E5AF6CD02E2FC /* firebase_auth_credentials_provider_test.mm */; }; 58B84B550725D9812729C7F7 /* FIRTransactionOptionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF39ECA1293D21A0A2AB2626 /* FIRTransactionOptionsTests.mm */; }; 58E377DCCC64FE7D2C6B59A1 /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; }; 5958E3E3A0446A88B815CB70 /* grpc_connection_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D9649021544D4F00EB9CFB /* grpc_connection_test.cc */; }; 59880AE766F7FBFF0C41A94E /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; }; + 59A3F624F45DC98D8B9F8014 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */; }; 59E6941008253D4B0F77C2BA /* writer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BC3C788D290A935C353CEAA1 /* writer_test.cc */; }; 59E89A97A476790E89AFC7E7 /* view_snapshot_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC572A9168BBEF7B83E4BBC5 /* view_snapshot_test.cc */; }; 59E95B64C460C860E2BC7464 /* load_bundle_task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8F1A7B4158D9DD76EE4836BF /* load_bundle_task_test.cc */; }; + 59F3A9669E0AF835E62D6674 /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */; }; 59F512D155DE361095A04ED4 /* FIRSnapshotMetadataTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04D202154AA00B64F25 /* FIRSnapshotMetadataTests.mm */; }; 5A080105CCBFDB6BF3F3772D /* path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 403DBF6EFB541DFD01582AA3 /* path_test.cc */; }; 5A44725457D6B7805FD66EEB /* bundle_loader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A853C81A6A5A51C9D0389EDA /* bundle_loader_test.cc */; }; @@ -661,6 +722,7 @@ 618BBEB020B89AAC00B5BCE7 /* http.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9720B89AAC00B5BCE7 /* http.pb.cc */; }; 618BBEB120B89AAC00B5BCE7 /* status.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9920B89AAC00B5BCE7 /* status.pb.cc */; }; 61976CE9C088131EC564A503 /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; }; + 61C89E693B42E346ED2F5935 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */; }; 61D35E0DE04E70D3BC243A65 /* FIRGeoPointTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E048202154AA00B64F25 /* FIRGeoPointTests.mm */; }; 61ECC7CE18700CBD73D0D810 /* leveldb_migrations_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = EF83ACD5E1E9F25845A9ACED /* leveldb_migrations_test.cc */; }; 61F72C5620BC48FD001A68CB /* serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 61F72C5520BC48FD001A68CB /* serializer_test.cc */; }; @@ -679,13 +741,18 @@ 6380CACCF96A9B26900983DC /* leveldb_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E76F0CDF28E5FA62D21DE648 /* leveldb_target_cache_test.cc */; }; 63B91FC476F3915A44F00796 /* query.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D621C2DDC800EFB9CC /* query.pb.cc */; }; 64055C7B3BF2C4106714DD3C /* testing_hooks_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */; }; + 64B3FDEE22A5D07744A8A9ED /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */; }; + 64D8241E9F56973DAD3077BC /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */; }; 650B31A5EC6F8D2AEA79C350 /* index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE4A9E38D65688EE000EE2A1 /* index_manager_test.cc */; }; 65537B22A73E3909666FB5BC /* remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7EB299CF85034F09CFD6F3FD /* remote_document_cache_test.cc */; }; + 658CBF4A717EA160E27C973E /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */; }; + 659FFE071CD0F60DAEADD50B /* bloom_filter.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */; }; 65D54B964A2021E5A36AB21F /* bundle_loader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A853C81A6A5A51C9D0389EDA /* bundle_loader_test.cc */; }; 65E67ED71688670CC6715800 /* load_bundle_task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8F1A7B4158D9DD76EE4836BF /* load_bundle_task_test.cc */; }; 65FC1A102890C02EF1A65213 /* database_info_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D92E20235D22000A432D /* database_info_test.cc */; }; 660E99DEDA0A6FC1CCB200F9 /* FIRArrayTransformTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 73866A9F2082B069009BB4FF /* FIRArrayTransformTests.mm */; }; 662793139A36E5CFC935B949 /* task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 899FC22684B0F7BEEAE13527 /* task_test.cc */; }; + 662E94803D6FABE56F0D22C9 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */; }; 66464C291396AF149AD908FD /* FIRDocumentReferenceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E049202154AA00B64F25 /* FIRDocumentReferenceTests.mm */; }; 66CA091F8B610E0FB0A3F8A4 /* target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C37696557C81A6C2B7271A /* target_cache_test.cc */; }; 66D9F8E8A65F97F436B1EE5E /* memory_lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9765D47FA12FA283F4EFAD02 /* memory_lru_garbage_collector_test.cc */; }; @@ -693,6 +760,7 @@ 66FAB8EAC012A3822BD4D0C9 /* leveldb_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 332485C4DCC6BA0DBB5E31B7 /* leveldb_util_test.cc */; }; 6711E75A10EBA662341F5C9D /* leveldb_document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE89CFF09C6804573841397F /* leveldb_document_overlay_cache_test.cc */; }; 677C833244550767B71DB1BA /* log_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54C2294E1FECABAE007D065B /* log_test.cc */; }; + 67B8C34BDF0FFD7532D7BE4F /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */; }; 67BC2B77C1CC47388E79D774 /* FIRSnapshotMetadataTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04D202154AA00B64F25 /* FIRSnapshotMetadataTests.mm */; }; 67CF9FAA890307780731E1DA /* task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 899FC22684B0F7BEEAE13527 /* task_test.cc */; }; 6938575C8B5E6FE0D562547A /* exponential_backoff_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D1B68420E2AB1A00B35856 /* exponential_backoff_test.cc */; }; @@ -705,11 +773,13 @@ 6ABB82D43C0728EB095947AF /* geo_point_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB7BAB332012B519001E0872 /* geo_point_test.cc */; }; 6AED40FF444F0ACFE3AE96E3 /* target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C37696557C81A6C2B7271A /* target_cache_test.cc */; }; 6AF739DDA9D33DF756DE7CDE /* autoid_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A521FC913E500713A1A /* autoid_test.cc */; }; + 6B8E8B6C9EFDB3F1F91628A0 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */; }; 6B94E0AE1002C5C9EA0F5582 /* log_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54C2294E1FECABAE007D065B /* log_test.cc */; }; 6BA8753F49951D7AEAD70199 /* watch_change_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2D7472BC70C024D736FF74D9 /* watch_change_test.cc */; }; 6BFB7A4D37F1B7EB5A7461B0 /* memory_query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8EF6A33BC2D84233C355F1D0 /* memory_query_engine_test.cc */; }; 6C143182916AC638707DB854 /* FIRQuerySnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04F202154AA00B64F25 /* FIRQuerySnapshotTests.mm */; }; 6C388B2D0967088758FF2425 /* leveldb_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E76F0CDF28E5FA62D21DE648 /* leveldb_target_cache_test.cc */; }; + 6C415868AE347DC4A26588C3 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */; }; 6C92AD45A3619A18ECCA5B1F /* query_listener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7C3F995E040E9E9C5E8514BB /* query_listener_test.cc */; }; 6D578695E8E03988820D401C /* string_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CFC201A2EE200D97691 /* string_util_test.cc */; }; 6D7F70938662E8CA334F11C2 /* target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C37696557C81A6C2B7271A /* target_cache_test.cc */; }; @@ -721,6 +791,7 @@ 6E7603BC1D8011A5D6F62072 /* credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FA4576525144C5069A7A5 /* credentials_provider_test.cc */; }; 6E8302E021022309003E1EA3 /* FSTFuzzTestFieldPath.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6E8302DF21022309003E1EA3 /* FSTFuzzTestFieldPath.mm */; }; 6E8CD8F545C8EDA84918977C /* index.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 395E8B07639E69290A929695 /* index.pb.cc */; }; + 6EA1C48C20EB8D438893A949 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */; }; 6EA39FDE20FE820E008D461F /* FSTFuzzTestSerializer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6EA39FDD20FE820E008D461F /* FSTFuzzTestSerializer.mm */; }; 6EC28BB8C38E3FD126F68211 /* delayed_constructor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */; }; 6EDD3B4620BF247500C33877 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; @@ -745,6 +816,7 @@ 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; 71E2B154C4FB63F7B7CC4B50 /* target_id_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CF82019382300D97691 /* target_id_generator_test.cc */; }; 722F9A798F39F7D1FE7CF270 /* CodableGeoPointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5495EB022040E90200EBA509 /* CodableGeoPointTests.swift */; }; + 723BBD713478BB26CEFA5A7D /* md5_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = E2E39422953DE1D3C7B97E77 /* md5_testing.cc */; }; 7264B73291F7F1EB454C45B1 /* FIRIndexingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 795AA8FC31D2AF6864B07D39 /* FIRIndexingTests.mm */; }; 7281C2F04838AFFDF6A762DF /* memory_remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1CA9800A53669EFBFFB824E3 /* memory_remote_document_cache_test.cc */; }; 72AD91671629697074F2545B /* ordered_code_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D03201BC6E400D97691 /* ordered_code_test.cc */; }; @@ -762,18 +834,23 @@ 743DF2DF38CE289F13F44043 /* status_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3CAA33F964042646FDDAF9F9 /* status_testing.cc */; }; 7495E3BAE536CD839EE20F31 /* FSTLevelDBSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02C20213FFB00B64F25 /* FSTLevelDBSpecTests.mm */; }; 74985DE2C7EF4150D7A455FD /* statusor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352D20A3B3D7003E0143 /* statusor_test.cc */; }; + 74A63A931F834D1D6CF3BA9A /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */; }; 75A176239B37354588769206 /* FSTUserDataReaderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8D9892F204959C50613F16C8 /* FSTUserDataReaderTests.mm */; }; 75C6CECF607CA94F56260BAB /* memory_document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 29D9C76922DAC6F710BC1EF4 /* memory_document_overlay_cache_test.cc */; }; 75D124966E727829A5F99249 /* FIRTypeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E071202154D600B64F25 /* FIRTypeTests.mm */; }; 76A5447D76F060E996555109 /* task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 899FC22684B0F7BEEAE13527 /* task_test.cc */; }; + 76AD5862714F170251BDEACB /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */; }; + 76C18D1BA96E4F5DF1BF7F4B /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */; }; 76FEBDD2793B729BAD2E84C7 /* index_backfiller_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1F50E872B3F117A674DA8E94 /* index_backfiller_test.cc */; }; 7731E564468645A4A62E2A3C /* leveldb_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54995F6E205B6E12004EFFA0 /* leveldb_key_test.cc */; }; 77BB66DD17A8E6545DE22E0B /* remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7EB299CF85034F09CFD6F3FD /* remote_document_cache_test.cc */; }; 77C36312F8025EC73991D7DA /* index_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 8C7278B604B8799F074F4E8C /* index_spec_test.json */; }; 77C459976DCF7503AEE18F7F /* leveldb_bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8E9CD82E60893DDD7757B798 /* leveldb_bundle_cache_test.cc */; }; + 77C5703230DB77F0540D1F89 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */; }; 77D38E78F7CCB8504450A8FB /* index.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 395E8B07639E69290A929695 /* index.pb.cc */; }; 77D3CF0BE43BC67B9A26B06D /* FIRFieldPathTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04C202154AA00B64F25 /* FIRFieldPathTests.mm */; }; 784FCB02C76096DACCBA11F2 /* bundle.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = A366F6AE1A5A77548485C091 /* bundle.pb.cc */; }; + 78D99CDBB539B0AEE0029831 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */; }; 78E8DDDBE131F3DA9AF9F8B8 /* index.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 395E8B07639E69290A929695 /* index.pb.cc */; }; 795A0E11B3951ACEA2859C8A /* mutation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C8522DE226C467C54E6788D8 /* mutation_test.cc */; }; 79987AF2DF1FCE799008B846 /* CodableGeoPointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5495EB022040E90200EBA509 /* CodableGeoPointTests.swift */; }; @@ -782,6 +859,7 @@ 7A2D523AEF58B1413CC8D64F /* query_engine_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B8A853940305237AFDA8050B /* query_engine_test.cc */; }; 7A3BE0ED54933C234FDE23D1 /* leveldb_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 332485C4DCC6BA0DBB5E31B7 /* leveldb_util_test.cc */; }; 7A66A2CB5CF33F0C28202596 /* status_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352C20A3B3D7003E0143 /* status_test.cc */; }; + 7A7DB86955670B85B4514A1F /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */; }; 7A7EC216A0015D7620B4FF3E /* string_format_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFD366B783AE27B9E79EE7A /* string_format_apple_test.mm */; }; 7A8DF35E7DB4278E67E6BDB3 /* snapshot_version_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */; }; 7AA8771FE1F048D012E5E317 /* query_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 731541602214AFFA0037F4DC /* query_spec_test.json */; }; @@ -793,6 +871,7 @@ 7B8320F12E8092BC86FFCC2C /* fields_array_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA4CBA48204C9E25B56993BC /* fields_array_test.cc */; }; 7B86B1B21FD0EF2A67547F66 /* byte_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5342CDDB137B4E93E2E85CCA /* byte_string_test.cc */; }; 7B8D7BAC1A075DB773230505 /* app_testing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5467FB07203E6A44009C9584 /* app_testing.mm */; }; + 7B9B8C1F5C2FFE063C7B47DC /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */; }; 7BCC5973C4F4FCC272150E31 /* FIRCollectionReferenceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E045202154AA00B64F25 /* FIRCollectionReferenceTests.mm */; }; 7BCF050BA04537B0E7D44730 /* exponential_backoff_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D1B68420E2AB1A00B35856 /* exponential_backoff_test.cc */; }; 7C1DC1B44729381126D083AE /* leveldb_snappy_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D9D94300B9C02F7069523C00 /* leveldb_snappy_test.cc */; }; @@ -800,17 +879,20 @@ 7C7BA1DB0B66EB899A928283 /* hashing_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54511E8D209805F8005BD28F /* hashing_test.cc */; }; 7D25D41B013BB70ADE526055 /* target_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 526D755F65AC676234F57125 /* target_test.cc */; }; 7D320113FD076A1EF9A8B612 /* filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F02F734F272C3C70D1307076 /* filter_test.cc */; }; + 7D3207DEE229EFCF16E52693 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */; }; 7D40C8EB7755138F85920637 /* leveldb_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E76F0CDF28E5FA62D21DE648 /* leveldb_target_cache_test.cc */; }; 7DB0915EF7C22C700A423F7C /* target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C37696557C81A6C2B7271A /* target_cache_test.cc */; }; 7DBE7DB90CF83B589A94980F /* reference_set_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 132E32997D781B896672D30A /* reference_set_test.cc */; }; 7DD67E9621C52B790E844B16 /* FIRDatabaseTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06C202154D500B64F25 /* FIRDatabaseTests.mm */; }; 7DE2560C3B4EF0512F0D538C /* credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FA4576525144C5069A7A5 /* credentials_provider_test.cc */; }; 7DED491019248CE9B9E9EB50 /* FSTLevelDBSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02C20213FFB00B64F25 /* FSTLevelDBSpecTests.mm */; }; + 7E1B1335B2EC566FB25B710C /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */; }; 7E82D412BB56728BEBB7EF46 /* bundle_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C2A94EE24E60543F62CC35 /* bundle_serializer_test.cc */; }; 7E97B0F04E25610FF37E9259 /* memory_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2286F308EFB0534B1BDE05B9 /* memory_target_cache_test.cc */; }; 7EAB3129A58368EE4BD449ED /* leveldb_migrations_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = EF83ACD5E1E9F25845A9ACED /* leveldb_migrations_test.cc */; }; 7EF540911720DAAF516BEDF0 /* query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B9C261C26C5D311E1E3C0CB9 /* query_test.cc */; }; 7EF56BA2A480026D62CCA35A /* logic_utils_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 28B45B2104E2DAFBBF86DBB7 /* logic_utils_test.cc */; }; + 7F5501F917A11DE4E11F5CC7 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */; }; 7F6199159E24E19E2A3F5601 /* schedule_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B0B005A79E765AF02793DCE /* schedule_test.cc */; }; 7F771EB980D9CFAAB4764233 /* view_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5466E7809AD2871FFDE6C76 /* view_testing.cc */; }; 7F9CE96304D413F7E7AA0DA0 /* memory_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2286F308EFB0534B1BDE05B9 /* memory_target_cache_test.cc */; }; @@ -823,12 +905,16 @@ 814724DE70EFC3DDF439CD78 /* executor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4688208F9B9100554BA2 /* executor_test.cc */; }; 816E8E62DC163649BA96951C /* EncodableFieldValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1235769122B7E915007DDFA9 /* EncodableFieldValueTests.swift */; }; 81A6B241E63540900F205817 /* view_snapshot_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC572A9168BBEF7B83E4BBC5 /* view_snapshot_test.cc */; }; + 81AD038D81C1A8C2074B98B1 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */; }; 81AF02881A8D23D02FC202F6 /* bundle_loader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A853C81A6A5A51C9D0389EDA /* bundle_loader_test.cc */; }; 81B23D2D4E061074958AF12F /* target.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE7D20B89AAC00B5BCE7 /* target.pb.cc */; }; 81D1B1D2B66BD8310AC5707F /* string_win_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 79507DF8378D3C42F5B36268 /* string_win_test.cc */; }; 82228CD6CE4A7A9254F8E82D /* leveldb_snappy_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D9D94300B9C02F7069523C00 /* leveldb_snappy_test.cc */; }; 822E5D5EC4955393DF26BC5C /* string_apple_benchmark.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C73C0CC6F62A90D8573F383 /* string_apple_benchmark.mm */; }; + 8230A581857CB46D1C7A5B6A /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */; }; + 8242BB61FBF44B9F5CAC35A7 /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */; }; 82E3634FCF4A882948B81839 /* FIRQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = FF73B39D04D1760190E6B84A /* FIRQueryUnitTests.mm */; }; + 8311F672244D73D810406D7E /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */; }; 8342277EB0553492B6668877 /* leveldb_opener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 75860CD13AF47EB1EA39EC2F /* leveldb_opener_test.cc */; }; 8388418F43042605FB9BFB92 /* testutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352820A3B3BD003E0143 /* testutil.cc */; }; 839D8B502026706419FE09D6 /* leveldb_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 166CE73C03AB4366AAC5201C /* leveldb_index_manager_test.cc */; }; @@ -850,9 +936,11 @@ 86004E06C088743875C13115 /* load_bundle_task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8F1A7B4158D9DD76EE4836BF /* load_bundle_task_test.cc */; }; 8612F3C7E4A7D17221442699 /* grpc_unary_call_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D964942163E63900EB9CFB /* grpc_unary_call_test.cc */; }; 862B1AC9EDAB309BBF4FB18C /* sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA4E20A36DBB00BCEB75 /* sorted_map_test.cc */; }; + 86407DB439A2570F1A670212 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */; }; 86494278BE08F10A8AAF9603 /* iterator_adaptors_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0353420A3D8CB003E0143 /* iterator_adaptors_test.cc */; }; 867B370BF2DF84B6AB94B874 /* filesystem_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA02DA2FCD0001CFC6EB08DA /* filesystem_testing.cc */; }; 8683BBC3AC7B01937606A83B /* firestore.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D421C2DDC800EFB9CC /* firestore.pb.cc */; }; + 86B413EC49E3BBBEBF1FB7A0 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */; }; 86E6FC2B7657C35B342E1436 /* sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA4E20A36DBB00BCEB75 /* sorted_map_test.cc */; }; 8705C4856498F66E471A0997 /* FIRWriteBatchTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06F202154D600B64F25 /* FIRWriteBatchTests.mm */; }; 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; @@ -867,14 +955,20 @@ 8A6C809B9F81C30B7333FCAA /* FIRFirestoreSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6161B5012047140400A99DBB /* FIRFirestoreSourceTests.mm */; }; 8A76A3A8345B984C91B0843E /* schedule_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9B0B005A79E765AF02793DCE /* schedule_test.cc */; }; 8A79DDB4379A063C30A76329 /* iterator_adaptors_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0353420A3D8CB003E0143 /* iterator_adaptors_test.cc */; }; + 8AA50598040531DE8EAFF4BB /* bloom_filter.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */; }; 8AA7A1FCEE6EC309399978AD /* leveldb_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54995F6E205B6E12004EFFA0 /* leveldb_key_test.cc */; }; + 8AE0E09A570FB452460C4495 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */; }; 8B0EC945E74A03BD3ED8F9AA /* status_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3CAA33F964042646FDDAF9F9 /* status_testing.cc */; }; + 8B2921C75DB7DD912AE14B8F /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */; }; 8B31F63673F3B5238DE95AFB /* geo_point_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB7BAB332012B519001E0872 /* geo_point_test.cc */; }; 8B3EB33933D11CF897EAF4C3 /* leveldb_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 166CE73C03AB4366AAC5201C /* leveldb_index_manager_test.cc */; }; 8C39F6D4B3AA9074DF00CFB8 /* string_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CFC201A2EE200D97691 /* string_util_test.cc */; }; 8C602DAD4E8296AB5EFB962A /* firestore.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D421C2DDC800EFB9CC /* firestore.pb.cc */; }; 8C82D4D3F9AB63E79CC52DC8 /* Pods_Firestore_IntegrationTests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECEBABC7E7B693BE808A1052 /* Pods_Firestore_IntegrationTests_iOS.framework */; }; 8D0EF43F1B7B156550E65C20 /* FSTGoogleTestTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */; }; + 8DBA8DC55722ED9D3A1BB2C9 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */; }; + 8E103A426D6E650DC338F281 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */; }; + 8E41D53C77C30372840B0367 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */; }; 8ECDF2AFCF1BCA1A2CDAAD8A /* document_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB6B908320322E4D00CC290A /* document_test.cc */; }; 8F2055702DB5EE8DA4BACD7C /* memory_document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 29D9C76922DAC6F710BC1EF4 /* memory_document_overlay_cache_test.cc */; }; 8F3AE423677A4C50F7E0E5C0 /* database_info_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D92E20235D22000A432D /* database_info_test.cc */; }; @@ -887,6 +981,8 @@ 906DB5C85F57EFCBD2027E60 /* grpc_unary_call_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D964942163E63900EB9CFB /* grpc_unary_call_test.cc */; }; 907DF0E63248DBF0912CC56D /* filesystem_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA02DA2FCD0001CFC6EB08DA /* filesystem_testing.cc */; }; 90B9302B082E6252AF4E7DC7 /* leveldb_migrations_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = EF83ACD5E1E9F25845A9ACED /* leveldb_migrations_test.cc */; }; + 90DE9018DAB7D66DE5EC51DF /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */; }; + 90F75D7C0EA9D9AFC77EE33F /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */; }; 90FE088B8FD9EC06EEED1F39 /* memory_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB5A1E760451189DA36028B3 /* memory_index_manager_test.cc */; }; 911931696309D2EABB325F17 /* strerror_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 358C3B5FE573B1D60A4F7592 /* strerror_test.cc */; }; 913C2DB6951A2ED24778686C /* FIRTransactionOptionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF39ECA1293D21A0A2AB2626 /* FIRTransactionOptionsTests.mm */; }; @@ -903,8 +999,10 @@ 939C898FE9D129F6A2EA259C /* FSTHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E03A2021401F00B64F25 /* FSTHelpers.mm */; }; 93C8F772F4DC5A985FA3D815 /* task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 899FC22684B0F7BEEAE13527 /* task_test.cc */; }; 93E5620E3884A431A14500B0 /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; }; + 945CE2FED66752D9D97AA631 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */; }; 94854FAEAEA75A1AC77A0515 /* memory_bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB4AB1388538CD3CB19EB028 /* memory_bundle_cache_test.cc */; }; 94BBB23B93E449D03FA34F87 /* mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3068AA9DFBBA86C1FE2A946E /* mutation_queue_test.cc */; }; + 94C86F03FF86690307F28182 /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */; }; 95C0F55813DA51E6B8C439E1 /* status_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5493A423225F9990006DE7BA /* status_apple_test.mm */; }; 95CE3F5265B9BB7297EE5A6B /* lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 277EAACC4DD7C21332E8496A /* lru_garbage_collector_test.cc */; }; 95DCD082374F871A86EF905F /* to_string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = B68B1E002213A764008977EF /* to_string_apple_test.mm */; }; @@ -925,7 +1023,9 @@ 98FE82875A899A40A98AAC22 /* leveldb_opener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 75860CD13AF47EB1EA39EC2F /* leveldb_opener_test.cc */; }; 990EC10E92DADB7D86A4BEE3 /* string_format_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54131E9620ADE678001DF3FF /* string_format_test.cc */; }; 992DD6779C7A166D3A22E749 /* firebase_app_check_credentials_provider_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F119BDDF2F06B3C0883B8297 /* firebase_app_check_credentials_provider_test.mm */; }; + 9966167103B9714723A88669 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */; }; 9A29D572C64CA1FA62F591D4 /* FIRQueryTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E069202154D500B64F25 /* FIRQueryTests.mm */; }; + 9A75A9413ED1D994DC6F37C6 /* bloom_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */; }; 9A7CF567C6FF0623EB4CFF64 /* datastore_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3167BD972EFF8EC636530E59 /* datastore_test.cc */; }; 9A8B01AF6F19D248202FBC0A /* FIRQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = FF73B39D04D1760190E6B84A /* FIRQueryUnitTests.mm */; }; 9AC28D928902C6767A11F5FC /* objc_type_traits_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A0CF41BA5AED6049B0BEB2C /* objc_type_traits_apple_test.mm */; }; @@ -937,6 +1037,7 @@ 9C1F25177DC5753B075DCF65 /* existence_filter_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129D1F315EE100DD57A1 /* existence_filter_spec_test.json */; }; 9C366448F9BA7A4AC0821AF7 /* bundle_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 79EAA9F7B1B9592B5F053923 /* bundle_spec_test.json */; }; 9C86EEDEA131BFD50255EEF1 /* comparison_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 548DB928200D59F600E00ABC /* comparison_test.cc */; }; + 9CC32ACF397022BB7DF11B52 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */; }; 9CE07BAAD3D3BC5F069D38FE /* grpc_streaming_reader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D964922154AB8F00EB9CFB /* grpc_streaming_reader_test.cc */; }; 9D71628E38D9F64C965DF29E /* FSTAPIHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04E202154AA00B64F25 /* FSTAPIHelpers.mm */; }; 9E656F4FE92E8BFB7F625283 /* to_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B696858D2214B53900271095 /* to_string_test.cc */; }; @@ -947,10 +1048,13 @@ A05BC6BDA2ABE405009211A9 /* target_id_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CF82019382300D97691 /* target_id_generator_test.cc */; }; A06FBB7367CDD496887B86F8 /* leveldb_opener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 75860CD13AF47EB1EA39EC2F /* leveldb_opener_test.cc */; }; A0C6C658DFEE58314586907B /* offline_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A11F315EE100DD57A1 /* offline_spec_test.json */; }; + A0D61250F959BC52CEFF9467 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */; }; A0E1C7F5C7093A498F65C5CF /* memory_bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB4AB1388538CD3CB19EB028 /* memory_bundle_cache_test.cc */; }; + A0ED6C684A58A0077A5F9606 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */; }; A124744C6CBEF3DD415A1A72 /* FSTUserDataReaderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8D9892F204959C50613F16C8 /* FSTUserDataReaderTests.mm */; }; A1563EFEB021936D3FFE07E3 /* field_mask_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5320A36E1F00BCEB75 /* field_mask_test.cc */; }; A17DBC8F24127DA8A381F865 /* testutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352820A3B3BD003E0143 /* testutil.cc */; }; + A186FECD0257B92FDB0E83B8 /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */; }; A192648233110B7B8BD65528 /* field_transform_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7515B47C92ABEEC66864B55C /* field_transform_test.cc */; }; A1F57CC739211F64F2E9232D /* hard_assert_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 444B7AB3F5A2929070CB1363 /* hard_assert_test.cc */; }; A215078DBFBB5A4F4DADE8A9 /* leveldb_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 166CE73C03AB4366AAC5201C /* leveldb_index_manager_test.cc */; }; @@ -958,6 +1062,7 @@ A25FF76DEF542E01A2DF3B0E /* time_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5497CB76229DECDE000FB92F /* time_testing.cc */; }; A27096F764227BC73526FED3 /* leveldb_remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0840319686A223CC4AD3FAB1 /* leveldb_remote_document_cache_test.cc */; }; A27908A198E1D2230C1801AC /* bundle_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C2A94EE24E60543F62CC35 /* bundle_serializer_test.cc */; }; + A2E9978E02F7BCB016555F09 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */; }; A3262936317851958C8EABAF /* byte_stream_cpp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 01D10113ECC5B446DB35E96D /* byte_stream_cpp_test.cc */; }; A4757C171D2407F61332EA38 /* byte_stream_cpp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 01D10113ECC5B446DB35E96D /* byte_stream_cpp_test.cc */; }; A478FDD7C3F48FBFDDA7D8F5 /* leveldb_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5C7942B6244F4C416B11B86C /* leveldb_mutation_queue_test.cc */; }; @@ -977,9 +1082,12 @@ A6BDA28DBC85BC1BAB7061F4 /* leveldb_document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE89CFF09C6804573841397F /* leveldb_document_overlay_cache_test.cc */; }; A6D57EC3A0BF39060705ED29 /* string_format_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CFD366B783AE27B9E79EE7A /* string_format_apple_test.mm */; }; A6E236CE8B3A47BE32254436 /* array_sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54EB764C202277B30088B8F3 /* array_sorted_map_test.cc */; }; + A728A4D7FA17F9F3257E0002 /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */; }; A7309DAD4A3B5334536ECA46 /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; }; A7399FB3BEC50BBFF08EC9BA /* mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3068AA9DFBBA86C1FE2A946E /* mutation_queue_test.cc */; }; A80D38096052F928B17E1504 /* user_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CCC9BD953F121B9E29F9AA42 /* user_test.cc */; }; + A833A216988ADFD4876763CD /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */; }; + A841EEB5A94A271523EAE459 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */; }; A873EE3C8A97C90BA978B68A /* firebase_app_check_credentials_provider_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F119BDDF2F06B3C0883B8297 /* firebase_app_check_credentials_provider_test.mm */; }; A8AF92A35DFA30EEF9C27FB7 /* database_info_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D92E20235D22000A432D /* database_info_test.cc */; }; A8C9FF6D13E6C83D4AB54EA7 /* secure_random_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54740A531FC913E500713A1A /* secure_random_test.cc */; }; @@ -988,6 +1096,7 @@ A97ED2BAAEDB0F765BBD5F98 /* local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 307FF03D0297024D59348EBD /* local_store_test.cc */; }; A9A9994FB8042838671E8506 /* view_snapshot_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CC572A9168BBEF7B83E4BBC5 /* view_snapshot_test.cc */; }; AA13B6E1EF0AD9E9857AAE1C /* byte_stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 432C71959255C5DBDF522F52 /* byte_stream_test.cc */; }; + AA859F27A9098D6886B222A8 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */; }; AAC15E7CCAE79619B2ABB972 /* XCTestCase+Await.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E0372021401E00B64F25 /* XCTestCase+Await.mm */; }; AAF2F02E77A80C9CDE2C0C7A /* filesystem_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F51859B394D01C0C507282F1 /* filesystem_test.cc */; }; AAFA9D7A0A067F2D3D8D5487 /* token_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A082AFDD981B07B5AD78FDE8 /* token_test.cc */; }; @@ -1007,10 +1116,12 @@ ABF6506C201131F8005F2C74 /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; }; ABFD599019CF312CFF96B3EC /* perf_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = D5B2593BCB52957D62F1C9D3 /* perf_spec_test.json */; }; AC03C4F1456FB1C0D88E94FF /* query_listener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7C3F995E040E9E9C5E8514BB /* query_listener_test.cc */; }; + AC44D6363F57CEAAB291ED49 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */; }; AC6B856ACB12BB28D279693D /* random_access_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 014C60628830D95031574D15 /* random_access_queue_test.cc */; }; AC6C1E57B18730428CB15E03 /* executor_libdispatch_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4689208F9B9100554BA2 /* executor_libdispatch_test.mm */; }; AC835157AD2BE7AA8D20FB5A /* ConditionalConformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3228F51DCDC2E90D5C58F97 /* ConditionalConformanceTests.swift */; }; ACC9369843F5ED3BD2284078 /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; }; + AD00D000A63837FB47291BFE /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */; }; AD12205540893CEB48647937 /* filesystem_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA02DA2FCD0001CFC6EB08DA /* filesystem_testing.cc */; }; AD35AA07F973934BA30C9000 /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; }; AD3C26630E33BE59C49BEB0D /* grpc_unary_call_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D964942163E63900EB9CFB /* grpc_unary_call_test.cc */; }; @@ -1020,24 +1131,32 @@ AE068EDBC74AF27679CCB6DA /* FIRBundlesTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 776530F066E788C355B78457 /* FIRBundlesTests.mm */; }; AE0CFFC34A423E1B80D07418 /* resource_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2B02024FFD70028D6BE /* resource_path_test.cc */; }; AE5E5E4A7BF12C2337AFA13B /* bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F7FC06E0A47D393DE1759AE1 /* bundle_cache_test.cc */; }; + AEA092BBCA736A1CDC741143 /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */; }; AEBF3F80ACC01AA8A27091CD /* FSTIntegrationTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5491BC711FB44593008B3588 /* FSTIntegrationTestCase.mm */; }; AECCD9663BB3DC52199F954A /* executor_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4687208F9B9100554BA2 /* executor_std_test.cc */; }; AEE9105543013C9C89FAB2B5 /* create_noop_connectivity_monitor.cc in Sources */ = {isa = PBXBuildFile; fileRef = CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */; }; + AF450AFDF88C23E0121B34A1 /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */; }; AF4CD9DB5A7D4516FC54892B /* leveldb_lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B629525F7A1AAC1AB765C74F /* leveldb_lru_garbage_collector_test.cc */; }; AF6D6C47F9A25C65BFDCBBA0 /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; }; AF81B6A91987826426F18647 /* remote_store_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 3B843E4A1F3930A400548890 /* remote_store_spec_test.json */; }; AFB0ACCF130713DF6495E110 /* writer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BC3C788D290A935C353CEAA1 /* writer_test.cc */; }; AFB2455806D7C4100C16713B /* object_value_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 214877F52A705012D6720CA0 /* object_value_test.cc */; }; + AFCA3C24AA751B5B2D3E6FEF /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */; }; AFE84E7B0C356CD2A113E56E /* status_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3CAA33F964042646FDDAF9F9 /* status_testing.cc */; }; + AFF7D2CF35B51656E4744164 /* bloom_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */; }; B03F286F3AEC3781C386C646 /* FIRNumericTransformTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = D5B25E7E7D6873CBA4571841 /* FIRNumericTransformTests.mm */; }; B04E4FE20930384DF3A402F9 /* aggregate_query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AF924C79F49F793992A84879 /* aggregate_query_test.cc */; }; B0B779769926304268200015 /* query_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 731541602214AFFA0037F4DC /* query_spec_test.json */; }; B0D10C3451EDFB016A6EAF03 /* writer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BC3C788D290A935C353CEAA1 /* writer_test.cc */; }; + B0E745EAC5F37CA61F868F38 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */; }; B15D17049414E2F5AE72C9C6 /* memory_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F6CA0C5638AB6627CB5B4CF4 /* memory_local_store_test.cc */; }; + B188D7EC9A100F365DB02490 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */; }; B192F30DECA8C28007F9B1D0 /* array_sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54EB764C202277B30088B8F3 /* array_sorted_map_test.cc */; }; B220E091D8F4E6DE1EA44F57 /* executor_libdispatch_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4689208F9B9100554BA2 /* executor_libdispatch_test.mm */; }; B235E260EA0DCB7BAC04F69B /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; }; + B2554A2BA211D10823646DBE /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */; }; B28ACC69EB1F232AE612E77B /* async_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 872C92ABD71B12784A1C5520 /* async_testing.cc */; }; + B2A9965ED0114E39A911FD09 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */; }; B371628DA91E80B64AE53085 /* FIRFieldPathTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04C202154AA00B64F25 /* FIRFieldPathTests.mm */; }; B384E0F90D4CCC15C88CAF30 /* target_index_matcher_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */; }; B3A309CCF5D75A555C7196E1 /* path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 403DBF6EFB541DFD01582AA3 /* path_test.cc */; }; @@ -1046,14 +1165,18 @@ B3E6F4CDB1663407F0980C7A /* target.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE7D20B89AAC00B5BCE7 /* target.pb.cc */; }; B3F3DCA51819F1A213E00D9C /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; }; B40EDE2B1B228ED59CF62788 /* byte_stream_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7628664347B9C96462D4BF17 /* byte_stream_apple_test.mm */; }; + B41B17163DD9A421F35DE1A9 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */; }; B43014A0517F31246419E08A /* resume_token_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A41F315EE100DD57A1 /* resume_token_spec_test.json */; }; B46E778F9E40864B5D2B2F1C /* leveldb_transaction_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */; }; + B491EF0E70DC0542644F623E /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */; }; B4C675BE9030D5C7D19C4D19 /* ordered_code_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D03201BC6E400D97691 /* ordered_code_test.cc */; }; + B4F544C50B4472268A2E633B /* bloom_filter.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */; }; B513F723728E923DFF34F60F /* leveldb_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54995F6E205B6E12004EFFA0 /* leveldb_key_test.cc */; }; B54BA1E76636C0C93334271B /* settings_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DD12BC1DB2480886D2FB0005 /* settings_test.cc */; }; B576823475FBCA5EFA583F9C /* leveldb_migrations_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = EF83ACD5E1E9F25845A9ACED /* leveldb_migrations_test.cc */; }; B592DB7DB492B1C1D5E67D01 /* write.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D921C2DDC800EFB9CC /* write.pb.cc */; }; B5AEF7E4EBC29653DEE856A2 /* strerror_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 358C3B5FE573B1D60A4F7592 /* strerror_test.cc */; }; + B60BAF9ED610F9D4E245EEB3 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */; }; B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; }; B63D84B2980C7DEE7E6E4708 /* view_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C7429071B33BDF80A7FA2F8A /* view_test.cc */; }; B65D34A9203C995B0076A5E1 /* FIRTimestampTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */; }; @@ -1091,6 +1214,7 @@ B921A4F35B58925D958DD9A6 /* reference_set_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 132E32997D781B896672D30A /* reference_set_test.cc */; }; B9706A5CD29195A613CF4147 /* bundle_reader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6ECAF7DE28A19C69DF386D88 /* bundle_reader_test.cc */; }; B99452AB7E16B72D1C01FBBC /* datastore_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3167BD972EFF8EC636530E59 /* datastore_test.cc */; }; + B998971CE6D0D1DD2AD9250A /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */; }; BA0BB02821F1949783C8AA50 /* FIRCollectionReferenceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E045202154AA00B64F25 /* FIRCollectionReferenceTests.mm */; }; BA1C5EAE87393D8E60F5AE6D /* fake_target_metadata_provider.cc in Sources */ = {isa = PBXBuildFile; fileRef = 71140E5D09C6E76F7C71B2FC /* fake_target_metadata_provider.cc */; }; BA3C0BA8082A6FB2546E47AC /* CodableTimestampTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B65C996438B84DBC7616640 /* CodableTimestampTests.swift */; }; @@ -1104,10 +1228,13 @@ BBDFE0000C4D7E529E296ED4 /* mutation.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE8220B89AAC00B5BCE7 /* mutation.pb.cc */; }; BC0C98A9201E8F98B9A176A9 /* FIRWriteBatchTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06F202154D600B64F25 /* FIRWriteBatchTests.mm */; }; BC2D0A8EA272A0058F6C2B9E /* FIRFirestoreSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6161B5012047140400A99DBB /* FIRFirestoreSourceTests.mm */; }; + BC4249D72DDB23A04EF272F9 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */; }; BC549E3F3F119D80741D8612 /* leveldb_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 332485C4DCC6BA0DBB5E31B7 /* leveldb_util_test.cc */; }; BC5AC8890974E0821431267E /* limit_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA129F1F315EE100DD57A1 /* limit_spec_test.json */; }; BC8DFBCB023DBD914E27AA7D /* query_listener_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7C3F995E040E9E9C5E8514BB /* query_listener_test.cc */; }; BCA720A0F54D23654F806323 /* ConditionalConformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3228F51DCDC2E90D5C58F97 /* ConditionalConformanceTests.swift */; }; + BCAC9F7A865BD2320A4D8752 /* bloom_filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */; }; + BD3A421C9E40C57D25697E75 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */; }; BD6CC8614970A3D7D2CF0D49 /* exponential_backoff_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D1B68420E2AB1A00B35856 /* exponential_backoff_test.cc */; }; BDD2D1812BAD962E3C81A53F /* hashing_test_apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = B69CF3F02227386500B281C8 /* hashing_test_apple.mm */; }; BDDAE67000DBF10E9EA7FED0 /* nanopb_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6F5B6C1399F92FD60F2C582B /* nanopb_util_test.cc */; }; @@ -1119,6 +1246,7 @@ BEF0365AD2718B8B70715978 /* statusor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352D20A3B3D7003E0143 /* statusor_test.cc */; }; BEF35ECEE80F9F5161E7743A /* filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F02F734F272C3C70D1307076 /* filter_test.cc */; }; BFBE4732E93E38317B110778 /* index_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 8C7278B604B8799F074F4E8C /* index_spec_test.json */; }; + BFCDC78CD851F109EB7A1422 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */; }; BFEAC4151D3AA8CE1F92CC2D /* FSTSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E03020213FFC00B64F25 /* FSTSpecTests.mm */; }; C02A969BF4BB63ABCB531B4B /* create_noop_connectivity_monitor.cc in Sources */ = {isa = PBXBuildFile; fileRef = CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */; }; C06E54352661FCFB91968640 /* mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3068AA9DFBBA86C1FE2A946E /* mutation_queue_test.cc */; }; @@ -1130,14 +1258,18 @@ C15F5F1E7427738F20C2D789 /* offline_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A11F315EE100DD57A1 /* offline_spec_test.json */; }; C19214F5B43AA745A7FC2FC1 /* maybe_document.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE7E20B89AAC00B5BCE7 /* maybe_document.pb.cc */; }; C1B4621C0820EEB0AC9CCD22 /* bits_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D01201BC69F00D97691 /* bits_test.cc */; }; + C1C3369C7ECE069B76A84AD1 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */; }; C1CD78F1FDE0918B4F87BC6F /* empty_credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8FA60B08D59FEA0D6751E87F /* empty_credentials_provider_test.cc */; }; C1E35BCE2CFF9B56C28545A2 /* Pods_Firestore_Example_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62E103B28B48A81D682A0DE9 /* Pods_Firestore_Example_tvOS.framework */; }; C1F196EC5A7C112D2F7C7724 /* view_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C7429071B33BDF80A7FA2F8A /* view_test.cc */; }; C1F8991BD11FFD705D74244F /* random_access_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 014C60628830D95031574D15 /* random_access_queue_test.cc */; }; + C20151B20ACE518267B4850C /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */; }; C201BE60B8717CDCBEEDF3F0 /* testing_hooks_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */; }; C21B3A1CCB3AD42E57EA14FC /* Pods_Firestore_Tests_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 759E964B6A03E6775C992710 /* Pods_Firestore_Tests_macOS.framework */; }; C23552A6D9FB0557962870C2 /* local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 307FF03D0297024D59348EBD /* local_store_test.cc */; }; + C240DB0498C1C84C6AFA4C8D /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */; }; C25F321AC9BF8D1CFC8543AF /* reference_set_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 132E32997D781B896672D30A /* reference_set_test.cc */; }; + C2E0C68B2EA6FA3683F4EE94 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */; }; C393D6984614D8E4D8C336A2 /* mutation.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE8220B89AAC00B5BCE7 /* mutation.pb.cc */; }; C39CBADA58F442C8D66C3DA2 /* FIRFieldPathTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04C202154AA00B64F25 /* FIRFieldPathTests.mm */; }; C3E4EE9615367213A71FEECF /* filesystem_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA02DA2FCD0001CFC6EB08DA /* filesystem_testing.cc */; }; @@ -1152,6 +1284,7 @@ C5655568EC2A9F6B5E6F9141 /* firestore.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D421C2DDC800EFB9CC /* firestore.pb.cc */; }; C57B15CADD8C3E806B154C19 /* task_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 899FC22684B0F7BEEAE13527 /* task_test.cc */; }; C5F1E2220E30ED5EAC9ABD9E /* mutation.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE8220B89AAC00B5BCE7 /* mutation.pb.cc */; }; + C602E27459408B90A0DF2AA0 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */; }; C663A8B74B57FD84717DEA21 /* delayed_constructor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */; }; C6BF529243414C53DF5F1012 /* memory_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F6CA0C5638AB6627CB5B4CF4 /* memory_local_store_test.cc */; }; C71AD99EE8D176614E742FD7 /* string_apple_benchmark.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C73C0CC6F62A90D8573F383 /* string_apple_benchmark.mm */; }; @@ -1159,6 +1292,7 @@ C7F3C6F569BBA904477F011C /* memory_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2286F308EFB0534B1BDE05B9 /* memory_target_cache_test.cc */; }; C80B10E79CDD7EF7843C321E /* objc_type_traits_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2A0CF41BA5AED6049B0BEB2C /* objc_type_traits_apple_test.mm */; }; C840AD39F7EC5524F1C0F5AE /* filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F02F734F272C3C70D1307076 /* filter_test.cc */; }; + C86E85101352B5CDBF5909F9 /* md5_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D050936A2D52257FD17FB6E /* md5_test.cc */; }; C8722550B56CEB96F84DCE94 /* target_index_matcher_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */; }; C8A573895D819A92BF16B5E5 /* mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3068AA9DFBBA86C1FE2A946E /* mutation_queue_test.cc */; }; C8BA36C8B5E26C173F91E677 /* aggregation_result.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = D872D754B8AD88E28AF28B28 /* aggregation_result.pb.cc */; }; @@ -1167,7 +1301,11 @@ C8D3CE2343E53223E6487F2C /* Pods_Firestore_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5918805E993304321A05E82B /* Pods_Firestore_Example_iOS.framework */; }; C901A1BFD553B6DD70BB7CC7 /* bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F7FC06E0A47D393DE1759AE1 /* bundle_cache_test.cc */; }; C961FA581F87000DF674BBC8 /* field_transform_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7515B47C92ABEEC66864B55C /* field_transform_test.cc */; }; + C97CD9EA59E9BBEFE17E94D6 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */; }; + C985030E45AB19081D0273BE /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */; }; + C9C9A92E1734A097BE0670AF /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */; }; C9F96C511F45851D38EC449C /* status.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE9920B89AAC00B5BCE7 /* status.pb.cc */; }; + CA2392732BA7F8985699313D /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */; }; CA989C0E6020C372A62B7062 /* testutil.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352820A3B3BD003E0143 /* testutil.cc */; }; CAFB1E0ED514FEF4641E3605 /* log_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54C2294E1FECABAE007D065B /* log_test.cc */; }; CB2C731116D6C9464220626F /* FIRQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = FF73B39D04D1760190E6B84A /* FIRQueryUnitTests.mm */; }; @@ -1190,6 +1328,7 @@ CFA4A635ECD105D2044B3692 /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3355BE9391CC4857AF0BDAE3 /* DatabaseTests.swift */; }; CFCDC4670C61E034021F400B /* perf_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = D5B2593BCB52957D62F1C9D3 /* perf_spec_test.json */; }; CFF1EBC60A00BA5109893C6E /* memory_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB5A1E760451189DA36028B3 /* memory_index_manager_test.cc */; }; + D00B06FD0F20D09C813547F4 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */; }; D00E69F7FDF2BE674115AD3F /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; }; D04CBBEDB8DC16D8C201AC49 /* leveldb_target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E76F0CDF28E5FA62D21DE648 /* leveldb_target_cache_test.cc */; }; D0DA42DC66C4FE508A63B269 /* testing_hooks_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */; }; @@ -1202,12 +1341,15 @@ D22B96C19A0F3DE998D4320C /* delayed_constructor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */; }; D2A7E03E0E64AA93E0357A0E /* settings_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DD12BC1DB2480886D2FB0005 /* settings_test.cc */; }; D2A96D452AF6426C491AF931 /* DatabaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3355BE9391CC4857AF0BDAE3 /* DatabaseTests.swift */; }; + D2C486D904E08CC41E409695 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */; }; + D3180BF788CA5EBA9FCB58FB /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */; }; D377FA653FB976FB474D748C /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; }; D39F0216BF1EA8CD54C76CF8 /* FIRQueryUnitTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = FF73B39D04D1760190E6B84A /* FIRQueryUnitTests.mm */; }; D3B470C98ACFAB7307FB3800 /* datastore_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3167BD972EFF8EC636530E59 /* datastore_test.cc */; }; D3CB03747E34D7C0365638F1 /* transform_operation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 33607A3AE91548BD219EC9C6 /* transform_operation_test.cc */; }; D4572060A0FD4D448470D329 /* leveldb_transaction_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */; }; D4D8BA32ACC5C2B1B29711C0 /* memory_lru_garbage_collector_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9765D47FA12FA283F4EFAD02 /* memory_lru_garbage_collector_test.cc */; }; + D4F85AEACD2FD03C738D1052 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */; }; D50232D696F19C2881AC01CE /* token_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A082AFDD981B07B5AD78FDE8 /* token_test.cc */; }; D550446303227FB1B381133C /* FSTAPIHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04E202154AA00B64F25 /* FSTAPIHelpers.mm */; }; D560F39EA365CDE1E8C5DE33 /* empty_credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8FA60B08D59FEA0D6751E87F /* empty_credentials_provider_test.cc */; }; @@ -1216,13 +1358,16 @@ D5B252EE3F4037405DB1ECE3 /* FIRNumericTransformTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = D5B25E7E7D6873CBA4571841 /* FIRNumericTransformTests.mm */; }; D5B25CBF07F65E885C9D68AB /* perf_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = D5B2593BCB52957D62F1C9D3 /* perf_spec_test.json */; }; D5E9954FC1C5ABBC7A180B33 /* FSTSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E03020213FFC00B64F25 /* FSTSpecTests.mm */; }; + D5F6AAA1A1B9AE84205ECE27 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */; }; D6486C7FFA8BE6F9C7D2F4C4 /* filesystem_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F51859B394D01C0C507282F1 /* filesystem_test.cc */; }; D658E6DA5A218E08810E1688 /* byte_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5342CDDB137B4E93E2E85CCA /* byte_string_test.cc */; }; D6962E598CEDABA312D87760 /* bundle_reader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6ECAF7DE28A19C69DF386D88 /* bundle_reader_test.cc */; }; D69B97FF4C065EACEDD91886 /* FSTSyncEngineTestDriver.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02E20213FFC00B64F25 /* FSTSyncEngineTestDriver.mm */; }; D6DE74259F5C0CCA010D6A0D /* grpc_stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6BBE42F21262CF400C6A53E /* grpc_stream_test.cc */; }; D6E0E54CD1640E726900828A /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; }; + D6FF8D248C0D21164071B1C4 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */; }; D711B3F495923680B6FC2FC6 /* object_value_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 214877F52A705012D6720CA0 /* object_value_test.cc */; }; + D7229A3A0B37AF4B18052A17 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */; }; D73BBA4AB42940AB187169E3 /* listen_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A01F315EE100DD57A1 /* listen_spec_test.json */; }; D756A1A63E626572EE8DF592 /* firestore.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D421C2DDC800EFB9CC /* firestore.pb.cc */; }; D77941FD93DBE862AEF1F623 /* FSTTransactionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E07B202154EB00B64F25 /* FSTTransactionTests.mm */; }; @@ -1236,6 +1381,7 @@ DA1D665B12AA1062DCDEA6BD /* async_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB467B208E9A8200554BA2 /* async_queue_test.cc */; }; DA4303684707606318E1914D /* target_id_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CF82019382300D97691 /* target_id_generator_test.cc */; }; DABB9FB61B1733F985CBF713 /* executor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4688208F9B9100554BA2 /* executor_test.cc */; }; + DAD462C948703A1834328E19 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */; }; DAFF0CF921E64AC30062958F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DAFF0CF821E64AC30062958F /* AppDelegate.m */; }; DAFF0CFB21E64AC40062958F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DAFF0CFA21E64AC40062958F /* Assets.xcassets */; }; DAFF0CFE21E64AC40062958F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = DAFF0CFC21E64AC40062958F /* MainMenu.xib */; }; @@ -1250,12 +1396,15 @@ DC1C711290E12F8EF3601151 /* array_sorted_map_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54EB764C202277B30088B8F3 /* array_sorted_map_test.cc */; }; DC48407370E87F2233D7AB7E /* statusor_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0352D20A3B3D7003E0143 /* statusor_test.cc */; }; DC6804424FC8F7B3044DD0BB /* random_access_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 014C60628830D95031574D15 /* random_access_queue_test.cc */; }; + DCC8F3D4AA87C81AB3FD9491 /* md5_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D050936A2D52257FD17FB6E /* md5_test.cc */; }; DCD83C545D764FB15FD88B02 /* counting_query_engine.cc in Sources */ = {isa = PBXBuildFile; fileRef = 99434327614FEFF7F7DC88EC /* counting_query_engine.cc */; }; DD04F7FE7A1ADE230A247DBC /* byte_stream_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7628664347B9C96462D4BF17 /* byte_stream_apple_test.mm */; }; + DD0F288108714D5A406D0A9F /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */; }; DD213F68A6F79E1D4924BD95 /* Pods_Firestore_Example_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E42355285B9EF55ABD785792 /* Pods_Firestore_Example_macOS.framework */; }; DD5976A45071455FF3FE74B8 /* string_win_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 79507DF8378D3C42F5B36268 /* string_win_test.cc */; }; DD6C480629B3F87933FAF440 /* filesystem_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA02DA2FCD0001CFC6EB08DA /* filesystem_testing.cc */; }; DD935E243A64A4EB688E4C1C /* credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FA4576525144C5069A7A5 /* credentials_provider_test.cc */; }; + DD941BF189E38312E7A2CB21 /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */; }; DDD219222EEE13E3F9F2C703 /* leveldb_transaction_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */; }; DDDE74C752E65DE7D39A7166 /* view_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5466E7809AD2871FFDE6C76 /* view_testing.cc */; }; DE03B2D41F2149D600A30B9C /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; }; @@ -1271,6 +1420,7 @@ DF7ABEB48A650117CBEBCD26 /* object_value_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 214877F52A705012D6720CA0 /* object_value_test.cc */; }; DF96816EC67F9B8DF19B0CFD /* document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = FFCA39825D9678A03D1845D0 /* document_overlay_cache_test.cc */; }; DF983A9C1FBF758AF3AF110D /* aggregation_result.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = D872D754B8AD88E28AF28B28 /* aggregation_result.pb.cc */; }; + E042112665DD2504E3F495D5 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */; }; E04607A1E2964684184E8AEA /* index_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 8C7278B604B8799F074F4E8C /* index_spec_test.json */; }; E08297B35E12106105F448EB /* ordered_code_benchmark.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0473AFFF5567E667A125347B /* ordered_code_benchmark.cc */; }; E084921EFB7CF8CB1E950D6C /* iterator_adaptors_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54A0353420A3D8CB003E0143 /* iterator_adaptors_test.cc */; }; @@ -1283,12 +1433,14 @@ E21D819A06D9691A4B313440 /* remote_store_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 3B843E4A1F3930A400548890 /* remote_store_spec_test.json */; }; E25DCFEF318E003B8B7B9DC8 /* index_backfiller_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1F50E872B3F117A674DA8E94 /* index_backfiller_test.cc */; }; E27C0996AF6EC6D08D91B253 /* document.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D821C2DDC800EFB9CC /* document.pb.cc */; }; + E2AC3BDAAFFF9A45C916708B /* md5_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = E2E39422953DE1D3C7B97E77 /* md5_testing.cc */; }; E2AE851F9DC4C037CCD05E36 /* remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7EB299CF85034F09CFD6F3FD /* remote_document_cache_test.cc */; }; E2B15548A3B6796CE5A01975 /* FIRListenerRegistrationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06B202154D500B64F25 /* FIRListenerRegistrationTests.mm */; }; E2B7AEDCAAC5AD74C12E85C1 /* datastore_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3167BD972EFF8EC636530E59 /* datastore_test.cc */; }; E30BF9E316316446371C956C /* persistence_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9113B6F513D0473AEABBAF1F /* persistence_testing.cc */; }; E3319DC1804B69F0ED1FFE02 /* memory_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 74FBEFA4FE4B12C435011763 /* memory_mutation_queue_test.cc */; }; E375FBA0632EFB4D14C4E5A9 /* FSTGoogleTestTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 54764FAE1FAA21B90085E60A /* FSTGoogleTestTests.mm */; }; + E37C52277CD00C57E5848A0E /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */; }; E434ACDF63F219F3031F292E /* ConditionalConformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3228F51DCDC2E90D5C58F97 /* ConditionalConformanceTests.swift */; }; E435450184AEB51EE8435F66 /* write.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D921C2DDC800EFB9CC /* write.pb.cc */; }; E441A53D035479C53C74A0E6 /* recovery_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 9C1AFCC9E616EC33D6E169CF /* recovery_spec_test.json */; }; @@ -1296,18 +1448,24 @@ E500AB82DF2E7F3AFDB1AB3F /* to_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B696858D2214B53900271095 /* to_string_test.cc */; }; E50187548B537DBCDBF7F9F0 /* string_util_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CFC201A2EE200D97691 /* string_util_test.cc */; }; E51957EDECF741E1D3C3968A /* writer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BC3C788D290A935C353CEAA1 /* writer_test.cc */; }; + E54AC3EA240C05B3720A2FE9 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */; }; E56EEC9DAC455E2BE77D110A /* memory_document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 29D9C76922DAC6F710BC1EF4 /* memory_document_overlay_cache_test.cc */; }; + E59F597947D3E130A57E1B5E /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */; }; E63342115B1DA65DB6F2C59A /* leveldb_local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5FF903AEFA7A3284660FA4C5 /* leveldb_local_store_test.cc */; }; E6357221227031DD77EE5265 /* index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE4A9E38D65688EE000EE2A1 /* index_manager_test.cc */; }; + E666F0B9FD141F87AA5C87AC /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */; }; E6688C8E524770A3C6EBB33A /* write_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A51F315EE100DD57A1 /* write_spec_test.json */; }; E681BD94D45BCAC7BE2A99A4 /* bundle_serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C2A94EE24E60543F62CC35 /* bundle_serializer_test.cc */; }; E6821243C510797EFFC7BCE2 /* grpc_streaming_reader_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D964922154AB8F00EB9CFB /* grpc_streaming_reader_test.cc */; }; E688620D4578F1F7FBB1AF9C /* EncodableFieldValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1235769122B7E915007DDFA9 /* EncodableFieldValueTests.swift */; }; E6B825EE85BF20B88AF3E3CD /* memory_index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = DB5A1E760451189DA36028B3 /* memory_index_manager_test.cc */; }; E6F8EB02A0E499F25160BB40 /* FIRFieldPathTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04C202154AA00B64F25 /* FIRFieldPathTests.mm */; }; + E72A77095FF6814267DF0F6D /* md5_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = E2E39422953DE1D3C7B97E77 /* md5_testing.cc */; }; + E74D6C1056DE29969B5C4C62 /* md5_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3D050936A2D52257FD17FB6E /* md5_test.cc */; }; E764F0F389E7119220EB212C /* target_id_generator_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380CF82019382300D97691 /* target_id_generator_test.cc */; }; E7CE4B1ECD008983FAB90F44 /* string_format_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 54131E9620ADE678001DF3FF /* string_format_test.cc */; }; E7D415B8717701B952C344E5 /* executor_std_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6FB4687208F9B9100554BA2 /* executor_std_test.cc */; }; + E827A3B15D6C8C1298A7BC72 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */; }; E82F8EBBC8CC37299A459E73 /* hashing_test_apple.mm in Sources */ = {isa = PBXBuildFile; fileRef = B69CF3F02227386500B281C8 /* hashing_test_apple.mm */; }; E8495A8D1E11C0844339CCA3 /* database_info_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D92E20235D22000A432D /* database_info_test.cc */; }; E8608D40B683938C6D785627 /* credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FA4576525144C5069A7A5 /* credentials_provider_test.cc */; }; @@ -1331,17 +1489,21 @@ EC160876D8A42166440E0B53 /* FIRCursorTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E070202154D600B64F25 /* FIRCursorTests.mm */; }; EC3331B17394886A3715CFD8 /* target.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 618BBE7D20B89AAC00B5BCE7 /* target.pb.cc */; }; EC62F9E29CE3598881908FB8 /* leveldb_transaction_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */; }; + EC63BD5E46C8734B6D20312D /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */; }; EC7A44792A5513FBB6F501EE /* comparison_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 548DB928200D59F600E00ABC /* comparison_test.cc */; }; EC80A217F3D66EB0272B36B0 /* FSTLevelDBSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02C20213FFB00B64F25 /* FSTLevelDBSpecTests.mm */; }; ECC433628575AE994C621C54 /* create_noop_connectivity_monitor.cc in Sources */ = {isa = PBXBuildFile; fileRef = CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */; }; ECED3B60C5718B085AAB14FB /* to_string_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B696858D2214B53900271095 /* to_string_test.cc */; }; + ED14A67E34AEDF55232096EF /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */; }; ED420D8F49DA5C41EEF93913 /* FIRSnapshotMetadataTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04D202154AA00B64F25 /* FIRSnapshotMetadataTests.mm */; }; ED4E2AC80CAF2A8FDDAC3DEE /* field_mask_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5320A36E1F00BCEB75 /* field_mask_test.cc */; }; ED9DF1EB20025227B38736EC /* message_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = CE37875365497FFA8687B745 /* message_test.cc */; }; + EDF35B147B116F659D0D2CA8 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */; }; EE470CC3C8FBCDA5F70A8466 /* local_store_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 307FF03D0297024D59348EBD /* local_store_test.cc */; }; EE6DBFB0874A50578CE97A7F /* leveldb_remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0840319686A223CC4AD3FAB1 /* leveldb_remote_document_cache_test.cc */; }; EECC1EC64CA963A8376FA55C /* persistence_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9113B6F513D0473AEABBAF1F /* persistence_testing.cc */; }; EF3518F84255BAF3EBD317F6 /* exponential_backoff_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6D1B68420E2AB1A00B35856 /* exponential_backoff_test.cc */; }; + EF409F2A8AE28D177CCF635D /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */; }; EF43FF491B9282E0330E4CA2 /* remote_event_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */; }; EF4FB3034994E6386F3C78FF /* leveldb_overlay_migration_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D8A6D52723B1BABE1B7B8D8F /* leveldb_overlay_migration_manager_test.cc */; }; EF6C285129E462A200A7D4F1 /* FIRAggregateTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = EF6C285029E462A200A7D4F1 /* FIRAggregateTests.mm */; }; @@ -1359,11 +1521,14 @@ F0C8EB1F4FB56401CFA4F374 /* object_value_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 214877F52A705012D6720CA0 /* object_value_test.cc */; }; F0EA84FB66813F2BC164EF7C /* token_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A082AFDD981B07B5AD78FDE8 /* token_test.cc */; }; F10A3E4E164A5458DFF7EDE6 /* leveldb_remote_document_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0840319686A223CC4AD3FAB1 /* leveldb_remote_document_cache_test.cc */; }; + F17DDCAC8DE5A47A777F94FC /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */; }; F184E5367DF3CA158EDE8532 /* testing_hooks_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */; }; F19B749671F2552E964422F7 /* FIRListenerRegistrationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E06B202154D500B64F25 /* FIRListenerRegistrationTests.mm */; }; F1EAEE9DF819C017A9506AEB /* FIRIndexingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 795AA8FC31D2AF6864B07D39 /* FIRIndexingTests.mm */; }; + F1F8FB9254E9A5107161A7B2 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */; }; F272A8C41D2353700A11D1FB /* field_mask_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 549CCA5320A36E1F00BCEB75 /* field_mask_test.cc */; }; F27347560A963E8162C56FF3 /* target_index_matcher_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */; }; + F2876F16CF689FD7FFBA9DFA /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */; }; F2AB7EACA1B9B1A7046D3995 /* FSTSyncEngineTestDriver.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02E20213FFC00B64F25 /* FSTSyncEngineTestDriver.mm */; }; F3261CBFC169DB375A0D9492 /* FSTMockDatastore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02D20213FFC00B64F25 /* FSTMockDatastore.mm */; }; F3DEF2DB11FADAABDAA4C8BB /* bundle_builder.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4F5B96F3ABCD2CA901DB1CD4 /* bundle_builder.cc */; }; @@ -1371,6 +1536,7 @@ F481368DB694B3B4D0C8E4A2 /* query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B9C261C26C5D311E1E3C0CB9 /* query_test.cc */; }; F4F00BF4E87D7F0F0F8831DB /* FSTEventAccumulator.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E0392021401F00B64F25 /* FSTEventAccumulator.mm */; }; F4FAC5A7D40A0A9A3EA77998 /* FSTLevelDBSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E02C20213FFB00B64F25 /* FSTLevelDBSpecTests.mm */; }; + F563446799EFCF4916758E6C /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */ = {isa = PBXBuildFile; fileRef = 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */; }; F56E9334642C207D7D85D428 /* pretty_printing_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB323F9553050F4F6490F9FF /* pretty_printing_test.cc */; }; F58A23FEF328EB74F681FE83 /* index_manager_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE4A9E38D65688EE000EE2A1 /* index_manager_test.cc */; }; F5A654E92FF6F3FF16B93E6B /* mutation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = C8522DE226C467C54E6788D8 /* mutation_test.cc */; }; @@ -1413,11 +1579,13 @@ FD6F5B4497D670330E7F89DA /* document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = FFCA39825D9678A03D1845D0 /* document_overlay_cache_test.cc */; }; FD8EA96A604E837092ACA51D /* ordered_code_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D03201BC6E400D97691 /* ordered_code_test.cc */; }; FE1C0263F6570DAC54A60F5C /* FIRTimestampTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B65D34A7203C99090076A5E1 /* FIRTimestampTest.m */; }; + FE20E696E014CDCE918E91D6 /* md5_testing.cc in Sources */ = {isa = PBXBuildFile; fileRef = E2E39422953DE1D3C7B97E77 /* md5_testing.cc */; }; FE701C2D739A5371BCBD62B9 /* leveldb_mutation_queue_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5C7942B6244F4C416B11B86C /* leveldb_mutation_queue_test.cc */; }; FE9131E2D84A560D287B6F90 /* resource.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1C3F7302BF4AE6CBC00ECDD0 /* resource.pb.cc */; }; FF3405218188DFCE586FB26B /* app_testing.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5467FB07203E6A44009C9584 /* app_testing.mm */; }; FF4FA5757D13A2B7CEE40F04 /* document.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 544129D821C2DDC800EFB9CC /* document.pb.cc */; }; FF6333B8BD9732C068157221 /* memory_bundle_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB4AB1388538CD3CB19EB028 /* memory_bundle_cache_test.cc */; }; + FFA7C1AF560D8E92A65E7FDD /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */ = {isa = PBXBuildFile; fileRef = 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1486,6 +1654,7 @@ 0473AFFF5567E667A125347B /* ordered_code_benchmark.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = ordered_code_benchmark.cc; sourceTree = ""; }; 062072B62773A055001655D7 /* AsyncAwaitIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncAwaitIntegrationTests.swift; sourceTree = ""; }; 0840319686A223CC4AD3FAB1 /* leveldb_remote_document_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_remote_document_cache_test.cc; sourceTree = ""; }; + 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json; sourceTree = ""; }; 0EE5300F8233D14025EF0456 /* string_apple_test.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = string_apple_test.mm; sourceTree = ""; }; 11984BA0A99D7A7ABA5B0D90 /* Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.release.xcconfig"; sourceTree = ""; }; 1235769122B7E915007DDFA9 /* EncodableFieldValueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncodableFieldValueTests.swift; sourceTree = ""; }; @@ -1496,11 +1665,13 @@ 12F4357299652983A615F886 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 132E32997D781B896672D30A /* reference_set_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reference_set_test.cc; sourceTree = ""; }; 166CE73C03AB4366AAC5201C /* leveldb_index_manager_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_index_manager_test.cc; sourceTree = ""; }; + 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json; sourceTree = ""; }; 1B342370EAE3AA02393E33EB /* cc_compilation_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = cc_compilation_test.cc; path = api/cc_compilation_test.cc; sourceTree = ""; }; 1B9F95EC29FAD3F100EEC075 /* FIRAggregateQueryUnitTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRAggregateQueryUnitTests.mm; sourceTree = ""; }; 1C01D8CE367C56BB2624E299 /* index.pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = index.pb.h; path = admin/index.pb.h; sourceTree = ""; }; 1C3F7302BF4AE6CBC00ECDD0 /* resource.pb.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = resource.pb.cc; sourceTree = ""; }; 1CA9800A53669EFBFFB824E3 /* memory_remote_document_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = memory_remote_document_cache_test.cc; sourceTree = ""; }; + 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = bloom_filter.pb.cc; sourceTree = ""; }; 1F50E872B3F117A674DA8E94 /* index_backfiller_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = index_backfiller_test.cc; sourceTree = ""; }; 214877F52A705012D6720CA0 /* object_value_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = object_value_test.cc; sourceTree = ""; }; 2220F583583EFC28DE792ABE /* Pods_Firestore_IntegrationTests_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1523,23 +1694,32 @@ 332485C4DCC6BA0DBB5E31B7 /* leveldb_util_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_util_test.cc; sourceTree = ""; }; 3355BE9391CC4857AF0BDAE3 /* DatabaseTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DatabaseTests.swift; sourceTree = ""; }; 33607A3AE91548BD219EC9C6 /* transform_operation_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = transform_operation_test.cc; sourceTree = ""; }; + 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_1_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_membership_test_result.json; sourceTree = ""; }; 358C3B5FE573B1D60A4F7592 /* strerror_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = strerror_test.cc; sourceTree = ""; }; 36D235D9F1240D5195CDB670 /* Pods-Firestore_IntegrationTests_tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_IntegrationTests_tvOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_IntegrationTests_tvOS/Pods-Firestore_IntegrationTests_tvOS.release.xcconfig"; sourceTree = ""; }; + 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json; sourceTree = ""; }; 395E8B07639E69290A929695 /* index.pb.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = index.pb.cc; path = admin/index.pb.cc; sourceTree = ""; }; 397FB002E298B780F1E223E2 /* Pods-Firestore_Tests_macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests_macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests_macOS/Pods-Firestore_Tests_macOS.release.xcconfig"; sourceTree = ""; }; 39B832380209CC5BAF93BC52 /* Pods_Firestore_IntegrationTests_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B843E4A1F3930A400548890 /* remote_store_spec_test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = remote_store_spec_test.json; sourceTree = ""; }; 3C81DE3772628FE297055662 /* Pods-Firestore_Example_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_iOS/Pods-Firestore_Example_iOS.debug.xcconfig"; sourceTree = ""; }; 3CAA33F964042646FDDAF9F9 /* status_testing.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = status_testing.cc; sourceTree = ""; }; + 3D050936A2D52257FD17FB6E /* md5_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = md5_test.cc; sourceTree = ""; }; 3F0992A4B83C60841C52E960 /* Pods-Firestore_Example_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_iOS/Pods-Firestore_Example_iOS.release.xcconfig"; sourceTree = ""; }; 3FBAA6F05C0B46A522E3B5A7 /* bundle_cache_test.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = bundle_cache_test.h; sourceTree = ""; }; + 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json; sourceTree = ""; }; 403DBF6EFB541DFD01582AA3 /* path_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = path_test.cc; sourceTree = ""; }; 40F9D09063A07F710811A84F /* value_util_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = value_util_test.cc; sourceTree = ""; }; 4132F30044D5DF1FB15B2A9D /* fake_credentials_provider.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = fake_credentials_provider.h; sourceTree = ""; }; 432C71959255C5DBDF522F52 /* byte_stream_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = byte_stream_test.cc; sourceTree = ""; }; 4334F87873015E3763954578 /* status_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = status_testing.h; sourceTree = ""; }; + 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json; sourceTree = ""; }; 444B7AB3F5A2929070CB1363 /* hard_assert_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = hard_assert_test.cc; sourceTree = ""; }; + 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json; sourceTree = ""; }; 48D0915834C3D234E5A875A9 /* grpc_stream_tester.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = grpc_stream_tester.h; sourceTree = ""; }; + 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json; sourceTree = ""; }; + 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json; sourceTree = ""; }; + 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json; sourceTree = ""; }; 4C73C0CC6F62A90D8573F383 /* string_apple_benchmark.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = string_apple_benchmark.mm; sourceTree = ""; }; 4F5B96F3ABCD2CA901DB1CD4 /* bundle_builder.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = bundle_builder.cc; sourceTree = ""; }; 526D755F65AC676234F57125 /* target_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = target_test.cc; sourceTree = ""; }; @@ -1644,9 +1824,12 @@ 54E9281E1F33950B00C1953E /* FSTIntegrationTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSTIntegrationTestCase.h; sourceTree = ""; }; 54E9282A1F339CAD00C1953E /* XCTestCase+Await.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCTestCase+Await.h"; sourceTree = ""; }; 54EB764C202277B30088B8F3 /* array_sorted_map_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = array_sorted_map_test.cc; sourceTree = ""; }; + 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json; sourceTree = ""; }; 584AE2C37A55B408541A6FF3 /* remote_event_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = remote_event_test.cc; sourceTree = ""; }; 5918805E993304321A05E82B /* Pods_Firestore_Example_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_Example_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5B5414D28802BC76FDADABD6 /* stream_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = stream_test.cc; sourceTree = ""; }; + 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json; sourceTree = ""; }; + 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_01_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_membership_test_result.json; sourceTree = ""; }; 5C7942B6244F4C416B11B86C /* leveldb_mutation_queue_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_mutation_queue_test.cc; sourceTree = ""; }; 5CAE131920FFFED600BE9A4A /* Firestore_Benchmarks_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Firestore_Benchmarks_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5CAE131D20FFFED600BE9A4A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1692,6 +1875,7 @@ 63136A2371C0C013EC7A540C /* target_index_matcher_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = target_index_matcher_test.cc; sourceTree = ""; }; 64AA92CFA356A2360F3C5646 /* filesystem_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = filesystem_testing.h; sourceTree = ""; }; 69E6C311558EC77729A16CF1 /* Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS/Pods-Firestore_Example_iOS-Firestore_SwiftTests_iOS.debug.xcconfig"; sourceTree = ""; }; + 6A7A30A2DB3367E08939E789 /* bloom_filter.pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = bloom_filter.pb.h; sourceTree = ""; }; 6AE927CDFC7A72BF825BE4CB /* Pods-Firestore_Tests_tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests_tvOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests_tvOS/Pods-Firestore_Tests_tvOS.release.xcconfig"; sourceTree = ""; }; 6E8302DE210222ED003E1EA3 /* FSTFuzzTestFieldPath.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSTFuzzTestFieldPath.h; sourceTree = ""; }; 6E8302DF21022309003E1EA3 /* FSTFuzzTestFieldPath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FSTFuzzTestFieldPath.mm; sourceTree = ""; }; @@ -1706,6 +1890,7 @@ 6F5B6C1399F92FD60F2C582B /* nanopb_util_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = nanopb_util_test.cc; path = nanopb/nanopb_util_test.cc; sourceTree = ""; }; 71140E5D09C6E76F7C71B2FC /* fake_target_metadata_provider.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = fake_target_metadata_provider.cc; sourceTree = ""; }; 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json; sourceTree = ""; }; 731541602214AFFA0037F4DC /* query_spec_test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = query_spec_test.json; sourceTree = ""; }; 73866A9F2082B069009BB4FF /* FIRArrayTransformTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRArrayTransformTests.mm; sourceTree = ""; }; 73F1F73A2210F3D800E1F692 /* index_manager_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = index_manager_test.h; sourceTree = ""; }; @@ -1722,6 +1907,7 @@ 795AA8FC31D2AF6864B07D39 /* FIRIndexingTests.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRIndexingTests.mm; sourceTree = ""; }; 79D4CD6A707ED3F7A6D2ECF5 /* view_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = view_testing.h; sourceTree = ""; }; 79EAA9F7B1B9592B5F053923 /* bundle_spec_test.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; path = bundle_spec_test.json; sourceTree = ""; }; + 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json; sourceTree = ""; }; 7B65C996438B84DBC7616640 /* CodableTimestampTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CodableTimestampTests.swift; sourceTree = ""; }; 7C3F995E040E9E9C5E8514BB /* query_listener_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = query_listener_test.cc; sourceTree = ""; }; 7EB299CF85034F09CFD6F3FD /* remote_document_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = remote_document_cache_test.cc; sourceTree = ""; }; @@ -1733,6 +1919,7 @@ 88CF09277CFA45EE1273E3BA /* leveldb_transaction_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_transaction_test.cc; sourceTree = ""; }; 899FC22684B0F7BEEAE13527 /* task_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = task_test.cc; sourceTree = ""; }; 8A41BBE832158C76BE901BC9 /* mutation_queue_test.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = mutation_queue_test.h; sourceTree = ""; }; + 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_1_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_membership_test_result.json; sourceTree = ""; }; 8ABAC2E0402213D837F73DC3 /* defer_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = defer_test.cc; sourceTree = ""; }; 8C058C8BE2723D9A53CCD64B /* persistence_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = persistence_testing.h; sourceTree = ""; }; 8C7278B604B8799F074F4E8C /* index_spec_test.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; path = index_spec_test.json; sourceTree = ""; }; @@ -1751,10 +1938,13 @@ 9B0B005A79E765AF02793DCE /* schedule_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = schedule_test.cc; sourceTree = ""; }; 9C1AFCC9E616EC33D6E169CF /* recovery_spec_test.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; path = recovery_spec_test.json; sourceTree = ""; }; 9CFD366B783AE27B9E79EE7A /* string_format_apple_test.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = string_format_apple_test.mm; sourceTree = ""; }; - A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; path = testing_hooks_test.cc; sourceTree = ""; }; + A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = testing_hooks_test.cc; sourceTree = ""; }; A082AFDD981B07B5AD78FDE8 /* token_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = token_test.cc; path = credentials/token_test.cc; sourceTree = ""; }; + A20BAA3D2F994384279727EC /* md5_testing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = md5_testing.h; sourceTree = ""; }; + A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = bloom_filter_test.cc; sourceTree = ""; }; A366F6AE1A5A77548485C091 /* bundle.pb.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = bundle.pb.cc; sourceTree = ""; }; A5466E7809AD2871FFDE6C76 /* view_testing.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = view_testing.cc; sourceTree = ""; }; + A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json; sourceTree = ""; }; A5FA86650A18F3B7A8162287 /* Pods-Firestore_Benchmarks_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Benchmarks_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Benchmarks_iOS/Pods-Firestore_Benchmarks_iOS.release.xcconfig"; sourceTree = ""; }; A70E82DD627B162BEF92B8ED /* Pods-Firestore_Example_tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_tvOS/Pods-Firestore_Example_tvOS.debug.xcconfig"; sourceTree = ""; }; A853C81A6A5A51C9D0389EDA /* bundle_loader_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = bundle_loader_test.cc; path = bundle/bundle_loader_test.cc; sourceTree = ""; }; @@ -1773,7 +1963,8 @@ ABF6506B201131F8005F2C74 /* timestamp_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = timestamp_test.cc; sourceTree = ""; }; AE4A9E38D65688EE000EE2A1 /* index_manager_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = index_manager_test.cc; sourceTree = ""; }; AE89CFF09C6804573841397F /* leveldb_document_overlay_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_document_overlay_cache_test.cc; sourceTree = ""; }; - AF924C79F49F793992A84879 /* aggregate_query_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; name = aggregate_query_test.cc; path = api/aggregate_query_test.cc; sourceTree = ""; }; + AF924C79F49F793992A84879 /* aggregate_query_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = aggregate_query_test.cc; path = api/aggregate_query_test.cc; sourceTree = ""; }; + B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json; sourceTree = ""; }; B3F5B3AAE791A5911B9EAA82 /* Pods-Firestore_Tests_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests_iOS/Pods-Firestore_Tests_iOS.release.xcconfig"; sourceTree = ""; }; B5C2A94EE24E60543F62CC35 /* bundle_serializer_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = bundle_serializer_test.cc; path = bundle/bundle_serializer_test.cc; sourceTree = ""; }; B5C37696557C81A6C2B7271A /* target_cache_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = target_cache_test.cc; sourceTree = ""; }; @@ -1813,6 +2004,9 @@ C0C7C8977C94F9F9AFA4DB00 /* local_store_test.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = local_store_test.h; sourceTree = ""; }; C7429071B33BDF80A7FA2F8A /* view_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = view_test.cc; sourceTree = ""; }; C8522DE226C467C54E6788D8 /* mutation_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = mutation_test.cc; sourceTree = ""; }; + C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json; sourceTree = ""; }; + C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json; sourceTree = ""; }; + C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json; sourceTree = ""; }; CB7B2D4691C380DE3EB59038 /* lru_garbage_collector_test.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = lru_garbage_collector_test.h; sourceTree = ""; }; CC572A9168BBEF7B83E4BBC5 /* view_snapshot_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = view_snapshot_test.cc; sourceTree = ""; }; CCC9BD953F121B9E29F9AA42 /* user_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = user_test.cc; path = credentials/user_test.cc; sourceTree = ""; }; @@ -1821,12 +2015,14 @@ CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = create_noop_connectivity_monitor.cc; sourceTree = ""; }; CF39ECA1293D21A0A2AB2626 /* FIRTransactionOptionsTests.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRTransactionOptionsTests.mm; sourceTree = ""; }; D0A6E9136804A41CEC9D55D4 /* delayed_constructor_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = delayed_constructor_test.cc; sourceTree = ""; }; + D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json; sourceTree = ""; }; D3CC3DC5338DCAF43A211155 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; D5B2593BCB52957D62F1C9D3 /* perf_spec_test.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = perf_spec_test.json; sourceTree = ""; }; D5B25E7E7D6873CBA4571841 /* FIRNumericTransformTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRNumericTransformTests.mm; sourceTree = ""; }; D7DF4A6F740086A2D8C0E28E /* Pods_Firestore_Tests_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_Tests_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D872D754B8AD88E28AF28B28 /* aggregation_result.pb.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = aggregation_result.pb.cc; sourceTree = ""; }; D8A6D52723B1BABE1B7B8D8F /* leveldb_overlay_migration_manager_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_overlay_migration_manager_test.cc; sourceTree = ""; }; + D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json; sourceTree = ""; }; D9D94300B9C02F7069523C00 /* leveldb_snappy_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_snappy_test.cc; sourceTree = ""; }; DAFF0CF521E64AC30062958F /* Firestore_Example_macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Firestore_Example_macOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; DAFF0CF721E64AC30062958F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -1839,6 +2035,7 @@ DB1F1E1B1ED15E8D042144B1 /* leveldb_query_engine_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_query_engine_test.cc; sourceTree = ""; }; DB5A1E760451189DA36028B3 /* memory_index_manager_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = memory_index_manager_test.cc; sourceTree = ""; }; DD12BC1DB2480886D2FB0005 /* settings_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = settings_test.cc; path = api/settings_test.cc; sourceTree = ""; }; + DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.json; name = Validation_BloomFilterTest_MD5_500_01_membership_test_result.json; path = bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_membership_test_result.json; sourceTree = ""; }; DE03B2E91F2149D600A30B9C /* Firestore_IntegrationTests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Firestore_IntegrationTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DE0761F61F2FE68D003233AF /* BasicCompileTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicCompileTests.swift; sourceTree = ""; }; DE51B1881F0D48AC0013853F /* FSTHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSTHelpers.h; sourceTree = ""; }; @@ -1849,6 +2046,7 @@ DF148C0D5EEC4A2CD9FA484C /* Pods-Firestore_Example_macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Example_macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Example_macOS/Pods-Firestore_Example_macOS.release.xcconfig"; sourceTree = ""; }; DF445D5201750281F1817387 /* document_overlay_cache_test.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = document_overlay_cache_test.h; sourceTree = ""; }; E1459FA70B8FC18DE4B80D0D /* overlay_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = overlay_test.cc; sourceTree = ""; }; + E2E39422953DE1D3C7B97E77 /* md5_testing.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = md5_testing.cc; sourceTree = ""; }; E3228F51DCDC2E90D5C58F97 /* ConditionalConformanceTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConditionalConformanceTests.swift; sourceTree = ""; }; E42355285B9EF55ABD785792 /* Pods_Firestore_Example_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_Example_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E592181BFD7C53C305123739 /* Pods-Firestore_Tests_iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests_iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests_iOS/Pods-Firestore_Tests_iOS.debug.xcconfig"; sourceTree = ""; }; @@ -1859,7 +2057,7 @@ EF83ACD5E1E9F25845A9ACED /* leveldb_migrations_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_migrations_test.cc; sourceTree = ""; }; F02F734F272C3C70D1307076 /* filter_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = filter_test.cc; sourceTree = ""; }; F119BDDF2F06B3C0883B8297 /* firebase_app_check_credentials_provider_test.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = firebase_app_check_credentials_provider_test.mm; path = credentials/firebase_app_check_credentials_provider_test.mm; sourceTree = ""; }; - F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */ = {isa = PBXFileReference; includeInIndex = 1; path = testing_hooks_util.cc; sourceTree = ""; }; + F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = testing_hooks_util.cc; sourceTree = ""; }; F354C0FE92645B56A6C6FD44 /* Pods-Firestore_IntegrationTests_iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_IntegrationTests_iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_IntegrationTests_iOS/Pods-Firestore_IntegrationTests_iOS.release.xcconfig"; sourceTree = ""; }; F51859B394D01C0C507282F1 /* filesystem_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = filesystem_test.cc; sourceTree = ""; }; F694C3CE4B77B3C0FA4BBA53 /* Pods_Firestore_Benchmarks_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_Benchmarks_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2028,6 +2226,8 @@ children = ( D872D754B8AD88E28AF28B28 /* aggregation_result.pb.cc */, B9ED38DA914BDCD2E3A0714D /* aggregation_result.pb.h */, + 1E0C7C0DCD2790019E66D8CC /* bloom_filter.pb.cc */, + 6A7A30A2DB3367E08939E789 /* bloom_filter.pb.h */, 544129D221C2DDC800EFB9CC /* common.pb.cc */, 544129D121C2DDC800EFB9CC /* common.pb.h */, 544129D821C2DDC800EFB9CC /* document.pb.cc */, @@ -2062,6 +2262,8 @@ CD422AF3E4515FB8E9BE67A0 /* equals_tester.h */, BA02DA2FCD0001CFC6EB08DA /* filesystem_testing.cc */, 64AA92CFA356A2360F3C5646 /* filesystem_testing.h */, + E2E39422953DE1D3C7B97E77 /* md5_testing.cc */, + A20BAA3D2F994384279727EC /* md5_testing.h */, 3CAA33F964042646FDDAF9F9 /* status_testing.cc */, 4334F87873015E3763954578 /* status_testing.h */, F1ADF4E1991C352F0ECCE1E7 /* testing_hooks_util.cc */, @@ -2079,6 +2281,8 @@ 546854A720A3681B004BDBD5 /* remote */ = { isa = PBXGroup; children = ( + 8264DF4364BB8F9089FCFA99 /* bloom_filter_golden_test_data */, + A2E6F09AD1EE0A6A452E9A08 /* bloom_filter_test.cc */, CF39535F2C41AB0006FA6C0E /* create_noop_connectivity_monitor.cc */, 9098A0C535096F2EE9C35DE0 /* create_noop_connectivity_monitor.h */, 3167BD972EFF8EC636530E59 /* datastore_test.cc */, @@ -2127,6 +2331,7 @@ 54A0353420A3D8CB003E0143 /* iterator_adaptors_test.cc */, 54C2294E1FECABAE007D065B /* log_test.cc */, 28B45B2104E2DAFBBF86DBB7 /* logic_utils_test.cc */, + 3D050936A2D52257FD17FB6E /* md5_test.cc */, 0473AFFF5567E667A125347B /* ordered_code_benchmark.cc */, AB380D03201BC6E400D97691 /* ordered_code_test.cc */, 403DBF6EFB541DFD01582AA3 /* path_test.cc */, @@ -2528,6 +2733,37 @@ path = FuzzTests; sourceTree = ""; }; + 8264DF4364BB8F9089FCFA99 /* bloom_filter_golden_test_data */ = { + isa = PBXGroup; + children = ( + 4B59C0A7B2A4548496ED4E7D /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json */, + C939D1789E38C09F9A0C1157 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json */, + 0D964D4936953635AC7E0834 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json */, + 5C68EE4CB94C0DD6E333F546 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json */, + 3FDD0050CA08C8302400C5FB /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json */, + 3369AC938F82A70685C5ED58 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json */, + A5D9044B72061CAF284BC9E4 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json */, + 5B96CC29E9946508F022859C /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json */, + 7B44DD11682C4803B73DCC34 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json */, + C8FB22BCB9F454DA44BA80C8 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json */, + 4B3E4A77493524333133C5DC /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json */, + 3841925AA60E13A027F565E6 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json */, + 728F617782600536F2561463 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json */, + C8582DFD74E8060C7072104B /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json */, + 57F8EE51B5EFC9FAB185B66C /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json */, + B0520A41251254B3C24024A3 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json */, + 4375BDCDBCA9938C7F086730 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json */, + 1A7D48A017ECB54FD381D126 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json */, + D22D4C211AC32E4F8B4883DA /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json */, + 478DC75A0DCA6249A616DD30 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json */, + 4BD051DBE754950FEAC7A446 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json */, + DD990FD89C165F4064B4F608 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json */, + D8E530B27D5641B9C26A452C /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json */, + 8AB49283E544497A9C5A0E59 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json */, + ); + name = bloom_filter_golden_test_data; + sourceTree = ""; + }; 8FC5BFAD63BAC5AADAC8A94A /* api */ = { isa = PBXGroup; children = ( @@ -3083,6 +3319,30 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 2AD98CD29CC6F820A74CDD5E /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */, + 57171BD004A1691B19A76453 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */, + AFCA3C24AA751B5B2D3E6FEF /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */, + D4F85AEACD2FD03C738D1052 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */, + 06D76CC82E034658BF7D4BE4 /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */, + 2A86AB04B38DBB770A1D8B13 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */, + C602E27459408B90A0DF2AA0 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */, + B998971CE6D0D1DD2AD9250A /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */, + 3A93D8FB318C6491A6B654F5 /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */, + 945CE2FED66752D9D97AA631 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */, + D5F6AAA1A1B9AE84205ECE27 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */, + 9966167103B9714723A88669 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */, + 8E41D53C77C30372840B0367 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */, + A728A4D7FA17F9F3257E0002 /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */, + 7B9B8C1F5C2FFE063C7B47DC /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */, + 2D361A44A8B8D57024B89F88 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */, + BC4249D72DDB23A04EF272F9 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */, + D2C486D904E08CC41E409695 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */, + DAD462C948703A1834328E19 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */, + 5785C7190F8F8DDE879F16B7 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */, + 7D3207DEE229EFCF16E52693 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */, + 48926FF55484E996B474D32F /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */, + 48720B5768AFA2B2F3E14C04 /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */, + 0869E4C03A4648B67A719349 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */, DEF4BF5FAA83C37100408F89 /* bundle_spec_test.json in Resources */, 546877D52248206A005E3DE0 /* collection_spec_test.json in Resources */, 546877D62248206A005E3DE0 /* existence_filter_spec_test.json in Resources */, @@ -3117,6 +3377,30 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + AD00D000A63837FB47291BFE /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */, + 143FBD21E02C709E3E6E8993 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */, + 8311F672244D73D810406D7E /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */, + 3E5FD39FE7442883AB3CE1F2 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */, + 90F75D7C0EA9D9AFC77EE33F /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */, + FFA7C1AF560D8E92A65E7FDD /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */, + 76AD5862714F170251BDEACB /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */, + EF409F2A8AE28D177CCF635D /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */, + F563446799EFCF4916758E6C /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */, + 8E103A426D6E650DC338F281 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */, + 27AF4C4BAFE079892D4F5341 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */, + 3E101CE56C70F06BA2FDD56C /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */, + C9C9A92E1734A097BE0670AF /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */, + 00A5761CD97E26A0EF4D47ED /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */, + 6B8E8B6C9EFDB3F1F91628A0 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */, + 5778E5F1FABEFA450B8CF4BC /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */, + E042112665DD2504E3F495D5 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */, + A0ED6C684A58A0077A5F9606 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */, + 2CDAAD6EC0BDAD9D929A59B5 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */, + 6EA1C48C20EB8D438893A949 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */, + 2689EB821AC8083568EACFB8 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */, + B188D7EC9A100F365DB02490 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */, + 1FE23E911F0761AA896FAD67 /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */, + 76C18D1BA96E4F5DF1BF7F4B /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */, 6141D3FDF5728FCE9CC1DBFA /* bundle_spec_test.json in Resources */, 54ACB6C9224C11F400172E69 /* collection_spec_test.json in Resources */, 54ACB6CA224C11F400172E69 /* existence_filter_spec_test.json in Resources */, @@ -3141,6 +3425,30 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8242BB61FBF44B9F5CAC35A7 /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */, + 2E5758FE6CFE753B04D50F89 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */, + 2FAE0BCBE559ED7214AEFEB7 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */, + 64D8241E9F56973DAD3077BC /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */, + 035034AB3797D1E5E0112EC3 /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */, + E59F597947D3E130A57E1B5E /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */, + 070B9CCDD759E66E6E10CC68 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */, + E666F0B9FD141F87AA5C87AC /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */, + EC63BD5E46C8734B6D20312D /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */, + 7E1B1335B2EC566FB25B710C /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */, + 90DE9018DAB7D66DE5EC51DF /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */, + C2E0C68B2EA6FA3683F4EE94 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */, + D6FF8D248C0D21164071B1C4 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */, + ED14A67E34AEDF55232096EF /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */, + C97CD9EA59E9BBEFE17E94D6 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */, + 1BD772FABD69673BF5864110 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */, + 185B0DF3E9396AA218E7A460 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */, + D7229A3A0B37AF4B18052A17 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */, + 360EB1D691F9C19A21D0916F /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */, + 12A611A85D59ED2742EEE187 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */, + 41C1C67BD1A10F2A8D1F5316 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */, + AC44D6363F57CEAAB291ED49 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */, + 8B2921C75DB7DD912AE14B8F /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */, + B491EF0E70DC0542644F623E /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */, 4B5FA86D9568ECE20C6D3AD1 /* bundle_spec_test.json in Resources */, 08839E1CEAAC07E350257E9D /* collection_spec_test.json in Resources */, 9C1F25177DC5753B075DCF65 /* existence_filter_spec_test.json in Resources */, @@ -3165,6 +3473,30 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0C9887A2F6728CB9E8A4C3CA /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */, + 57F0E1A1F2B614BA74961D9A /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */, + F2876F16CF689FD7FFBA9DFA /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */, + E37C52277CD00C57E5848A0E /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */, + 59F3A9669E0AF835E62D6674 /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */, + A2E9978E02F7BCB016555F09 /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */, + 658CBF4A717EA160E27C973E /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */, + A186FECD0257B92FDB0E83B8 /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */, + D3180BF788CA5EBA9FCB58FB /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */, + A0D61250F959BC52CEFF9467 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */, + 198C6B31EFAA230F7FF9B76F /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */, + 7F5501F917A11DE4E11F5CC7 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */, + 81AD038D81C1A8C2074B98B1 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */, + 330DE2A5AE6AF8D66C9C849F /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */, + BFCDC78CD851F109EB7A1422 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */, + 51A483DE202CC3E9FCD8FF6E /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */, + 77C5703230DB77F0540D1F89 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */, + 43B6A25A860337D21D933C29 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */, + 6C415868AE347DC4A26588C3 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */, + C20151B20ACE518267B4850C /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */, + AA859F27A9098D6886B222A8 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */, + F1F8FB9254E9A5107161A7B2 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */, + 34B62A40BB56F9574B87B28B /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */, + C1C3369C7ECE069B76A84AD1 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */, 0B002E2E2012B32EB801C6D5 /* bundle_spec_test.json in Resources */, 009CDC6F03AC92F3E345085E /* collection_spec_test.json in Resources */, 7AD020FC27493FF8E659436C /* existence_filter_spec_test.json in Resources */, @@ -3208,6 +3540,30 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + AEA092BBCA736A1CDC741143 /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */, + EDF35B147B116F659D0D2CA8 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */, + 342DA187B53105640073658F /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */, + DD0F288108714D5A406D0A9F /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */, + F17DDCAC8DE5A47A777F94FC /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */, + 74A63A931F834D1D6CF3BA9A /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */, + A841EEB5A94A271523EAE459 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */, + 0D8395F9244C191BF8D9F666 /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */, + C240DB0498C1C84C6AFA4C8D /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */, + A833A216988ADFD4876763CD /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */, + 4C17393656A7D6255AA998B3 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */, + 78D99CDBB539B0AEE0029831 /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */, + 86407DB439A2570F1A670212 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */, + 94C86F03FF86690307F28182 /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */, + B41B17163DD9A421F35DE1A9 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */, + 47136EEB53CF80D7C8436F38 /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */, + B2A9965ED0114E39A911FD09 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */, + B60BAF9ED610F9D4E245EEB3 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */, + 162291531D29B002F6872A7F /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */, + 67B8C34BDF0FFD7532D7BE4F /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */, + B2554A2BA211D10823646DBE /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */, + 61C89E693B42E346ED2F5935 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */, + DD941BF189E38312E7A2CB21 /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */, + 86B413EC49E3BBBEBF1FB7A0 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */, 9C366448F9BA7A4AC0821AF7 /* bundle_spec_test.json in Resources */, 54DA12A61F315EE100DD57A1 /* collection_spec_test.json in Resources */, 54DA12A71F315EE100DD57A1 /* existence_filter_spec_test.json in Resources */, @@ -3250,6 +3606,30 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7A7DB86955670B85B4514A1F /* Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json in Resources */, + 06E0914D76667F1345EC17F5 /* Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json in Resources */, + 37461AF1ACC2E64DF1709736 /* Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json in Resources */, + D00B06FD0F20D09C813547F4 /* Validation_BloomFilterTest_MD5_1_01_membership_test_result.json in Resources */, + C985030E45AB19081D0273BE /* Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json in Resources */, + CA2392732BA7F8985699313D /* Validation_BloomFilterTest_MD5_1_1_membership_test_result.json in Resources */, + 59A3F624F45DC98D8B9F8014 /* Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json in Resources */, + AF450AFDF88C23E0121B34A1 /* Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json in Resources */, + 31C9186C5B8558361FACFD1F /* Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json in Resources */, + 07F1F1FA00CE7B55E3476FD4 /* Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json in Resources */, + B0E745EAC5F37CA61F868F38 /* Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json in Resources */, + 8230A581857CB46D1C7A5B6A /* Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json in Resources */, + E54AC3EA240C05B3720A2FE9 /* Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json in Resources */, + 409B29C81132718B36BF2497 /* Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json in Resources */, + 043C7B3DECB94F69F28BB798 /* Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json in Resources */, + 64B3FDEE22A5D07744A8A9ED /* Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json in Resources */, + E827A3B15D6C8C1298A7BC72 /* Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json in Resources */, + 8DBA8DC55722ED9D3A1BB2C9 /* Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json in Resources */, + 9CC32ACF397022BB7DF11B52 /* Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json in Resources */, + 8AE0E09A570FB452460C4495 /* Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json in Resources */, + BD3A421C9E40C57D25697E75 /* Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json in Resources */, + 662E94803D6FABE56F0D22C9 /* Validation_BloomFilterTest_MD5_500_01_membership_test_result.json in Resources */, + 2618255E63631038B64DF3BB /* Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json in Resources */, + 42A98512D4C9EC6722334FE6 /* Validation_BloomFilterTest_MD5_500_1_membership_test_result.json in Resources */, 32030FA5B4BE6ABDFF2F974E /* bundle_spec_test.json in Resources */, 46B104DEE6014D881F7ED169 /* collection_spec_test.json in Resources */, 3887E1635B31DCD7BC0922BD /* existence_filter_spec_test.json in Resources */, @@ -3716,6 +4096,8 @@ B28ACC69EB1F232AE612E77B /* async_testing.cc in Sources */, 1733601ECCEA33E730DEAF45 /* autoid_test.cc in Sources */, 0DAA255C2FEB387895ADEE12 /* bits_test.cc in Sources */, + B4F544C50B4472268A2E633B /* bloom_filter.pb.cc in Sources */, + 3B5CEA04AC1627256A1AE8BA /* bloom_filter_test.cc in Sources */, 394259BB091E1DB5994B91A2 /* bundle.pb.cc in Sources */, EBAC5E8D0E2ECD9FBEDB7DAE /* bundle_builder.cc in Sources */, 5150E9F256E6E82D6F3CB3F1 /* bundle_cache_test.cc in Sources */, @@ -3798,6 +4180,8 @@ F924DF3D9DCD2720C315A372 /* logic_utils_test.cc in Sources */, 3F6C9F8A993CF4B0CD51E7F0 /* lru_garbage_collector_test.cc in Sources */, 12158DFCEE09D24B7988A340 /* maybe_document.pb.cc in Sources */, + 380E543B7BC6F648BBB250B4 /* md5_test.cc in Sources */, + FE20E696E014CDCE918E91D6 /* md5_testing.cc in Sources */, FA43BA0195DA90CE29B29D36 /* memory_bundle_cache_test.cc in Sources */, 8F2055702DB5EE8DA4BACD7C /* memory_document_overlay_cache_test.cc in Sources */, CFF1EBC60A00BA5109893C6E /* memory_index_manager_test.cc in Sources */, @@ -3928,6 +4312,8 @@ F73471529D36DD48ABD8AAE8 /* async_testing.cc in Sources */, 5D5E24E3FA1128145AA117D2 /* autoid_test.cc in Sources */, B6FDE6F91D3F81D045E962A0 /* bits_test.cc in Sources */, + 2403890A78D7AB099754A18C /* bloom_filter.pb.cc in Sources */, + 3C5D441E7D5C140F0FB14D91 /* bloom_filter_test.cc in Sources */, 4D1775B7916D4CDAD1BF1876 /* bundle.pb.cc in Sources */, 474DF520B9859479845C8A4D /* bundle_builder.cc in Sources */, 04D7D9DB95E66FECF2C0A412 /* bundle_cache_test.cc in Sources */, @@ -4010,6 +4396,8 @@ 7EF56BA2A480026D62CCA35A /* logic_utils_test.cc in Sources */, 1F56F51EB6DF0951B1F4F85B /* lru_garbage_collector_test.cc in Sources */, 88FD82A1FC5FEC5D56B481D8 /* maybe_document.pb.cc in Sources */, + DCC8F3D4AA87C81AB3FD9491 /* md5_test.cc in Sources */, + 169EDCF15637580BA79B61AD /* md5_testing.cc in Sources */, 9611A0FAA2E10A6B1C1AC2EA /* memory_bundle_cache_test.cc in Sources */, 75C6CECF607CA94F56260BAB /* memory_document_overlay_cache_test.cc in Sources */, 3987A3E8534BAA496D966735 /* memory_index_manager_test.cc in Sources */, @@ -4160,6 +4548,8 @@ 08E3D48B3651E4908D75B23A /* async_testing.cc in Sources */, B842780CF42361ACBBB381A9 /* autoid_test.cc in Sources */, 146C140B254F3837A4DD7AE8 /* bits_test.cc in Sources */, + 659FFE071CD0F60DAEADD50B /* bloom_filter.pb.cc in Sources */, + AFF7D2CF35B51656E4744164 /* bloom_filter_test.cc in Sources */, 3DDC57212ADBA9AD498EAA4C /* bundle.pb.cc in Sources */, F3DEF2DB11FADAABDAA4C8BB /* bundle_builder.cc in Sources */, 392966346DA5EB3165E16A22 /* bundle_cache_test.cc in Sources */, @@ -4242,6 +4632,8 @@ 0595B5EBEB8F09952B72C883 /* logic_utils_test.cc in Sources */, 913F6E57AF18F84C5ECFD414 /* lru_garbage_collector_test.cc in Sources */, 6F511ABFD023AEB81F92DB12 /* maybe_document.pb.cc in Sources */, + 13ED75EFC2F6917951518A4B /* md5_test.cc in Sources */, + E2AC3BDAAFFF9A45C916708B /* md5_testing.cc in Sources */, FF6333B8BD9732C068157221 /* memory_bundle_cache_test.cc in Sources */, 5F6FD840AC2D729B50991CCB /* memory_document_overlay_cache_test.cc in Sources */, E6B825EE85BF20B88AF3E3CD /* memory_index_manager_test.cc in Sources */, @@ -4392,6 +4784,8 @@ 2C5E4D9FDE7615AD0F63909E /* async_testing.cc in Sources */, 6AF739DDA9D33DF756DE7CDE /* autoid_test.cc in Sources */, C1B4621C0820EEB0AC9CCD22 /* bits_test.cc in Sources */, + 1AE27A46DC082F28D9494599 /* bloom_filter.pb.cc in Sources */, + BCAC9F7A865BD2320A4D8752 /* bloom_filter_test.cc in Sources */, 01C66732ECCB83AB1D896026 /* bundle.pb.cc in Sources */, EAA1962BFBA0EBFBA53B343F /* bundle_builder.cc in Sources */, C901A1BFD553B6DD70BB7CC7 /* bundle_cache_test.cc in Sources */, @@ -4474,6 +4868,8 @@ 0D6AE96565603226DB2E6838 /* logic_utils_test.cc in Sources */, 95CE3F5265B9BB7297EE5A6B /* lru_garbage_collector_test.cc in Sources */, C19214F5B43AA745A7FC2FC1 /* maybe_document.pb.cc in Sources */, + 211A60ECA3976D27C0BF59BB /* md5_test.cc in Sources */, + E72A77095FF6814267DF0F6D /* md5_testing.cc in Sources */, 94854FAEAEA75A1AC77A0515 /* memory_bundle_cache_test.cc in Sources */, 053C11420E49AE1A77E21C20 /* memory_document_overlay_cache_test.cc in Sources */, 4D8367018652104A8803E8DB /* memory_index_manager_test.cc in Sources */, @@ -4614,6 +5010,8 @@ 11BC867491A6631D37DE56A8 /* async_testing.cc in Sources */, 54740A581FC914F000713A1A /* autoid_test.cc in Sources */, AB380D02201BC69F00D97691 /* bits_test.cc in Sources */, + 15576E9A23A1C6678D5D7DE1 /* bloom_filter.pb.cc in Sources */, + 1CEEB0E7FBBB974224BBA557 /* bloom_filter_test.cc in Sources */, 784FCB02C76096DACCBA11F2 /* bundle.pb.cc in Sources */, 856A1EAAD674ADBDAAEDAC37 /* bundle_builder.cc in Sources */, BB3F35B1510FE5449E50EC8A /* bundle_cache_test.cc in Sources */, @@ -4696,6 +5094,8 @@ D156B9F19B5B29E77664FDFC /* logic_utils_test.cc in Sources */, 1290FA77A922B76503AE407C /* lru_garbage_collector_test.cc in Sources */, 618BBEA720B89AAC00B5BCE7 /* maybe_document.pb.cc in Sources */, + C86E85101352B5CDBF5909F9 /* md5_test.cc in Sources */, + 723BBD713478BB26CEFA5A7D /* md5_testing.cc in Sources */, A0E1C7F5C7093A498F65C5CF /* memory_bundle_cache_test.cc in Sources */, E56EEC9DAC455E2BE77D110A /* memory_document_overlay_cache_test.cc in Sources */, 3B47CC43DBA24434E215B8ED /* memory_index_manager_test.cc in Sources */, @@ -4865,6 +5265,8 @@ 35C330499D50AC415B24C580 /* async_testing.cc in Sources */, 8F781F527ED72DC6C123689E /* autoid_test.cc in Sources */, 0B9BD73418289EFF91917934 /* bits_test.cc in Sources */, + 8AA50598040531DE8EAFF4BB /* bloom_filter.pb.cc in Sources */, + 9A75A9413ED1D994DC6F37C6 /* bloom_filter_test.cc in Sources */, F8126CD7308A4B8AEC0F30A8 /* bundle.pb.cc in Sources */, 5AFA1055E8F6B4E4B1CCE2C4 /* bundle_builder.cc in Sources */, AE5E5E4A7BF12C2337AFA13B /* bundle_cache_test.cc in Sources */, @@ -4947,6 +5349,8 @@ 6FCC64A1937E286E76C294D0 /* logic_utils_test.cc in Sources */, 4DF18D15AC926FB7A4888313 /* lru_garbage_collector_test.cc in Sources */, 12E04A12ABD5533B616D552A /* maybe_document.pb.cc in Sources */, + E74D6C1056DE29969B5C4C62 /* md5_test.cc in Sources */, + 1DCDED1F94EBC7F72FDBFC98 /* md5_testing.cc in Sources */, 479A392EAB42453D49435D28 /* memory_bundle_cache_test.cc in Sources */, 5CEB0E83DA68652927D2CF07 /* memory_document_overlay_cache_test.cc in Sources */, 90FE088B8FD9EC06EEED1F39 /* memory_index_manager_test.cc in Sources */, diff --git a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm index fba25c382f7..aa349601e5a 100644 --- a/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm +++ b/Firestore/Example/Tests/Integration/API/FIRQueryTests.mm @@ -1192,7 +1192,10 @@ - (void)testOrderByEquality { matchesResult:@[ @"doc6", @"doc3" ]]; } -- (void)testResumingAQueryShouldUseExistenceFilterToDetectDeletes { +- (void)testResumingAQueryShouldUseBloomFilterToAvoidFullRequery { + using firebase::firestore::testutil::CaptureExistenceFilterMismatches; + using firebase::firestore::util::TestingHooks; + // Set this test to stop when the first failure occurs because some test assertion failures make // the rest of the test not applicable or will even crash. [self setContinueAfterFailure:NO]; @@ -1204,100 +1207,135 @@ - (void)testResumingAQueryShouldUseExistenceFilterToDetectDeletes { [testDocs setValue:@{@"key" : @42} forKey:[NSString stringWithFormat:@"doc%@", @(1000 + i)]]; } - // Create 100 documents in a new collection. - FIRCollectionReference *collRef = [self collectionRefWithDocuments:testDocs]; - - // Run a query to populate the local cache with the 100 documents and a resume token. - FIRQuerySnapshot *querySnapshot1 = [self readDocumentSetForRef:collRef - source:FIRFirestoreSourceDefault]; - XCTAssertEqual(querySnapshot1.count, 100, @"querySnapshot1.count has an unexpected value"); - NSArray *createdDocuments = - FIRDocumentReferenceArrayFromQuerySnapshot(querySnapshot1); - - // Delete 50 of the 100 documents. Do this in a transaction, rather than - // [FIRDocumentReference deleteDocument], to avoid affecting the local cache. - NSSet *deletedDocumentIds; - { - NSMutableArray *deletedDocumentIdsAccumulator = [[NSMutableArray alloc] init]; - XCTestExpectation *expectation = [self expectationWithDescription:@"DeleteTransaction"]; - [collRef.firestore - runTransactionWithBlock:^id _Nullable(FIRTransaction *transaction, NSError **) { - for (decltype(createdDocuments.count) i = 0; i < createdDocuments.count; i += 2) { - FIRDocumentReference *documentToDelete = createdDocuments[i]; - [transaction deleteDocument:documentToDelete]; - [deletedDocumentIdsAccumulator addObject:documentToDelete.documentID]; - } - return @"document deletion successful"; - } - completion:^(id, NSError *) { - [expectation fulfill]; - }]; - [self awaitExpectation:expectation]; - deletedDocumentIds = [NSSet setWithArray:deletedDocumentIdsAccumulator]; - } - XCTAssertEqual(deletedDocumentIds.count, 50u, @"deletedDocumentIds has the wrong size"); - - // Wait for 10 seconds, during which Watch will stop tracking the query and will send an existence - // filter rather than "delete" events when the query is resumed. - [NSThread sleepForTimeInterval:10.0f]; - - // Resume the query and save the resulting snapshot for verification. - // Use some internal testing hooks to "capture" the existence filter mismatches to verify them. - FIRQuerySnapshot *querySnapshot2; - std::vector - existence_filter_mismatches = - firebase::firestore::testutil::CaptureExistenceFilterMismatches([&] { - querySnapshot2 = [self readDocumentSetForRef:collRef source:FIRFirestoreSourceDefault]; - }); - - // Verify that the snapshot from the resumed query contains the expected documents; that is, - // that it contains the 50 documents that were _not_ deleted. - // TODO(b/270731363): Remove the "if" condition below once the Firestore Emulator is fixed to - // send an existence filter. At the time of writing, the Firestore emulator fails to send an - // existence filter, resulting in the client including the deleted documents in the snapshot - // of the resumed query. - if (!([FSTIntegrationTestCase isRunningAgainstEmulator] && querySnapshot2.count == 100)) { - NSSet *actualDocumentIds = - [NSSet setWithArray:FIRQuerySnapshotGetIDs(querySnapshot2)]; - NSSet *expectedDocumentIds; + // Each iteration of the "while" loop below runs a single iteration of the test. The test will + // be run multiple times only if a bloom filter false positive occurs. + int attemptNumber = 0; + while (true) { + attemptNumber++; + + // Create 100 documents in a new collection. + FIRCollectionReference *collRef = [self collectionRefWithDocuments:testDocs]; + + // Run a query to populate the local cache with the 100 documents and a resume token. + FIRQuerySnapshot *querySnapshot1 = [self readDocumentSetForRef:collRef + source:FIRFirestoreSourceDefault]; + XCTAssertEqual(querySnapshot1.count, 100, @"querySnapshot1.count has an unexpected value"); + NSArray *createdDocuments = + FIRDocumentReferenceArrayFromQuerySnapshot(querySnapshot1); + + // Delete 50 of the 100 documents. Do this in a transaction, rather than + // [FIRDocumentReference deleteDocument], to avoid affecting the local cache. + NSSet *deletedDocumentIds; { - NSMutableArray *expectedDocumentIdsAccumulator = [[NSMutableArray alloc] init]; - for (FIRDocumentReference *documentRef in createdDocuments) { - if (![deletedDocumentIds containsObject:documentRef.documentID]) { - [expectedDocumentIdsAccumulator addObject:documentRef.documentID]; + NSMutableArray *deletedDocumentIdsAccumulator = [[NSMutableArray alloc] init]; + XCTestExpectation *expectation = [self expectationWithDescription:@"DeleteTransaction"]; + [collRef.firestore + runTransactionWithBlock:^id _Nullable(FIRTransaction *transaction, NSError **) { + for (decltype(createdDocuments.count) i = 0; i < createdDocuments.count; i += 2) { + FIRDocumentReference *documentToDelete = createdDocuments[i]; + [transaction deleteDocument:documentToDelete]; + [deletedDocumentIdsAccumulator addObject:documentToDelete.documentID]; + } + return @"document deletion successful"; + } + completion:^(id, NSError *) { + [expectation fulfill]; + }]; + [self awaitExpectation:expectation]; + deletedDocumentIds = [NSSet setWithArray:deletedDocumentIdsAccumulator]; + } + XCTAssertEqual(deletedDocumentIds.count, 50u, @"deletedDocumentIds has the wrong size"); + + // Wait for 10 seconds, during which Watch will stop tracking the query and will send an + // existence filter rather than "delete" events when the query is resumed. + [NSThread sleepForTimeInterval:10.0f]; + + // Resume the query and save the resulting snapshot for verification. + // Use some internal testing hooks to "capture" the existence filter mismatches to verify that + // Watch sent a bloom filter, and it was used to avert a full requery. + FIRQuerySnapshot *querySnapshot2; + std::vector existence_filter_mismatches = + CaptureExistenceFilterMismatches([&] { + querySnapshot2 = [self readDocumentSetForRef:collRef source:FIRFirestoreSourceDefault]; + }); + + // Verify that the snapshot from the resumed query contains the expected documents; that is, + // that it contains the 50 documents that were _not_ deleted. + // TODO(b/270731363): Remove the "if" condition below once the Firestore Emulator is fixed to + // send an existence filter. At the time of writing, the Firestore emulator fails to send an + // existence filter, resulting in the client including the deleted documents in the snapshot + // of the resumed query. + if (!([FSTIntegrationTestCase isRunningAgainstEmulator] && querySnapshot2.count == 100)) { + NSSet *actualDocumentIds = + [NSSet setWithArray:FIRQuerySnapshotGetIDs(querySnapshot2)]; + NSSet *expectedDocumentIds; + { + NSMutableArray *expectedDocumentIdsAccumulator = [[NSMutableArray alloc] init]; + for (FIRDocumentReference *documentRef in createdDocuments) { + if (![deletedDocumentIds containsObject:documentRef.documentID]) { + [expectedDocumentIdsAccumulator addObject:documentRef.documentID]; + } } + expectedDocumentIds = [NSSet setWithArray:expectedDocumentIdsAccumulator]; + } + if (![actualDocumentIds isEqualToSet:expectedDocumentIds]) { + NSArray *unexpectedDocumentIds = + SortedStringsNotIn(actualDocumentIds, expectedDocumentIds); + NSArray *missingDocumentIds = + SortedStringsNotIn(expectedDocumentIds, actualDocumentIds); + XCTFail(@"querySnapshot2 contained %lu documents (expected %lu): " + @"%lu unexpected and %lu missing; " + @"unexpected documents: %@; missing documents: %@", + (unsigned long)actualDocumentIds.count, (unsigned long)expectedDocumentIds.count, + (unsigned long)unexpectedDocumentIds.count, (unsigned long)missingDocumentIds.count, + [unexpectedDocumentIds componentsJoinedByString:@", "], + [missingDocumentIds componentsJoinedByString:@", "]); } - expectedDocumentIds = [NSSet setWithArray:expectedDocumentIdsAccumulator]; } - if (![actualDocumentIds isEqualToSet:expectedDocumentIds]) { - NSArray *unexpectedDocumentIds = - SortedStringsNotIn(actualDocumentIds, expectedDocumentIds); - NSArray *missingDocumentIds = - SortedStringsNotIn(expectedDocumentIds, actualDocumentIds); - XCTFail(@"querySnapshot2 contained %lu documents (expected %lu): " - @"%lu unexpected and %lu missing; " - @"unexpected documents: %@; missing documents: %@", - (unsigned long)actualDocumentIds.count, (unsigned long)expectedDocumentIds.count, - (unsigned long)unexpectedDocumentIds.count, (unsigned long)missingDocumentIds.count, - [unexpectedDocumentIds componentsJoinedByString:@", "], - [missingDocumentIds componentsJoinedByString:@", "]); + + // Skip the verification of the existence filter mismatch when testing against the Firestore + // emulator because the Firestore emulator fails to to send an existence filter at all. + // TODO(b/270731363): Enable the verification of the existence filter mismatch once the + // Firestore emulator is fixed to send an existence filter. + if ([FSTIntegrationTestCase isRunningAgainstEmulator]) { + return; } - } - // Skip the verification of the existence filter mismatch when testing against the Firestore - // emulator because the Firestore emulator fails to to send an existence filter at all. - // TODO(b/270731363): Enable the verification of the existence filter mismatch once the Firestore - // emulator is fixed to send an existence filter. - if ([FSTIntegrationTestCase isRunningAgainstEmulator]) { - return; - } + // Verify that Watch sent an existence filter with the correct counts when the query was + // resumed. + XCTAssertEqual(existence_filter_mismatches.size(), size_t{1}, + @"Watch should have sent exactly 1 existence filter"); + const TestingHooks::ExistenceFilterMismatchInfo &existenceFilterMismatchInfo = + existence_filter_mismatches[0]; + XCTAssertEqual(existenceFilterMismatchInfo.local_cache_count, 100); + XCTAssertEqual(existenceFilterMismatchInfo.existence_filter_count, 50); + + // Verify that Watch sent a valid bloom filter. + const absl::optional &bloom_filter = + existence_filter_mismatches[0].bloom_filter; + XCTAssertTrue(bloom_filter.has_value(), + "Watch should have included a bloom filter in the existence filter"); + XCTAssertGreaterThan(bloom_filter->hash_count, 0); + XCTAssertGreaterThan(bloom_filter->bitmap_length, 0); + XCTAssertGreaterThan(bloom_filter->padding, 0); + XCTAssertLessThan(bloom_filter->padding, 8); + + // Verify that the bloom filter was successfully used to avert a full requery. If a false + // positive occurred then retry the entire test. Although statistically rare, false positives + // are expected to happen occasionally. When a false positive _does_ happen, just retry the test + // with a different set of documents. If that retry _also_ experiences a false positive, then + // fail the test because that is so improbable that something must have gone wrong. + if (attemptNumber == 1 && !bloom_filter->applied) { + continue; + } + + XCTAssertTrue(bloom_filter->applied, + @"The bloom filter should have been successfully applied with attemptNumber=%@", + @(attemptNumber)); - // Verify that Watch sent an existence filter with the correct counts when the query was resumed. - XCTAssertEqual(static_cast(existence_filter_mismatches.size()), 1); - firebase::firestore::util::TestingHooks::ExistenceFilterMismatchInfo &info = - existence_filter_mismatches[0]; - XCTAssertEqual(info.local_cache_count, 100); - XCTAssertEqual(info.existence_filter_count, 50); + // Break out of the test loop now that the test passes. + break; + } } @end diff --git a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm index 4c645635dd9..27ad5e9c7c9 100644 --- a/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm +++ b/Firestore/Example/Tests/SpecTests/FSTMockDatastore.mm @@ -115,6 +115,11 @@ void WatchQuery(const TargetData& query) override { // Snapshot version is ignored on the wire TargetData sentTargetData = query.WithResumeToken(query.resume_token(), SnapshotVersion::None()); + + if (query.expected_count().has_value()) { + sentTargetData = sentTargetData.WithExpectedCount(query.expected_count().value()); + } + datastore_->IncrementWatchStreamRequests(); active_targets_[query.target_id()] = sentTargetData; } diff --git a/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm b/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm index 0845bc339dc..622b3b527d7 100644 --- a/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm +++ b/Firestore/Example/Tests/SpecTests/FSTSpecTests.mm @@ -56,6 +56,7 @@ #include "Firestore/core/src/model/types.h" #include "Firestore/core/src/nanopb/message.h" #include "Firestore/core/src/nanopb/nanopb_util.h" +#include "Firestore/core/src/remote/bloom_filter.h" #include "Firestore/core/src/remote/existence_filter.h" #include "Firestore/core/src/remote/serializer.h" #include "Firestore/core/src/remote/watch_change.h" @@ -71,6 +72,7 @@ #include "Firestore/core/src/util/to_string.h" #include "Firestore/core/test/unit/testutil/testutil.h" #include "absl/memory/memory.h" +#include "absl/strings/escaping.h" #include "absl/types/optional.h" namespace objc = firebase::firestore::objc; @@ -98,6 +100,8 @@ using firebase::firestore::nanopb::ByteString; using firebase::firestore::nanopb::MakeByteString; using firebase::firestore::nanopb::Message; +using firebase::firestore::remote::BloomFilter; +using firebase::firestore::remote::BloomFilterParameters; using firebase::firestore::remote::DocumentWatchChange; using firebase::firestore::remote::ExistenceFilter; using firebase::firestore::remote::ExistenceFilterWatchChange; @@ -115,6 +119,7 @@ using firebase::firestore::util::MakeStringPtr; using firebase::firestore::util::Path; using firebase::firestore::util::Status; +using firebase::firestore::util::StatusOr; using firebase::firestore::util::TimerId; using firebase::firestore::util::ToString; using firebase::firestore::util::WrapCompare; @@ -327,6 +332,26 @@ - (SnapshotVersion)parseVersion:(NSNumber *_Nullable)version { return Version(version.longLongValue); } +- (absl::optional)parseBloomFilterParameter: + (NSDictionary *_Nullable)bloomFilterProto { + if (bloomFilterProto == nil) { + return absl::nullopt; + } + NSDictionary *bitsData = bloomFilterProto[@"bits"]; + + // Decode base64 string into uint8_t vector. If bitmap is not specified in proto, use default + // empty string. + NSString *bitmapEncoded = bitsData[@"bitmap"]; + std::string bitmapDecoded; + absl::Base64Unescape([bitmapEncoded cStringUsingEncoding:NSASCIIStringEncoding], &bitmapDecoded); + ByteString bitmap(bitmapDecoded); + + // If not specified in proto, default padding and hashCount to 0. + int32_t padding = [bitsData[@"padding"] intValue]; + int32_t hashCount = [bloomFilterProto[@"hashCount"] intValue]; + return BloomFilterParameters{std::move(bitmap), padding, hashCount}; +} + - (QueryPurpose)parseQueryPurpose:(NSString *)value { if ([value isEqualToString:@"TargetPurposeListen"]) { return QueryPurpose::Listen; @@ -334,6 +359,9 @@ - (QueryPurpose)parseQueryPurpose:(NSString *)value { if ([value isEqualToString:@"TargetPurposeExistenceFilterMismatch"]) { return QueryPurpose::ExistenceFilterMismatch; } + if ([value isEqualToString:@"TargetPurposeExistenceFilterMismatchBloom"]) { + return QueryPurpose::ExistenceFilterMismatchBloom; + } if ([value isEqualToString:@"TargetPurposeLimboResolution"]) { return QueryPurpose::LimboResolution; } @@ -484,8 +512,11 @@ - (void)doWatchFilter:(NSDictionary *)watchFilter { NSArray *targets = watchFilter[@"targetIds"]; HARD_ASSERT(targets.count == 1, "ExistenceFilters currently support exactly one target only."); - ExistenceFilter filter{static_cast(keys.count)}; - ExistenceFilterWatchChange change{filter, targets[0].intValue}; + absl::optional bloomFilterParameters = + [self parseBloomFilterParameter:watchFilter[@"bloomFilter"]]; + + ExistenceFilter filter{static_cast(keys.count), std::move(bloomFilterParameters)}; + ExistenceFilterWatchChange change{std::move(filter), targets[0].intValue}; [self.driver receiveWatchChange:change snapshotVersion:SnapshotVersion::None()]; } @@ -702,8 +733,18 @@ - (void)validateEvent:(FSTQueryEvent *)actual matches:(NSDictionary *)expected { } XCTAssertEqual(actual.viewSnapshot.value().document_changes().size(), expectedChanges.size()); - for (size_t i = 0; i != expectedChanges.size(); ++i) { - XCTAssertTrue((actual.viewSnapshot.value().document_changes()[i] == expectedChanges[i])); + + auto comparator = [](const DocumentViewChange &lhs, const DocumentViewChange &rhs) { + return lhs.document()->key() < rhs.document()->key(); + }; + + std::vector expectedChangesSorted = expectedChanges; + std::sort(expectedChangesSorted.begin(), expectedChangesSorted.end(), comparator); + std::vector actualChangesSorted = + actual.viewSnapshot.value().document_changes(); + std::sort(actualChangesSorted.begin(), actualChangesSorted.end(), comparator); + for (size_t i = 0; i != expectedChangesSorted.size(); ++i) { + XCTAssertTrue((actualChangesSorted[i] == expectedChangesSorted[i])); } BOOL expectedHasPendingWrites = @@ -806,6 +847,10 @@ - (void)validateExpectedState:(nullable NSDictionary *)expectedState { target_data = target_data.WithResumeToken( ByteString(), [self parseVersion:queryData[@"readTime"]]); } + + if ([queryData objectForKey:@"expectedCount"] != nil) { + target_data = target_data.WithExpectedCount([queryData[@"expectedCount"] intValue]); + } queries.push_back(std::move(target_data)); } expectedActiveTargets[targetID] = std::move(queries); @@ -924,7 +969,13 @@ - (void)validateActiveTargets { XCTAssertEqual(actual.target_id(), targetData.target_id()); XCTAssertEqual(actual.snapshot_version(), targetData.snapshot_version()); XCTAssertEqual(actual.resume_token(), targetData.resume_token()); - + if (targetData.expected_count().has_value()) { + if (!actual.expected_count().has_value()) { + XCTFail(@"Actual target data doesn't have an expected_count."); + } else { + XCTAssertEqual(actual.expected_count().value(), targetData.expected_count().value()); + } + } actualTargets.erase(targetID); } diff --git a/Firestore/Example/Tests/SpecTests/json/existence_filter_spec_test.json b/Firestore/Example/Tests/SpecTests/json/existence_filter_spec_test.json index bfebee3eefe..9c04b65138c 100644 --- a/Firestore/Example/Tests/SpecTests/json/existence_filter_spec_test.json +++ b/Firestore/Example/Tests/SpecTests/json/existence_filter_spec_test.json @@ -3,7 +3,6 @@ "describeName": "Existence Filters:", "itName": "Bloom filter can process special characters in document name", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -207,7 +206,6 @@ "describeName": "Existence Filters:", "itName": "Bloom filter fills in default values for undefined padding and hashCount", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -394,7 +392,6 @@ "describeName": "Existence Filters:", "itName": "Bloom filter is handled at global snapshot", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -633,7 +630,6 @@ "describeName": "Existence Filters:", "itName": "Bloom filter limbo resolution is denied", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -893,7 +889,6 @@ "describeName": "Existence Filters:", "itName": "Bloom filter with large size works as expected", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -6517,7 +6512,6 @@ "describeName": "Existence Filters:", "itName": "Full re-query is skipped when bloom filter can identify documents deleted", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -6977,7 +6971,6 @@ "describeName": "Existence Filters:", "itName": "Full re-query is triggered when bloom filter can not identify documents deleted", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -7190,7 +7183,6 @@ "describeName": "Existence Filters:", "itName": "Full re-query is triggered when bloom filter hashCount is invalid", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -7379,7 +7371,6 @@ "describeName": "Existence Filters:", "itName": "Full re-query is triggered when bloom filter is empty", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -7568,7 +7559,6 @@ "describeName": "Existence Filters:", "itName": "Same documents can have different bloom filters", "tags": [ - "no-ios" ], "config": { "numClients": 1, diff --git a/Firestore/Example/Tests/SpecTests/json/limbo_spec_test.json b/Firestore/Example/Tests/SpecTests/json/limbo_spec_test.json index c7b20d5c6fb..adffb61f510 100644 --- a/Firestore/Example/Tests/SpecTests/json/limbo_spec_test.json +++ b/Firestore/Example/Tests/SpecTests/json/limbo_spec_test.json @@ -7956,7 +7956,6 @@ "describeName": "Limbo Documents:", "itName": "Limbo resolution throttling with bloom filter application", "tags": [ - "no-ios" ], "config": { "maxConcurrentLimboResolutions": 2, diff --git a/Firestore/Example/Tests/SpecTests/json/listen_spec_test.json b/Firestore/Example/Tests/SpecTests/json/listen_spec_test.json index 7b1e596ce9c..7370a0cd675 100644 --- a/Firestore/Example/Tests/SpecTests/json/listen_spec_test.json +++ b/Firestore/Example/Tests/SpecTests/json/listen_spec_test.json @@ -3385,7 +3385,6 @@ "describeName": "Listens:", "itName": "ExpectedCount in listen request should work after coming back online", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -12745,7 +12744,6 @@ "describeName": "Listens:", "itName": "Resuming a query should specify expectedCount that does not include pending mutations", "tags": [ - "no-ios" ], "config": { "numClients": 1, @@ -12947,7 +12945,6 @@ "describeName": "Listens:", "itName": "Resuming a query should specify expectedCount when adding the target", "tags": [ - "no-ios" ], "config": { "numClients": 1, diff --git a/Firestore/Protos/CMakeLists.txt b/Firestore/Protos/CMakeLists.txt index 48310bbfe9b..8b1174c0880 100644 --- a/Firestore/Protos/CMakeLists.txt +++ b/Firestore/Protos/CMakeLists.txt @@ -45,6 +45,7 @@ set( google/api/http google/firestore/admin/index google/firestore/v1/aggregation_result + google/firestore/v1/bloom_filter google/firestore/v1/common google/firestore/v1/document google/firestore/v1/firestore diff --git a/Firestore/Protos/cpp/google/firestore/v1/bloom_filter.pb.cc b/Firestore/Protos/cpp/google/firestore/v1/bloom_filter.pb.cc new file mode 100644 index 00000000000..1a918a4b688 --- /dev/null +++ b/Firestore/Protos/cpp/google/firestore/v1/bloom_filter.pb.cc @@ -0,0 +1,608 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/bloom_filter.proto + +#include "google/firestore/v1/bloom_filter.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) +#include +extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BitSequence_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto; +namespace google { +namespace firestore { +namespace v1 { +class BitSequenceDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _BitSequence_default_instance_; +class BloomFilterDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _BloomFilter_default_instance_; +} // namespace v1 +} // namespace firestore +} // namespace google +static void InitDefaultsscc_info_BitSequence_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::google::firestore::v1::_BitSequence_default_instance_; + new (ptr) ::google::firestore::v1::BitSequence(); + ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); + } + ::google::firestore::v1::BitSequence::InitAsDefaultInstance(); +} + +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BitSequence_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_BitSequence_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto}, {}}; + +static void InitDefaultsscc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + { + void* ptr = &::google::firestore::v1::_BloomFilter_default_instance_; + new (ptr) ::google::firestore::v1::BloomFilter(); + ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); + } + ::google::firestore::v1::BloomFilter::InitAsDefaultInstance(); +} + +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto}, { + &scc_info_BitSequence_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto.base,}}; + +static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto[2]; +static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto = nullptr; +static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto = nullptr; + +const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::BitSequence, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::BitSequence, bitmap_), + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::BitSequence, padding_), + ~0u, // no _has_bits_ + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::BloomFilter, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::BloomFilter, bits_), + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::BloomFilter, hash_count_), +}; +static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { + { 0, -1, sizeof(::google::firestore::v1::BitSequence)}, + { 7, -1, sizeof(::google::firestore::v1::BloomFilter)}, +}; + +static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { + reinterpret_cast(&::google::firestore::v1::_BitSequence_default_instance_), + reinterpret_cast(&::google::firestore::v1::_BloomFilter_default_instance_), +}; + +const char descriptor_table_protodef_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = + "\n&google/firestore/v1/bloom_filter.proto" + "\022\023google.firestore.v1\".\n\013BitSequence\022\016\n\006" + "bitmap\030\001 \001(\014\022\017\n\007padding\030\002 \001(\005\"Q\n\013BloomFi" + "lter\022.\n\004bits\030\001 \001(\0132 .google.firestore.v1" + ".BitSequence\022\022\n\nhash_count\030\002 \001(\005B\311\001\n\027com" + ".google.firestore.v1B\020BloomFilterProtoP\001" + "ZDone(&ptr)) { + ::PROTOBUF_NAMESPACE_ID::uint32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + CHK_(ptr); + switch (tag >> 3) { + // bytes bitmap = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { + auto str = _internal_mutable_bitmap(); + ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx); + CHK_(ptr); + } else goto handle_unusual; + continue; + // int32 padding = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { + padding_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; + default: { + handle_unusual: + if ((tag & 7) == 4 || tag == 0) { + ctx->SetLastTag(tag); + goto success; + } + ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + CHK_(ptr != nullptr); + continue; + } + } // switch + } // while +success: + return ptr; +failure: + ptr = nullptr; + goto success; +#undef CHK_ +} + +::PROTOBUF_NAMESPACE_ID::uint8* BitSequence::_InternalSerialize( + ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.firestore.v1.BitSequence) + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // bytes bitmap = 1; + if (this->bitmap().size() > 0) { + target = stream->WriteBytesMaybeAliased( + 1, this->_internal_bitmap(), target); + } + + // int32 padding = 2; + if (this->padding() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_padding(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields(), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.firestore.v1.BitSequence) + return target; +} + +size_t BitSequence::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.firestore.v1.BitSequence) + size_t total_size = 0; + + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // bytes bitmap = 1; + if (this->bitmap().size() > 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::BytesSize( + this->_internal_bitmap()); + } + + // int32 padding = 2; + if (this->padding() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( + this->_internal_padding()); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( + _internal_metadata_, total_size, &_cached_size_); + } + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void BitSequence::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.firestore.v1.BitSequence) + GOOGLE_DCHECK_NE(&from, this); + const BitSequence* source = + ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated( + &from); + if (source == nullptr) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.firestore.v1.BitSequence) + ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.firestore.v1.BitSequence) + MergeFrom(*source); + } +} + +void BitSequence::MergeFrom(const BitSequence& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.firestore.v1.BitSequence) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.bitmap().size() > 0) { + + bitmap_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.bitmap_); + } + if (from.padding() != 0) { + _internal_set_padding(from._internal_padding()); + } +} + +void BitSequence::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.firestore.v1.BitSequence) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void BitSequence::CopyFrom(const BitSequence& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.firestore.v1.BitSequence) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BitSequence::IsInitialized() const { + return true; +} + +void BitSequence::InternalSwap(BitSequence* other) { + using std::swap; + _internal_metadata_.Swap(&other->_internal_metadata_); + bitmap_.Swap(&other->bitmap_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + GetArenaNoVirtual()); + swap(padding_, other->padding_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata BitSequence::GetMetadata() const { + return GetMetadataStatic(); +} + + +// =================================================================== + +void BloomFilter::InitAsDefaultInstance() { + ::google::firestore::v1::_BloomFilter_default_instance_._instance.get_mutable()->bits_ = const_cast< ::google::firestore::v1::BitSequence*>( + ::google::firestore::v1::BitSequence::internal_default_instance()); +} +class BloomFilter::_Internal { + public: + static const ::google::firestore::v1::BitSequence& bits(const BloomFilter* msg); +}; + +const ::google::firestore::v1::BitSequence& +BloomFilter::_Internal::bits(const BloomFilter* msg) { + return *msg->bits_; +} +BloomFilter::BloomFilter() + : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.firestore.v1.BloomFilter) +} +BloomFilter::BloomFilter(const BloomFilter& from) + : ::PROTOBUF_NAMESPACE_ID::Message(), + _internal_metadata_(nullptr) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + if (from._internal_has_bits()) { + bits_ = new ::google::firestore::v1::BitSequence(*from.bits_); + } else { + bits_ = nullptr; + } + hash_count_ = from.hash_count_; + // @@protoc_insertion_point(copy_constructor:google.firestore.v1.BloomFilter) +} + +void BloomFilter::SharedCtor() { + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto.base); + ::memset(&bits_, 0, static_cast( + reinterpret_cast(&hash_count_) - + reinterpret_cast(&bits_)) + sizeof(hash_count_)); +} + +BloomFilter::~BloomFilter() { + // @@protoc_insertion_point(destructor:google.firestore.v1.BloomFilter) + SharedDtor(); +} + +void BloomFilter::SharedDtor() { + if (this != internal_default_instance()) delete bits_; +} + +void BloomFilter::SetCachedSize(int size) const { + _cached_size_.Set(size); +} +const BloomFilter& BloomFilter::default_instance() { + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&::scc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto.base); + return *internal_default_instance(); +} + + +void BloomFilter::Clear() { +// @@protoc_insertion_point(message_clear_start:google.firestore.v1.BloomFilter) + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + if (GetArenaNoVirtual() == nullptr && bits_ != nullptr) { + delete bits_; + } + bits_ = nullptr; + hash_count_ = 0; + _internal_metadata_.Clear(); +} + +const char* BloomFilter::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { +#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure + while (!ctx->Done(&ptr)) { + ::PROTOBUF_NAMESPACE_ID::uint32 tag; + ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); + CHK_(ptr); + switch (tag >> 3) { + // .google.firestore.v1.BitSequence bits = 1; + case 1: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 10)) { + ptr = ctx->ParseMessage(_internal_mutable_bits(), ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; + // int32 hash_count = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { + hash_count_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; + default: { + handle_unusual: + if ((tag & 7) == 4 || tag == 0) { + ctx->SetLastTag(tag); + goto success; + } + ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + CHK_(ptr != nullptr); + continue; + } + } // switch + } // while +success: + return ptr; +failure: + ptr = nullptr; + goto success; +#undef CHK_ +} + +::PROTOBUF_NAMESPACE_ID::uint8* BloomFilter::_InternalSerialize( + ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const { + // @@protoc_insertion_point(serialize_to_array_start:google.firestore.v1.BloomFilter) + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // .google.firestore.v1.BitSequence bits = 1; + if (this->has_bits()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 1, _Internal::bits(this), target, stream); + } + + // int32 hash_count = 2; + if (this->hash_count() != 0) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_hash_count(), target); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( + _internal_metadata_.unknown_fields(), target, stream); + } + // @@protoc_insertion_point(serialize_to_array_end:google.firestore.v1.BloomFilter) + return target; +} + +size_t BloomFilter::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.firestore.v1.BloomFilter) + size_t total_size = 0; + + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + // .google.firestore.v1.BitSequence bits = 1; + if (this->has_bits()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *bits_); + } + + // int32 hash_count = 2; + if (this->hash_count() != 0) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size( + this->_internal_hash_count()); + } + + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { + return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( + _internal_metadata_, total_size, &_cached_size_); + } + int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size); + SetCachedSize(cached_size); + return total_size; +} + +void BloomFilter::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.firestore.v1.BloomFilter) + GOOGLE_DCHECK_NE(&from, this); + const BloomFilter* source = + ::PROTOBUF_NAMESPACE_ID::DynamicCastToGenerated( + &from); + if (source == nullptr) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.firestore.v1.BloomFilter) + ::PROTOBUF_NAMESPACE_ID::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.firestore.v1.BloomFilter) + MergeFrom(*source); + } +} + +void BloomFilter::MergeFrom(const BloomFilter& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.firestore.v1.BloomFilter) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.has_bits()) { + _internal_mutable_bits()->::google::firestore::v1::BitSequence::MergeFrom(from._internal_bits()); + } + if (from.hash_count() != 0) { + _internal_set_hash_count(from._internal_hash_count()); + } +} + +void BloomFilter::CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.firestore.v1.BloomFilter) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void BloomFilter::CopyFrom(const BloomFilter& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.firestore.v1.BloomFilter) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BloomFilter::IsInitialized() const { + return true; +} + +void BloomFilter::InternalSwap(BloomFilter* other) { + using std::swap; + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(bits_, other->bits_); + swap(hash_count_, other->hash_count_); +} + +::PROTOBUF_NAMESPACE_ID::Metadata BloomFilter::GetMetadata() const { + return GetMetadataStatic(); +} + + +// @@protoc_insertion_point(namespace_scope) +} // namespace v1 +} // namespace firestore +} // namespace google +PROTOBUF_NAMESPACE_OPEN +template<> PROTOBUF_NOINLINE ::google::firestore::v1::BitSequence* Arena::CreateMaybeMessage< ::google::firestore::v1::BitSequence >(Arena* arena) { + return Arena::CreateInternal< ::google::firestore::v1::BitSequence >(arena); +} +template<> PROTOBUF_NOINLINE ::google::firestore::v1::BloomFilter* Arena::CreateMaybeMessage< ::google::firestore::v1::BloomFilter >(Arena* arena) { + return Arena::CreateInternal< ::google::firestore::v1::BloomFilter >(arena); +} +PROTOBUF_NAMESPACE_CLOSE + +// @@protoc_insertion_point(global_scope) +#include diff --git a/Firestore/Protos/cpp/google/firestore/v1/bloom_filter.pb.h b/Firestore/Protos/cpp/google/firestore/v1/bloom_filter.pb.h new file mode 100644 index 00000000000..ae26449641f --- /dev/null +++ b/Firestore/Protos/cpp/google/firestore/v1/bloom_filter.pb.h @@ -0,0 +1,574 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/bloom_filter.proto + +#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto +#define GOOGLE_PROTOBUF_INCLUDED_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto + +#include +#include + +#include +#if PROTOBUF_VERSION < 3011000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +// @@protoc_insertion_point(includes) +#include +#define PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto +PROTOBUF_NAMESPACE_OPEN +namespace internal { +class AnyMetadata; +} // namespace internal +PROTOBUF_NAMESPACE_CLOSE + +// Internal implementation detail -- do not use these members. +struct TableStruct_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto { + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[2] + PROTOBUF_SECTION_VARIABLE(protodesc_cold); + static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[]; + static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[]; + static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[]; +}; +extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto; +namespace google { +namespace firestore { +namespace v1 { +class BitSequence; +class BitSequenceDefaultTypeInternal; +extern BitSequenceDefaultTypeInternal _BitSequence_default_instance_; +class BloomFilter; +class BloomFilterDefaultTypeInternal; +extern BloomFilterDefaultTypeInternal _BloomFilter_default_instance_; +} // namespace v1 +} // namespace firestore +} // namespace google +PROTOBUF_NAMESPACE_OPEN +template<> ::google::firestore::v1::BitSequence* Arena::CreateMaybeMessage<::google::firestore::v1::BitSequence>(Arena*); +template<> ::google::firestore::v1::BloomFilter* Arena::CreateMaybeMessage<::google::firestore::v1::BloomFilter>(Arena*); +PROTOBUF_NAMESPACE_CLOSE +namespace google { +namespace firestore { +namespace v1 { + +// =================================================================== + +class BitSequence : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.firestore.v1.BitSequence) */ { + public: + BitSequence(); + virtual ~BitSequence(); + + BitSequence(const BitSequence& from); + BitSequence(BitSequence&& from) noexcept + : BitSequence() { + *this = ::std::move(from); + } + + inline BitSequence& operator=(const BitSequence& from) { + CopyFrom(from); + return *this; + } + inline BitSequence& operator=(BitSequence&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return GetMetadataStatic().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return GetMetadataStatic().reflection; + } + static const BitSequence& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const BitSequence* internal_default_instance() { + return reinterpret_cast( + &_BitSequence_default_instance_); + } + static constexpr int kIndexInFileMessages = + 0; + + friend void swap(BitSequence& a, BitSequence& b) { + a.Swap(&b); + } + inline void Swap(BitSequence* other) { + if (other == this) return; + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + inline BitSequence* New() const final { + return CreateMaybeMessage(nullptr); + } + + BitSequence* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final; + void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final; + void CopyFrom(const BitSequence& from); + void MergeFrom(const BitSequence& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize( + ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + inline void SharedCtor(); + inline void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(BitSequence* other); + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.firestore.v1.BitSequence"; + } + private: + inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { + return nullptr; + } + inline void* MaybeArenaPtr() const { + return nullptr; + } + public: + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + private: + static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto); + return ::descriptor_table_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto.file_level_metadata[kIndexInFileMessages]; + } + + public: + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kBitmapFieldNumber = 1, + kPaddingFieldNumber = 2, + }; + // bytes bitmap = 1; + void clear_bitmap(); + const std::string& bitmap() const; + void set_bitmap(const std::string& value); + void set_bitmap(std::string&& value); + void set_bitmap(const char* value); + void set_bitmap(const void* value, size_t size); + std::string* mutable_bitmap(); + std::string* release_bitmap(); + void set_allocated_bitmap(std::string* bitmap); + private: + const std::string& _internal_bitmap() const; + void _internal_set_bitmap(const std::string& value); + std::string* _internal_mutable_bitmap(); + public: + + // int32 padding = 2; + void clear_padding(); + ::PROTOBUF_NAMESPACE_ID::int32 padding() const; + void set_padding(::PROTOBUF_NAMESPACE_ID::int32 value); + private: + ::PROTOBUF_NAMESPACE_ID::int32 _internal_padding() const; + void _internal_set_padding(::PROTOBUF_NAMESPACE_ID::int32 value); + public: + + // @@protoc_insertion_point(class_scope:google.firestore.v1.BitSequence) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr bitmap_; + ::PROTOBUF_NAMESPACE_ID::int32 padding_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto; +}; +// ------------------------------------------------------------------- + +class BloomFilter : + public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.firestore.v1.BloomFilter) */ { + public: + BloomFilter(); + virtual ~BloomFilter(); + + BloomFilter(const BloomFilter& from); + BloomFilter(BloomFilter&& from) noexcept + : BloomFilter() { + *this = ::std::move(from); + } + + inline BloomFilter& operator=(const BloomFilter& from) { + CopyFrom(from); + return *this; + } + inline BloomFilter& operator=(BloomFilter&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { + return GetDescriptor(); + } + static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() { + return GetMetadataStatic().descriptor; + } + static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() { + return GetMetadataStatic().reflection; + } + static const BloomFilter& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const BloomFilter* internal_default_instance() { + return reinterpret_cast( + &_BloomFilter_default_instance_); + } + static constexpr int kIndexInFileMessages = + 1; + + friend void swap(BloomFilter& a, BloomFilter& b) { + a.Swap(&b); + } + inline void Swap(BloomFilter* other) { + if (other == this) return; + InternalSwap(other); + } + + // implements Message ---------------------------------------------- + + inline BloomFilter* New() const final { + return CreateMaybeMessage(nullptr); + } + + BloomFilter* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final { + return CreateMaybeMessage(arena); + } + void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final; + void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final; + void CopyFrom(const BloomFilter& from); + void MergeFrom(const BloomFilter& from); + PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; + + size_t ByteSizeLong() const final; + const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final; + ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize( + ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final; + int GetCachedSize() const final { return _cached_size_.Get(); } + + private: + inline void SharedCtor(); + inline void SharedDtor(); + void SetCachedSize(int size) const final; + void InternalSwap(BloomFilter* other); + friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata; + static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { + return "google.firestore.v1.BloomFilter"; + } + private: + inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { + return nullptr; + } + inline void* MaybeArenaPtr() const { + return nullptr; + } + public: + + ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; + private: + static ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadataStatic() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&::descriptor_table_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto); + return ::descriptor_table_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto.file_level_metadata[kIndexInFileMessages]; + } + + public: + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + enum : int { + kBitsFieldNumber = 1, + kHashCountFieldNumber = 2, + }; + // .google.firestore.v1.BitSequence bits = 1; + bool has_bits() const; + private: + bool _internal_has_bits() const; + public: + void clear_bits(); + const ::google::firestore::v1::BitSequence& bits() const; + ::google::firestore::v1::BitSequence* release_bits(); + ::google::firestore::v1::BitSequence* mutable_bits(); + void set_allocated_bits(::google::firestore::v1::BitSequence* bits); + private: + const ::google::firestore::v1::BitSequence& _internal_bits() const; + ::google::firestore::v1::BitSequence* _internal_mutable_bits(); + public: + + // int32 hash_count = 2; + void clear_hash_count(); + ::PROTOBUF_NAMESPACE_ID::int32 hash_count() const; + void set_hash_count(::PROTOBUF_NAMESPACE_ID::int32 value); + private: + ::PROTOBUF_NAMESPACE_ID::int32 _internal_hash_count() const; + void _internal_set_hash_count(::PROTOBUF_NAMESPACE_ID::int32 value); + public: + + // @@protoc_insertion_point(class_scope:google.firestore.v1.BloomFilter) + private: + class _Internal; + + ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + ::google::firestore::v1::BitSequence* bits_; + ::PROTOBUF_NAMESPACE_ID::int32 hash_count_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; + friend struct ::TableStruct_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto; +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// BitSequence + +// bytes bitmap = 1; +inline void BitSequence::clear_bitmap() { + bitmap_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} +inline const std::string& BitSequence::bitmap() const { + // @@protoc_insertion_point(field_get:google.firestore.v1.BitSequence.bitmap) + return _internal_bitmap(); +} +inline void BitSequence::set_bitmap(const std::string& value) { + _internal_set_bitmap(value); + // @@protoc_insertion_point(field_set:google.firestore.v1.BitSequence.bitmap) +} +inline std::string* BitSequence::mutable_bitmap() { + // @@protoc_insertion_point(field_mutable:google.firestore.v1.BitSequence.bitmap) + return _internal_mutable_bitmap(); +} +inline const std::string& BitSequence::_internal_bitmap() const { + return bitmap_.GetNoArena(); +} +inline void BitSequence::_internal_set_bitmap(const std::string& value) { + + bitmap_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); +} +inline void BitSequence::set_bitmap(std::string&& value) { + + bitmap_.SetNoArena( + &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.firestore.v1.BitSequence.bitmap) +} +inline void BitSequence::set_bitmap(const char* value) { + GOOGLE_DCHECK(value != nullptr); + + bitmap_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.firestore.v1.BitSequence.bitmap) +} +inline void BitSequence::set_bitmap(const void* value, size_t size) { + + bitmap_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.firestore.v1.BitSequence.bitmap) +} +inline std::string* BitSequence::_internal_mutable_bitmap() { + + return bitmap_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} +inline std::string* BitSequence::release_bitmap() { + // @@protoc_insertion_point(field_release:google.firestore.v1.BitSequence.bitmap) + + return bitmap_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); +} +inline void BitSequence::set_allocated_bitmap(std::string* bitmap) { + if (bitmap != nullptr) { + + } else { + + } + bitmap_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), bitmap); + // @@protoc_insertion_point(field_set_allocated:google.firestore.v1.BitSequence.bitmap) +} + +// int32 padding = 2; +inline void BitSequence::clear_padding() { + padding_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::int32 BitSequence::_internal_padding() const { + return padding_; +} +inline ::PROTOBUF_NAMESPACE_ID::int32 BitSequence::padding() const { + // @@protoc_insertion_point(field_get:google.firestore.v1.BitSequence.padding) + return _internal_padding(); +} +inline void BitSequence::_internal_set_padding(::PROTOBUF_NAMESPACE_ID::int32 value) { + + padding_ = value; +} +inline void BitSequence::set_padding(::PROTOBUF_NAMESPACE_ID::int32 value) { + _internal_set_padding(value); + // @@protoc_insertion_point(field_set:google.firestore.v1.BitSequence.padding) +} + +// ------------------------------------------------------------------- + +// BloomFilter + +// .google.firestore.v1.BitSequence bits = 1; +inline bool BloomFilter::_internal_has_bits() const { + return this != internal_default_instance() && bits_ != nullptr; +} +inline bool BloomFilter::has_bits() const { + return _internal_has_bits(); +} +inline void BloomFilter::clear_bits() { + if (GetArenaNoVirtual() == nullptr && bits_ != nullptr) { + delete bits_; + } + bits_ = nullptr; +} +inline const ::google::firestore::v1::BitSequence& BloomFilter::_internal_bits() const { + const ::google::firestore::v1::BitSequence* p = bits_; + return p != nullptr ? *p : *reinterpret_cast( + &::google::firestore::v1::_BitSequence_default_instance_); +} +inline const ::google::firestore::v1::BitSequence& BloomFilter::bits() const { + // @@protoc_insertion_point(field_get:google.firestore.v1.BloomFilter.bits) + return _internal_bits(); +} +inline ::google::firestore::v1::BitSequence* BloomFilter::release_bits() { + // @@protoc_insertion_point(field_release:google.firestore.v1.BloomFilter.bits) + + ::google::firestore::v1::BitSequence* temp = bits_; + bits_ = nullptr; + return temp; +} +inline ::google::firestore::v1::BitSequence* BloomFilter::_internal_mutable_bits() { + + if (bits_ == nullptr) { + auto* p = CreateMaybeMessage<::google::firestore::v1::BitSequence>(GetArenaNoVirtual()); + bits_ = p; + } + return bits_; +} +inline ::google::firestore::v1::BitSequence* BloomFilter::mutable_bits() { + // @@protoc_insertion_point(field_mutable:google.firestore.v1.BloomFilter.bits) + return _internal_mutable_bits(); +} +inline void BloomFilter::set_allocated_bits(::google::firestore::v1::BitSequence* bits) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + if (message_arena == nullptr) { + delete bits_; + } + if (bits) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + if (message_arena != submessage_arena) { + bits = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, bits, submessage_arena); + } + + } else { + + } + bits_ = bits; + // @@protoc_insertion_point(field_set_allocated:google.firestore.v1.BloomFilter.bits) +} + +// int32 hash_count = 2; +inline void BloomFilter::clear_hash_count() { + hash_count_ = 0; +} +inline ::PROTOBUF_NAMESPACE_ID::int32 BloomFilter::_internal_hash_count() const { + return hash_count_; +} +inline ::PROTOBUF_NAMESPACE_ID::int32 BloomFilter::hash_count() const { + // @@protoc_insertion_point(field_get:google.firestore.v1.BloomFilter.hash_count) + return _internal_hash_count(); +} +inline void BloomFilter::_internal_set_hash_count(::PROTOBUF_NAMESPACE_ID::int32 value) { + + hash_count_ = value; +} +inline void BloomFilter::set_hash_count(::PROTOBUF_NAMESPACE_ID::int32 value) { + _internal_set_hash_count(value); + // @@protoc_insertion_point(field_set:google.firestore.v1.BloomFilter.hash_count) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace v1 +} // namespace firestore +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#include +#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto diff --git a/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.cc b/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.cc index e4d0ada2ac7..9bf5b20075b 100644 --- a/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.cc +++ b/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.cc @@ -36,12 +36,12 @@ extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOB extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DocumentDelete_google_2ffirestore_2fv1_2fwrite_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fcommon_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DocumentMask_google_2ffirestore_2fv1_2fcommon_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DocumentRemove_google_2ffirestore_2fv1_2fwrite_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListenRequest_LabelsEntry_DoNotUse_google_2ffirestore_2fv1_2ffirestore_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fcommon_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Precondition_google_2ffirestore_2fv1_2fcommon_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fquery_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_StructuredAggregationQuery_google_2ffirestore_2fv1_2fquery_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fquery_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_StructuredQuery_google_2ffirestore_2fv1_2fquery_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<4> scc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Target_DocumentsTarget_google_2ffirestore_2fv1_2ffirestore_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Target_QueryTarget_google_2ffirestore_2fv1_2ffirestore_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_TargetChange_google_2ffirestore_2fv1_2ffirestore_2eproto; @@ -49,6 +49,7 @@ extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fcommon_2eproto ::PROTO extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<5> scc_info_Write_google_2ffirestore_2fv1_2fwrite_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2ffirestore_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_WriteRequest_LabelsEntry_DoNotUse_google_2ffirestore_2fv1_2ffirestore_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_WriteResult_google_2ffirestore_2fv1_2fwrite_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fwrappers_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2frpc_2fstatus_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Status_google_2frpc_2fstatus_2eproto; namespace google { @@ -540,11 +541,12 @@ static void InitDefaultsscc_info_Target_google_2ffirestore_2fv1_2ffirestore_2epr ::google::firestore::v1::Target::InitAsDefaultInstance(); } -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 3, 0, InitDefaultsscc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto}, { +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<4> scc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 4, 0, InitDefaultsscc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto}, { &scc_info_Target_QueryTarget_google_2ffirestore_2fv1_2ffirestore_2eproto.base, &scc_info_Target_DocumentsTarget_google_2ffirestore_2fv1_2ffirestore_2eproto.base, - &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,}}; + &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base, + &scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto.base,}}; static void InitDefaultsscc_info_Target_DocumentsTarget_google_2ffirestore_2fv1_2ffirestore_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -897,6 +899,7 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2ffirestore_2fv1_2ffire offsetof(::google::firestore::v1::TargetDefaultTypeInternal, read_time_), PROTOBUF_FIELD_OFFSET(::google::firestore::v1::Target, target_id_), PROTOBUF_FIELD_OFFSET(::google::firestore::v1::Target, once_), + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::Target, expected_count_), PROTOBUF_FIELD_OFFSET(::google::firestore::v1::Target, target_type_), PROTOBUF_FIELD_OFFSET(::google::firestore::v1::Target, resume_type_), ~0u, // no _has_bits_ @@ -952,9 +955,9 @@ static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOB { 214, -1, sizeof(::google::firestore::v1::Target_DocumentsTarget)}, { 220, -1, sizeof(::google::firestore::v1::Target_QueryTarget)}, { 228, -1, sizeof(::google::firestore::v1::Target)}, - { 241, -1, sizeof(::google::firestore::v1::TargetChange)}, - { 251, -1, sizeof(::google::firestore::v1::ListCollectionIdsRequest)}, - { 259, -1, sizeof(::google::firestore::v1::ListCollectionIdsResponse)}, + { 242, -1, sizeof(::google::firestore::v1::TargetChange)}, + { 252, -1, sizeof(::google::firestore::v1::ListCollectionIdsRequest)}, + { 260, -1, sizeof(::google::firestore::v1::ListCollectionIdsResponse)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -998,198 +1001,200 @@ const char descriptor_table_protodef_google_2ffirestore_2fv1_2ffirestore_2eproto "roto\032\037google/firestore/v1/query.proto\032\037g" "oogle/firestore/v1/write.proto\032\033google/p" "rotobuf/empty.proto\032\037google/protobuf/tim" - "estamp.proto\032\027google/rpc/status.proto\"\263\001" - "\n\022GetDocumentRequest\022\014\n\004name\030\001 \001(\t\022/\n\004ma" - "sk\030\002 \001(\0132!.google.firestore.v1.DocumentM" - "ask\022\025\n\013transaction\030\003 \001(\014H\000\022/\n\tread_time\030" - "\005 \001(\0132\032.google.protobuf.TimestampH\000B\026\n\024c" - "onsistency_selector\"\235\002\n\024ListDocumentsReq" - "uest\022\016\n\006parent\030\001 \001(\t\022\025\n\rcollection_id\030\002 " - "\001(\t\022\021\n\tpage_size\030\003 \001(\005\022\022\n\npage_token\030\004 \001" - "(\t\022\020\n\010order_by\030\006 \001(\t\022/\n\004mask\030\007 \001(\0132!.goo" - "gle.firestore.v1.DocumentMask\022\025\n\013transac" - "tion\030\010 \001(\014H\000\022/\n\tread_time\030\n \001(\0132\032.google" - ".protobuf.TimestampH\000\022\024\n\014show_missing\030\014 " - "\001(\010B\026\n\024consistency_selector\"b\n\025ListDocum" - "entsResponse\0220\n\tdocuments\030\001 \003(\0132\035.google" - ".firestore.v1.Document\022\027\n\017next_page_toke" - "n\030\002 \001(\t\"\265\001\n\025CreateDocumentRequest\022\016\n\006par" - "ent\030\001 \001(\t\022\025\n\rcollection_id\030\002 \001(\t\022\023\n\013docu" - "ment_id\030\003 \001(\t\022/\n\010document\030\004 \001(\0132\035.google" - ".firestore.v1.Document\022/\n\004mask\030\005 \001(\0132!.g" - "oogle.firestore.v1.DocumentMask\"\356\001\n\025Upda" - "teDocumentRequest\022/\n\010document\030\001 \001(\0132\035.go" - "ogle.firestore.v1.Document\0226\n\013update_mas" - "k\030\002 \001(\0132!.google.firestore.v1.DocumentMa" - "sk\022/\n\004mask\030\003 \001(\0132!.google.firestore.v1.D" - "ocumentMask\022;\n\020current_document\030\004 \001(\0132!." - "google.firestore.v1.Precondition\"b\n\025Dele" - "teDocumentRequest\022\014\n\004name\030\001 \001(\t\022;\n\020curre" - "nt_document\030\002 \001(\0132!.google.firestore.v1." - "Precondition\"\224\002\n\030BatchGetDocumentsReques" - "t\022\020\n\010database\030\001 \001(\t\022\021\n\tdocuments\030\002 \003(\t\022/" - "\n\004mask\030\003 \001(\0132!.google.firestore.v1.Docum" - "entMask\022\025\n\013transaction\030\004 \001(\014H\000\022B\n\017new_tr" - "ansaction\030\005 \001(\0132\'.google.firestore.v1.Tr" - "ansactionOptionsH\000\022/\n\tread_time\030\007 \001(\0132\032." + "estamp.proto\032\036google/protobuf/wrappers.p" + "roto\032\027google/rpc/status.proto\"\263\001\n\022GetDoc" + "umentRequest\022\014\n\004name\030\001 \001(\t\022/\n\004mask\030\002 \001(\013" + "2!.google.firestore.v1.DocumentMask\022\025\n\013t" + "ransaction\030\003 \001(\014H\000\022/\n\tread_time\030\005 \001(\0132\032." "google.protobuf.TimestampH\000B\026\n\024consisten" - "cy_selector\"\254\001\n\031BatchGetDocumentsRespons" - "e\022.\n\005found\030\001 \001(\0132\035.google.firestore.v1.D" - "ocumentH\000\022\021\n\007missing\030\002 \001(\tH\000\022\023\n\013transact" - "ion\030\003 \001(\014\022-\n\tread_time\030\004 \001(\0132\032.google.pr" - "otobuf.TimestampB\010\n\006result\"e\n\027BeginTrans" - "actionRequest\022\020\n\010database\030\001 \001(\t\0228\n\007optio" - "ns\030\002 \001(\0132\'.google.firestore.v1.Transacti" - "onOptions\"/\n\030BeginTransactionResponse\022\023\n" - "\013transaction\030\001 \001(\014\"b\n\rCommitRequest\022\020\n\010d" - "atabase\030\001 \001(\t\022*\n\006writes\030\002 \003(\0132\032.google.f" - "irestore.v1.Write\022\023\n\013transaction\030\003 \001(\014\"z" - "\n\016CommitResponse\0227\n\rwrite_results\030\001 \003(\0132" - " .google.firestore.v1.WriteResult\022/\n\013com" - "mit_time\030\002 \001(\0132\032.google.protobuf.Timesta" - "mp\"8\n\017RollbackRequest\022\020\n\010database\030\001 \001(\t\022" - "\023\n\013transaction\030\002 \001(\014\"\225\002\n\017RunQueryRequest" - "\022\016\n\006parent\030\001 \001(\t\022@\n\020structured_query\030\002 \001" - "(\0132$.google.firestore.v1.StructuredQuery" - "H\000\022\025\n\013transaction\030\005 \001(\014H\001\022B\n\017new_transac" - "tion\030\006 \001(\0132\'.google.firestore.v1.Transac" - "tionOptionsH\001\022/\n\tread_time\030\007 \001(\0132\032.googl" - "e.protobuf.TimestampH\001B\014\n\nquery_typeB\026\n\024" - "consistency_selector\"\240\001\n\020RunQueryRespons" - "e\022\023\n\013transaction\030\002 \001(\014\022/\n\010document\030\001 \001(\013" - "2\035.google.firestore.v1.Document\022-\n\tread_" - "time\030\003 \001(\0132\032.google.protobuf.Timestamp\022\027" - "\n\017skipped_results\030\004 \001(\005\"\267\002\n\032RunAggregati" - "onQueryRequest\022\016\n\006parent\030\001 \001(\t\022W\n\034struct" - "ured_aggregation_query\030\002 \001(\0132/.google.fi" - "restore.v1.StructuredAggregationQueryH\000\022" - "\025\n\013transaction\030\004 \001(\014H\001\022B\n\017new_transactio" + "cy_selector\"\235\002\n\024ListDocumentsRequest\022\016\n\006" + "parent\030\001 \001(\t\022\025\n\rcollection_id\030\002 \001(\t\022\021\n\tp" + "age_size\030\003 \001(\005\022\022\n\npage_token\030\004 \001(\t\022\020\n\010or" + "der_by\030\006 \001(\t\022/\n\004mask\030\007 \001(\0132!.google.fire" + "store.v1.DocumentMask\022\025\n\013transaction\030\010 \001" + "(\014H\000\022/\n\tread_time\030\n \001(\0132\032.google.protobu" + "f.TimestampH\000\022\024\n\014show_missing\030\014 \001(\010B\026\n\024c" + "onsistency_selector\"b\n\025ListDocumentsResp" + "onse\0220\n\tdocuments\030\001 \003(\0132\035.google.firesto" + "re.v1.Document\022\027\n\017next_page_token\030\002 \001(\t\"" + "\265\001\n\025CreateDocumentRequest\022\016\n\006parent\030\001 \001(" + "\t\022\025\n\rcollection_id\030\002 \001(\t\022\023\n\013document_id\030" + "\003 \001(\t\022/\n\010document\030\004 \001(\0132\035.google.firesto" + "re.v1.Document\022/\n\004mask\030\005 \001(\0132!.google.fi" + "restore.v1.DocumentMask\"\356\001\n\025UpdateDocume" + "ntRequest\022/\n\010document\030\001 \001(\0132\035.google.fir" + "estore.v1.Document\0226\n\013update_mask\030\002 \001(\0132" + "!.google.firestore.v1.DocumentMask\022/\n\004ma" + "sk\030\003 \001(\0132!.google.firestore.v1.DocumentM" + "ask\022;\n\020current_document\030\004 \001(\0132!.google.f" + "irestore.v1.Precondition\"b\n\025DeleteDocume" + "ntRequest\022\014\n\004name\030\001 \001(\t\022;\n\020current_docum" + "ent\030\002 \001(\0132!.google.firestore.v1.Precondi" + "tion\"\224\002\n\030BatchGetDocumentsRequest\022\020\n\010dat" + "abase\030\001 \001(\t\022\021\n\tdocuments\030\002 \003(\t\022/\n\004mask\030\003" + " \001(\0132!.google.firestore.v1.DocumentMask\022" + "\025\n\013transaction\030\004 \001(\014H\000\022B\n\017new_transactio" "n\030\005 \001(\0132\'.google.firestore.v1.Transactio" - "nOptionsH\001\022/\n\tread_time\030\006 \001(\0132\032.google.p" - "rotobuf.TimestampH\001B\014\n\nquery_typeB\026\n\024con" - "sistency_selector\"\231\001\n\033RunAggregationQuer" - "yResponse\0226\n\006result\030\001 \001(\0132&.google.fires" - "tore.v1.AggregationResult\022\023\n\013transaction" - "\030\002 \001(\014\022-\n\tread_time\030\003 \001(\0132\032.google.proto" - "buf.Timestamp\"\343\001\n\014WriteRequest\022\020\n\010databa" - "se\030\001 \001(\t\022\021\n\tstream_id\030\002 \001(\t\022*\n\006writes\030\003 " - "\003(\0132\032.google.firestore.v1.Write\022\024\n\014strea" - "m_token\030\004 \001(\014\022=\n\006labels\030\005 \003(\0132-.google.f" - "irestore.v1.WriteRequest.LabelsEntry\032-\n\013" - "LabelsEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:" - "\0028\001\"\242\001\n\rWriteResponse\022\021\n\tstream_id\030\001 \001(\t" - "\022\024\n\014stream_token\030\002 \001(\014\0227\n\rwrite_results\030" - "\003 \003(\0132 .google.firestore.v1.WriteResult\022" - "/\n\013commit_time\030\004 \001(\0132\032.google.protobuf.T" - "imestamp\"\355\001\n\rListenRequest\022\020\n\010database\030\001" - " \001(\t\0221\n\nadd_target\030\002 \001(\0132\033.google.firest" - "ore.v1.TargetH\000\022\027\n\rremove_target\030\003 \001(\005H\000" - "\022>\n\006labels\030\004 \003(\0132..google.firestore.v1.L" - "istenRequest.LabelsEntry\032-\n\013LabelsEntry\022" - "\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B\017\n\rtarge" - "t_change\"\325\002\n\016ListenResponse\022:\n\rtarget_ch" - "ange\030\002 \001(\0132!.google.firestore.v1.TargetC" - "hangeH\000\022>\n\017document_change\030\003 \001(\0132#.googl" - "e.firestore.v1.DocumentChangeH\000\022>\n\017docum" - "ent_delete\030\004 \001(\0132#.google.firestore.v1.D" - "ocumentDeleteH\000\022>\n\017document_remove\030\006 \001(\013" - "2#.google.firestore.v1.DocumentRemoveH\000\022" - "6\n\006filter\030\005 \001(\0132$.google.firestore.v1.Ex" - "istenceFilterH\000B\017\n\rresponse_type\"\241\003\n\006Tar" - "get\0228\n\005query\030\002 \001(\0132\'.google.firestore.v1" - ".Target.QueryTargetH\000\022@\n\tdocuments\030\003 \001(\013" - "2+.google.firestore.v1.Target.DocumentsT" - "argetH\000\022\026\n\014resume_token\030\004 \001(\014H\001\022/\n\tread_" - "time\030\013 \001(\0132\032.google.protobuf.TimestampH\001" - "\022\021\n\ttarget_id\030\005 \001(\005\022\014\n\004once\030\006 \001(\010\032$\n\017Doc" - "umentsTarget\022\021\n\tdocuments\030\002 \003(\t\032m\n\013Query" - "Target\022\016\n\006parent\030\001 \001(\t\022@\n\020structured_que" - "ry\030\002 \001(\0132$.google.firestore.v1.Structure" - "dQueryH\000B\014\n\nquery_typeB\r\n\013target_typeB\r\n" - "\013resume_type\"\252\002\n\014TargetChange\022N\n\022target_" - "change_type\030\001 \001(\01622.google.firestore.v1." - "TargetChange.TargetChangeType\022\022\n\ntarget_" - "ids\030\002 \003(\005\022!\n\005cause\030\003 \001(\0132\022.google.rpc.St" - "atus\022\024\n\014resume_token\030\004 \001(\014\022-\n\tread_time\030" - "\006 \001(\0132\032.google.protobuf.Timestamp\"N\n\020Tar" - "getChangeType\022\r\n\tNO_CHANGE\020\000\022\007\n\003ADD\020\001\022\n\n" - "\006REMOVE\020\002\022\013\n\007CURRENT\020\003\022\t\n\005RESET\020\004\"Q\n\030Lis" - "tCollectionIdsRequest\022\016\n\006parent\030\001 \001(\t\022\021\n" - "\tpage_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(\t\"L\n\031" - "ListCollectionIdsResponse\022\026\n\016collection_" - "ids\030\001 \003(\t\022\027\n\017next_page_token\030\002 \001(\t2\236\024\n\tF" - "irestore\022\217\001\n\013GetDocument\022\'.google.firest" - "ore.v1.GetDocumentRequest\032\035.google.fires" - "tore.v1.Document\"8\202\323\344\223\0022\0220/v1/{name=proj" - "ects/*/databases/*/documents/*/**}\022\262\001\n\rL" - "istDocuments\022).google.firestore.v1.ListD" - "ocumentsRequest\032*.google.firestore.v1.Li" - "stDocumentsResponse\"J\202\323\344\223\002D\022B/v1/{parent" - "=projects/*/databases/*/documents/*/**}/" - "{collection_id}\022\257\001\n\016CreateDocument\022*.goo" - "gle.firestore.v1.CreateDocumentRequest\032\035" - ".google.firestore.v1.Document\"R\202\323\344\223\002L\"@/" - "v1/{parent=projects/*/databases/*/docume" - "nts/**}/{collection_id}:\010document\022\250\001\n\016Up" - "dateDocument\022*.google.firestore.v1.Updat" - "eDocumentRequest\032\035.google.firestore.v1.D" - "ocument\"K\202\323\344\223\002E29/v1/{document.name=proj" - "ects/*/databases/*/documents/*/**}:\010docu" - "ment\022\216\001\n\016DeleteDocument\022*.google.firesto" - "re.v1.DeleteDocumentRequest\032\026.google.pro" - "tobuf.Empty\"8\202\323\344\223\0022*0/v1/{name=projects/" - "*/databases/*/documents/*/**}\022\271\001\n\021BatchG" - "etDocuments\022-.google.firestore.v1.BatchG" - "etDocumentsRequest\032..google.firestore.v1" - ".BatchGetDocumentsResponse\"C\202\323\344\223\002=\"8/v1/" - "{database=projects/*/databases/*}/docume" - "nts:batchGet:\001*0\001\022\274\001\n\020BeginTransaction\022," - ".google.firestore.v1.BeginTransactionReq" - "uest\032-.google.firestore.v1.BeginTransact" - "ionResponse\"K\202\323\344\223\002E\"@/v1/{database=proje" - "cts/*/databases/*}/documents:beginTransa" - "ction:\001*\022\224\001\n\006Commit\022\".google.firestore.v" - "1.CommitRequest\032#.google.firestore.v1.Co" - "mmitResponse\"A\202\323\344\223\002;\"6/v1/{database=proj" - "ects/*/databases/*}/documents:commit:\001*\022" - "\215\001\n\010Rollback\022$.google.firestore.v1.Rollb" - "ackRequest\032\026.google.protobuf.Empty\"C\202\323\344\223" - "\002=\"8/v1/{database=projects/*/databases/*" - "}/documents:rollback:\001*\022\337\001\n\010RunQuery\022$.g" - "oogle.firestore.v1.RunQueryRequest\032%.goo" - "gle.firestore.v1.RunQueryResponse\"\203\001\202\323\344\223" - "\002}\"6/v1/{parent=projects/*/databases/*/d" - "ocuments}:runQuery:\001*Z@\";/v1/{parent=pro" - "jects/*/databases/*/documents/*/**}:runQ" - "uery:\001*0\001\022\227\002\n\023RunAggregationQuery\022/.goog" - "le.firestore.v1.RunAggregationQueryReque" - "st\0320.google.firestore.v1.RunAggregationQ" - "ueryResponse\"\232\001\202\323\344\223\002\223\001\"A/v1/{parent=proj" - "ects/*/databases/*/documents}:runAggrega" - "tionQuery:\001*ZK\"F/v1/{parent=projects/*/d" - "atabases/*/documents/*/**}:runAggregatio" - "nQuery:\001*0\001\022\224\001\n\005Write\022!.google.firestore" - ".v1.WriteRequest\032\".google.firestore.v1.W" - "riteResponse\"@\202\323\344\223\002:\"5/v1/{database=proj" - "ects/*/databases/*}/documents:write:\001*(\001" - "0\001\022\230\001\n\006Listen\022\".google.firestore.v1.List" - "enRequest\032#.google.firestore.v1.ListenRe" - "sponse\"A\202\323\344\223\002;\"6/v1/{database=projects/*" - "/databases/*}/documents:listen:\001*(\0010\001\022\213\002" - "\n\021ListCollectionIds\022-.google.firestore.v" - "1.ListCollectionIdsRequest\032..google.fire" - "store.v1.ListCollectionIdsResponse\"\226\001\202\323\344" - "\223\002\217\001\"\?/v1/{parent=projects/*/databases/*" - "/documents}:listCollectionIds:\001*ZI\"D/v1/" - "{parent=projects/*/databases/*/documents" - "/*/**}:listCollectionIds:\001*B\262\001\n\027com.goog" - "le.firestore.v1B\016FirestoreProtoP\001Z\n\006labe" + "ls\030\004 \003(\0132..google.firestore.v1.ListenReq" + "uest.LabelsEntry\032-\n\013LabelsEntry\022\013\n\003key\030\001" + " \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001B\017\n\rtarget_change" + "\"\325\002\n\016ListenResponse\022:\n\rtarget_change\030\002 \001" + "(\0132!.google.firestore.v1.TargetChangeH\000\022" + ">\n\017document_change\030\003 \001(\0132#.google.firest" + "ore.v1.DocumentChangeH\000\022>\n\017document_dele" + "te\030\004 \001(\0132#.google.firestore.v1.DocumentD" + "eleteH\000\022>\n\017document_remove\030\006 \001(\0132#.googl" + "e.firestore.v1.DocumentRemoveH\000\0226\n\006filte" + "r\030\005 \001(\0132$.google.firestore.v1.ExistenceF" + "ilterH\000B\017\n\rresponse_type\"\326\003\n\006Target\0228\n\005q" + "uery\030\002 \001(\0132\'.google.firestore.v1.Target." + "QueryTargetH\000\022@\n\tdocuments\030\003 \001(\0132+.googl" + "e.firestore.v1.Target.DocumentsTargetH\000\022" + "\026\n\014resume_token\030\004 \001(\014H\001\022/\n\tread_time\030\013 \001" + "(\0132\032.google.protobuf.TimestampH\001\022\021\n\ttarg" + "et_id\030\005 \001(\005\022\014\n\004once\030\006 \001(\010\0223\n\016expected_co" + "unt\030\014 \001(\0132\033.google.protobuf.Int32Value\032$" + "\n\017DocumentsTarget\022\021\n\tdocuments\030\002 \003(\t\032m\n\013" + "QueryTarget\022\016\n\006parent\030\001 \001(\t\022@\n\020structure" + "d_query\030\002 \001(\0132$.google.firestore.v1.Stru" + "cturedQueryH\000B\014\n\nquery_typeB\r\n\013target_ty" + "peB\r\n\013resume_type\"\252\002\n\014TargetChange\022N\n\022ta" + "rget_change_type\030\001 \001(\01622.google.firestor" + "e.v1.TargetChange.TargetChangeType\022\022\n\nta" + "rget_ids\030\002 \003(\005\022!\n\005cause\030\003 \001(\0132\022.google.r" + "pc.Status\022\024\n\014resume_token\030\004 \001(\014\022-\n\tread_" + "time\030\006 \001(\0132\032.google.protobuf.Timestamp\"N" + "\n\020TargetChangeType\022\r\n\tNO_CHANGE\020\000\022\007\n\003ADD" + "\020\001\022\n\n\006REMOVE\020\002\022\013\n\007CURRENT\020\003\022\t\n\005RESET\020\004\"Q" + "\n\030ListCollectionIdsRequest\022\016\n\006parent\030\001 \001" + "(\t\022\021\n\tpage_size\030\002 \001(\005\022\022\n\npage_token\030\003 \001(" + "\t\"L\n\031ListCollectionIdsResponse\022\026\n\016collec" + "tion_ids\030\001 \003(\t\022\027\n\017next_page_token\030\002 \001(\t2" + "\236\024\n\tFirestore\022\217\001\n\013GetDocument\022\'.google.f" + "irestore.v1.GetDocumentRequest\032\035.google." + "firestore.v1.Document\"8\202\323\344\223\0022\0220/v1/{name" + "=projects/*/databases/*/documents/*/**}\022" + "\262\001\n\rListDocuments\022).google.firestore.v1." + "ListDocumentsRequest\032*.google.firestore." + "v1.ListDocumentsResponse\"J\202\323\344\223\002D\022B/v1/{p" + "arent=projects/*/databases/*/documents/*" + "/**}/{collection_id}\022\257\001\n\016CreateDocument\022" + "*.google.firestore.v1.CreateDocumentRequ" + "est\032\035.google.firestore.v1.Document\"R\202\323\344\223" + "\002L\"@/v1/{parent=projects/*/databases/*/d" + "ocuments/**}/{collection_id}:\010document\022\250" + "\001\n\016UpdateDocument\022*.google.firestore.v1." + "UpdateDocumentRequest\032\035.google.firestore" + ".v1.Document\"K\202\323\344\223\002E29/v1/{document.name" + "=projects/*/databases/*/documents/*/**}:" + "\010document\022\216\001\n\016DeleteDocument\022*.google.fi" + "restore.v1.DeleteDocumentRequest\032\026.googl" + "e.protobuf.Empty\"8\202\323\344\223\0022*0/v1/{name=proj" + "ects/*/databases/*/documents/*/**}\022\271\001\n\021B" + "atchGetDocuments\022-.google.firestore.v1.B" + "atchGetDocumentsRequest\032..google.firesto" + "re.v1.BatchGetDocumentsResponse\"C\202\323\344\223\002=\"" + "8/v1/{database=projects/*/databases/*}/d" + "ocuments:batchGet:\001*0\001\022\274\001\n\020BeginTransact" + "ion\022,.google.firestore.v1.BeginTransacti" + "onRequest\032-.google.firestore.v1.BeginTra" + "nsactionResponse\"K\202\323\344\223\002E\"@/v1/{database=" + "projects/*/databases/*}/documents:beginT" + "ransaction:\001*\022\224\001\n\006Commit\022\".google.firest" + "ore.v1.CommitRequest\032#.google.firestore." + "v1.CommitResponse\"A\202\323\344\223\002;\"6/v1/{database" + "=projects/*/databases/*}/documents:commi" + "t:\001*\022\215\001\n\010Rollback\022$.google.firestore.v1." + "RollbackRequest\032\026.google.protobuf.Empty\"" + "C\202\323\344\223\002=\"8/v1/{database=projects/*/databa" + "ses/*}/documents:rollback:\001*\022\337\001\n\010RunQuer" + "y\022$.google.firestore.v1.RunQueryRequest\032" + "%.google.firestore.v1.RunQueryResponse\"\203" + "\001\202\323\344\223\002}\"6/v1/{parent=projects/*/database" + "s/*/documents}:runQuery:\001*Z@\";/v1/{paren" + "t=projects/*/databases/*/documents/*/**}" + ":runQuery:\001*0\001\022\227\002\n\023RunAggregationQuery\022/" + ".google.firestore.v1.RunAggregationQuery" + "Request\0320.google.firestore.v1.RunAggrega" + "tionQueryResponse\"\232\001\202\323\344\223\002\223\001\"A/v1/{parent" + "=projects/*/databases/*/documents}:runAg" + "gregationQuery:\001*ZK\"F/v1/{parent=project" + "s/*/databases/*/documents/*/**}:runAggre" + "gationQuery:\001*0\001\022\224\001\n\005Write\022!.google.fire" + "store.v1.WriteRequest\032\".google.firestore" + ".v1.WriteResponse\"@\202\323\344\223\002:\"5/v1/{database" + "=projects/*/databases/*}/documents:write" + ":\001*(\0010\001\022\230\001\n\006Listen\022\".google.firestore.v1" + ".ListenRequest\032#.google.firestore.v1.Lis" + "tenResponse\"A\202\323\344\223\002;\"6/v1/{database=proje" + "cts/*/databases/*}/documents:listen:\001*(\001" + "0\001\022\213\002\n\021ListCollectionIds\022-.google.firest" + "ore.v1.ListCollectionIdsRequest\032..google" + ".firestore.v1.ListCollectionIdsResponse\"" + "\226\001\202\323\344\223\002\217\001\"\?/v1/{parent=projects/*/databa" + "ses/*/documents}:listCollectionIds:\001*ZI\"" + "D/v1/{parent=projects/*/databases/*/docu" + "ments/*/**}:listCollectionIds:\001*B\262\001\n\027com" + ".google.firestore.v1B\016FirestoreProtoP\001Z<" + "google.golang.org/genproto/googleapis/fi" + "restore/v1;firestore\242\002\004GCFS\252\002\036Google.Clo" + "ud.Firestore.V1Beta1\312\002\036Google\\Cloud\\Fire" + "store\\V1beta1b\006proto3" ; -static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_deps[9] = { +static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_deps[10] = { &::descriptor_table_google_2fapi_2fannotations_2eproto, &::descriptor_table_google_2ffirestore_2fv1_2faggregation_5fresult_2eproto, &::descriptor_table_google_2ffirestore_2fv1_2fcommon_2eproto, @@ -1198,6 +1203,7 @@ static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor &::descriptor_table_google_2ffirestore_2fv1_2fwrite_2eproto, &::descriptor_table_google_2fprotobuf_2fempty_2eproto, &::descriptor_table_google_2fprotobuf_2ftimestamp_2eproto, + &::descriptor_table_google_2fprotobuf_2fwrappers_2eproto, &::descriptor_table_google_2frpc_2fstatus_2eproto, }; static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_sccs[29] = { @@ -1234,8 +1240,8 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_once; static bool descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto = { - &descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_initialized, descriptor_table_protodef_google_2ffirestore_2fv1_2ffirestore_2eproto, "google/firestore/v1/firestore.proto", 7896, - &descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_once, descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_sccs, descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_deps, 29, 9, + &descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_initialized, descriptor_table_protodef_google_2ffirestore_2fv1_2ffirestore_2eproto, "google/firestore/v1/firestore.proto", 7981, + &descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_once, descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_sccs, descriptor_table_google_2ffirestore_2fv1_2ffirestore_2eproto_deps, 29, 10, schemas, file_default_instances, TableStruct_google_2ffirestore_2fv1_2ffirestore_2eproto::offsets, file_level_metadata_google_2ffirestore_2fv1_2ffirestore_2eproto, 29, file_level_enum_descriptors_google_2ffirestore_2fv1_2ffirestore_2eproto, file_level_service_descriptors_google_2ffirestore_2fv1_2ffirestore_2eproto, }; @@ -9164,12 +9170,15 @@ void Target::InitAsDefaultInstance() { &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); ::google::firestore::v1::_Target_default_instance_.read_time_ = const_cast< PROTOBUF_NAMESPACE_ID::Timestamp*>( PROTOBUF_NAMESPACE_ID::Timestamp::internal_default_instance()); + ::google::firestore::v1::_Target_default_instance_._instance.get_mutable()->expected_count_ = const_cast< PROTOBUF_NAMESPACE_ID::Int32Value*>( + PROTOBUF_NAMESPACE_ID::Int32Value::internal_default_instance()); } class Target::_Internal { public: static const ::google::firestore::v1::Target_QueryTarget& query(const Target* msg); static const ::google::firestore::v1::Target_DocumentsTarget& documents(const Target* msg); static const PROTOBUF_NAMESPACE_ID::Timestamp& read_time(const Target* msg); + static const PROTOBUF_NAMESPACE_ID::Int32Value& expected_count(const Target* msg); }; const ::google::firestore::v1::Target_QueryTarget& @@ -9184,6 +9193,10 @@ const PROTOBUF_NAMESPACE_ID::Timestamp& Target::_Internal::read_time(const Target* msg) { return *msg->resume_type_.read_time_; } +const PROTOBUF_NAMESPACE_ID::Int32Value& +Target::_Internal::expected_count(const Target* msg) { + return *msg->expected_count_; +} void Target::set_allocated_query(::google::firestore::v1::Target_QueryTarget* query) { ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); clear_target_type(); @@ -9233,6 +9246,12 @@ void Target::clear_read_time() { clear_has_resume_type(); } } +void Target::clear_expected_count() { + if (GetArenaNoVirtual() == nullptr && expected_count_ != nullptr) { + delete expected_count_; + } + expected_count_ = nullptr; +} Target::Target() : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { SharedCtor(); @@ -9242,6 +9261,11 @@ Target::Target(const Target& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { _internal_metadata_.MergeFrom(from._internal_metadata_); + if (from._internal_has_expected_count()) { + expected_count_ = new PROTOBUF_NAMESPACE_ID::Int32Value(*from.expected_count_); + } else { + expected_count_ = nullptr; + } ::memcpy(&target_id_, &from.target_id_, static_cast(reinterpret_cast(&once_) - reinterpret_cast(&target_id_)) + sizeof(once_)); @@ -9278,9 +9302,9 @@ Target::Target(const Target& from) void Target::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Target_google_2ffirestore_2fv1_2ffirestore_2eproto.base); - ::memset(&target_id_, 0, static_cast( + ::memset(&expected_count_, 0, static_cast( reinterpret_cast(&once_) - - reinterpret_cast(&target_id_)) + sizeof(once_)); + reinterpret_cast(&expected_count_)) + sizeof(once_)); clear_has_target_type(); clear_has_resume_type(); } @@ -9291,6 +9315,7 @@ Target::~Target() { } void Target::SharedDtor() { + if (this != internal_default_instance()) delete expected_count_; if (has_target_type()) { clear_target_type(); } @@ -9351,6 +9376,10 @@ void Target::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + if (GetArenaNoVirtual() == nullptr && expected_count_ != nullptr) { + delete expected_count_; + } + expected_count_ = nullptr; ::memset(&target_id_, 0, static_cast( reinterpret_cast(&once_) - reinterpret_cast(&target_id_)) + sizeof(once_)); @@ -9409,6 +9438,13 @@ const char* Target::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int CHK_(ptr); } else goto handle_unusual; continue; + // .google.protobuf.Int32Value expected_count = 12; + case 12: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 98)) { + ptr = ctx->ParseMessage(_internal_mutable_expected_count(), ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; default: { handle_unusual: if ((tag & 7) == 4 || tag == 0) { @@ -9477,6 +9513,14 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Target::_InternalSerialize( 11, _Internal::read_time(this), target, stream); } + // .google.protobuf.Int32Value expected_count = 12; + if (this->has_expected_count()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 12, _Internal::expected_count(this), target, stream); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields(), target, stream); @@ -9493,6 +9537,13 @@ size_t Target::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + // .google.protobuf.Int32Value expected_count = 12; + if (this->has_expected_count()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *expected_count_); + } + // int32 target_id = 5; if (this->target_id() != 0) { total_size += 1 + @@ -9574,6 +9625,9 @@ void Target::MergeFrom(const Target& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; + if (from.has_expected_count()) { + _internal_mutable_expected_count()->PROTOBUF_NAMESPACE_ID::Int32Value::MergeFrom(from._internal_expected_count()); + } if (from.target_id() != 0) { _internal_set_target_id(from._internal_target_id()); } @@ -9629,6 +9683,7 @@ bool Target::IsInitialized() const { void Target::InternalSwap(Target* other) { using std::swap; _internal_metadata_.Swap(&other->_internal_metadata_); + swap(expected_count_, other->expected_count_); swap(target_id_, other->target_id_); swap(once_, other->once_); swap(target_type_, other->target_type_); diff --git a/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.h b/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.h index ca9ee65d692..3f1c9adee68 100644 --- a/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.h +++ b/Firestore/Protos/cpp/google/firestore/v1/firestore.pb.h @@ -60,6 +60,7 @@ #include "google/firestore/v1/write.pb.h" #include #include +#include #include "google/rpc/status.pb.h" // @@protoc_insertion_point(includes) #include @@ -4830,6 +4831,7 @@ class Target : // accessors ------------------------------------------------------- enum : int { + kExpectedCountFieldNumber = 12, kTargetIdFieldNumber = 5, kOnceFieldNumber = 6, kQueryFieldNumber = 2, @@ -4837,6 +4839,21 @@ class Target : kResumeTokenFieldNumber = 4, kReadTimeFieldNumber = 11, }; + // .google.protobuf.Int32Value expected_count = 12; + bool has_expected_count() const; + private: + bool _internal_has_expected_count() const; + public: + void clear_expected_count(); + const PROTOBUF_NAMESPACE_ID::Int32Value& expected_count() const; + PROTOBUF_NAMESPACE_ID::Int32Value* release_expected_count(); + PROTOBUF_NAMESPACE_ID::Int32Value* mutable_expected_count(); + void set_allocated_expected_count(PROTOBUF_NAMESPACE_ID::Int32Value* expected_count); + private: + const PROTOBUF_NAMESPACE_ID::Int32Value& _internal_expected_count() const; + PROTOBUF_NAMESPACE_ID::Int32Value* _internal_mutable_expected_count(); + public: + // int32 target_id = 5; void clear_target_id(); ::PROTOBUF_NAMESPACE_ID::int32 target_id() const; @@ -4938,6 +4955,7 @@ class Target : inline void clear_has_resume_type(); ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + PROTOBUF_NAMESPACE_ID::Int32Value* expected_count_; ::PROTOBUF_NAMESPACE_ID::int32 target_id_; bool once_; union TargetTypeUnion { @@ -10599,6 +10617,61 @@ inline void Target::set_once(bool value) { // @@protoc_insertion_point(field_set:google.firestore.v1.Target.once) } +// .google.protobuf.Int32Value expected_count = 12; +inline bool Target::_internal_has_expected_count() const { + return this != internal_default_instance() && expected_count_ != nullptr; +} +inline bool Target::has_expected_count() const { + return _internal_has_expected_count(); +} +inline const PROTOBUF_NAMESPACE_ID::Int32Value& Target::_internal_expected_count() const { + const PROTOBUF_NAMESPACE_ID::Int32Value* p = expected_count_; + return p != nullptr ? *p : *reinterpret_cast( + &PROTOBUF_NAMESPACE_ID::_Int32Value_default_instance_); +} +inline const PROTOBUF_NAMESPACE_ID::Int32Value& Target::expected_count() const { + // @@protoc_insertion_point(field_get:google.firestore.v1.Target.expected_count) + return _internal_expected_count(); +} +inline PROTOBUF_NAMESPACE_ID::Int32Value* Target::release_expected_count() { + // @@protoc_insertion_point(field_release:google.firestore.v1.Target.expected_count) + + PROTOBUF_NAMESPACE_ID::Int32Value* temp = expected_count_; + expected_count_ = nullptr; + return temp; +} +inline PROTOBUF_NAMESPACE_ID::Int32Value* Target::_internal_mutable_expected_count() { + + if (expected_count_ == nullptr) { + auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + expected_count_ = p; + } + return expected_count_; +} +inline PROTOBUF_NAMESPACE_ID::Int32Value* Target::mutable_expected_count() { + // @@protoc_insertion_point(field_mutable:google.firestore.v1.Target.expected_count) + return _internal_mutable_expected_count(); +} +inline void Target::set_allocated_expected_count(PROTOBUF_NAMESPACE_ID::Int32Value* expected_count) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(expected_count_); + } + if (expected_count) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(expected_count)->GetArena(); + if (message_arena != submessage_arena) { + expected_count = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, expected_count, submessage_arena); + } + + } else { + + } + expected_count_ = expected_count; + // @@protoc_insertion_point(field_set_allocated:google.firestore.v1.Target.expected_count) +} + inline bool Target::has_target_type() const { return target_type_case() != TARGET_TYPE_NOT_SET; } diff --git a/Firestore/Protos/cpp/google/firestore/v1/write.pb.cc b/Firestore/Protos/cpp/google/firestore/v1/write.pb.cc index f331081b05d..9cd2f3fd3c1 100644 --- a/Firestore/Protos/cpp/google/firestore/v1/write.pb.cc +++ b/Firestore/Protos/cpp/google/firestore/v1/write.pb.cc @@ -31,6 +31,7 @@ // @@protoc_insertion_point(includes) #include extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fdocument_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_ArrayValue_google_2ffirestore_2fv1_2fdocument_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fdocument_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_Document_google_2ffirestore_2fv1_2fdocument_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fcommon_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DocumentMask_google_2ffirestore_2fv1_2fcommon_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2ffirestore_2fv1_2fwrite_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DocumentTransform_google_2ffirestore_2fv1_2fwrite_2eproto; @@ -171,8 +172,9 @@ static void InitDefaultsscc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite ::google::firestore::v1::ExistenceFilter::InitAsDefaultInstance(); } -::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto}, {}}; +::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto}, { + &scc_info_BloomFilter_google_2ffirestore_2fv1_2fbloom_5ffilter_2eproto.base,}}; static void InitDefaultsscc_info_Write_google_2ffirestore_2fv1_2fwrite_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -285,6 +287,7 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2ffirestore_2fv1_2fwrit ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(::google::firestore::v1::ExistenceFilter, target_id_), PROTOBUF_FIELD_OFFSET(::google::firestore::v1::ExistenceFilter, count_), + PROTOBUF_FIELD_OFFSET(::google::firestore::v1::ExistenceFilter, unchanged_names_), }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, -1, sizeof(::google::firestore::v1::Write)}, @@ -310,7 +313,8 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2ffirestore_2fv1_2fwrite_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\037google/firestore/v1/write.proto\022\023googl" - "e.firestore.v1\032 google/firestore/v1/comm" + "e.firestore.v1\032&google/firestore/v1/bloo" + "m_filter.proto\032 google/firestore/v1/comm" "on.proto\032\"google/firestore/v1/document.p" "roto\032\037google/protobuf/timestamp.proto\"\355\002" "\n\005Write\022/\n\006update\030\001 \001(\0132\035.google.firesto" @@ -348,15 +352,18 @@ const char descriptor_table_protodef_google_2ffirestore_2fv1_2fwrite_2eproto[] P "-\n\tread_time\030\004 \001(\0132\032.google.protobuf.Tim" "estamp\"m\n\016DocumentRemove\022\020\n\010document\030\001 \001" "(\t\022\032\n\022removed_target_ids\030\002 \003(\005\022-\n\tread_t" - "ime\030\004 \001(\0132\032.google.protobuf.Timestamp\"3\n" + "ime\030\004 \001(\0132\032.google.protobuf.Timestamp\"n\n" "\017ExistenceFilter\022\021\n\ttarget_id\030\001 \001(\005\022\r\n\005c" - "ount\030\002 \001(\005B\256\001\n\027com.google.firestore.v1B\n" - "WriteProtoP\001Zunchanged_names_ = const_cast< ::google::firestore::v1::BloomFilter*>( + ::google::firestore::v1::BloomFilter::internal_default_instance()); } class ExistenceFilter::_Internal { public: + static const ::google::firestore::v1::BloomFilter& unchanged_names(const ExistenceFilter* msg); }; +const ::google::firestore::v1::BloomFilter& +ExistenceFilter::_Internal::unchanged_names(const ExistenceFilter* msg) { + return *msg->unchanged_names_; +} +void ExistenceFilter::clear_unchanged_names() { + if (GetArenaNoVirtual() == nullptr && unchanged_names_ != nullptr) { + delete unchanged_names_; + } + unchanged_names_ = nullptr; +} ExistenceFilter::ExistenceFilter() : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { SharedCtor(); @@ -2852,6 +2872,11 @@ ExistenceFilter::ExistenceFilter(const ExistenceFilter& from) : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { _internal_metadata_.MergeFrom(from._internal_metadata_); + if (from._internal_has_unchanged_names()) { + unchanged_names_ = new ::google::firestore::v1::BloomFilter(*from.unchanged_names_); + } else { + unchanged_names_ = nullptr; + } ::memcpy(&target_id_, &from.target_id_, static_cast(reinterpret_cast(&count_) - reinterpret_cast(&target_id_)) + sizeof(count_)); @@ -2859,9 +2884,10 @@ ExistenceFilter::ExistenceFilter(const ExistenceFilter& from) } void ExistenceFilter::SharedCtor() { - ::memset(&target_id_, 0, static_cast( + ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_ExistenceFilter_google_2ffirestore_2fv1_2fwrite_2eproto.base); + ::memset(&unchanged_names_, 0, static_cast( reinterpret_cast(&count_) - - reinterpret_cast(&target_id_)) + sizeof(count_)); + reinterpret_cast(&unchanged_names_)) + sizeof(count_)); } ExistenceFilter::~ExistenceFilter() { @@ -2870,6 +2896,7 @@ ExistenceFilter::~ExistenceFilter() { } void ExistenceFilter::SharedDtor() { + if (this != internal_default_instance()) delete unchanged_names_; } void ExistenceFilter::SetCachedSize(int size) const { @@ -2887,6 +2914,10 @@ void ExistenceFilter::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + if (GetArenaNoVirtual() == nullptr && unchanged_names_ != nullptr) { + delete unchanged_names_; + } + unchanged_names_ = nullptr; ::memset(&target_id_, 0, static_cast( reinterpret_cast(&count_) - reinterpret_cast(&target_id_)) + sizeof(count_)); @@ -2914,6 +2945,13 @@ const char* ExistenceFilter::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPAC CHK_(ptr); } else goto handle_unusual; continue; + // .google.firestore.v1.BloomFilter unchanged_names = 3; + case 3: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 26)) { + ptr = ctx->ParseMessage(_internal_mutable_unchanged_names(), ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; default: { handle_unusual: if ((tag & 7) == 4 || tag == 0) { @@ -2952,6 +2990,14 @@ ::PROTOBUF_NAMESPACE_ID::uint8* ExistenceFilter::_InternalSerialize( target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(2, this->_internal_count(), target); } + // .google.firestore.v1.BloomFilter unchanged_names = 3; + if (this->has_unchanged_names()) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 3, _Internal::unchanged_names(this), target, stream); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( _internal_metadata_.unknown_fields(), target, stream); @@ -2968,6 +3014,13 @@ size_t ExistenceFilter::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; + // .google.firestore.v1.BloomFilter unchanged_names = 3; + if (this->has_unchanged_names()) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *unchanged_names_); + } + // int32 target_id = 1; if (this->target_id() != 0) { total_size += 1 + @@ -3013,6 +3066,9 @@ void ExistenceFilter::MergeFrom(const ExistenceFilter& from) { ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; + if (from.has_unchanged_names()) { + _internal_mutable_unchanged_names()->::google::firestore::v1::BloomFilter::MergeFrom(from._internal_unchanged_names()); + } if (from.target_id() != 0) { _internal_set_target_id(from._internal_target_id()); } @@ -3042,6 +3098,7 @@ bool ExistenceFilter::IsInitialized() const { void ExistenceFilter::InternalSwap(ExistenceFilter* other) { using std::swap; _internal_metadata_.Swap(&other->_internal_metadata_); + swap(unchanged_names_, other->unchanged_names_); swap(target_id_, other->target_id_); swap(count_, other->count_); } diff --git a/Firestore/Protos/cpp/google/firestore/v1/write.pb.h b/Firestore/Protos/cpp/google/firestore/v1/write.pb.h index f5e7d251cd5..ee2a2ee48b5 100644 --- a/Firestore/Protos/cpp/google/firestore/v1/write.pb.h +++ b/Firestore/Protos/cpp/google/firestore/v1/write.pb.h @@ -49,6 +49,7 @@ #include // IWYU pragma: export #include #include +#include "google/firestore/v1/bloom_filter.pb.h" #include "google/firestore/v1/common.pb.h" #include "google/firestore/v1/document.pb.h" #include @@ -1659,9 +1660,25 @@ class ExistenceFilter : // accessors ------------------------------------------------------- enum : int { + kUnchangedNamesFieldNumber = 3, kTargetIdFieldNumber = 1, kCountFieldNumber = 2, }; + // .google.firestore.v1.BloomFilter unchanged_names = 3; + bool has_unchanged_names() const; + private: + bool _internal_has_unchanged_names() const; + public: + void clear_unchanged_names(); + const ::google::firestore::v1::BloomFilter& unchanged_names() const; + ::google::firestore::v1::BloomFilter* release_unchanged_names(); + ::google::firestore::v1::BloomFilter* mutable_unchanged_names(); + void set_allocated_unchanged_names(::google::firestore::v1::BloomFilter* unchanged_names); + private: + const ::google::firestore::v1::BloomFilter& _internal_unchanged_names() const; + ::google::firestore::v1::BloomFilter* _internal_mutable_unchanged_names(); + public: + // int32 target_id = 1; void clear_target_id(); ::PROTOBUF_NAMESPACE_ID::int32 target_id() const; @@ -1685,6 +1702,7 @@ class ExistenceFilter : class _Internal; ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + ::google::firestore::v1::BloomFilter* unchanged_names_; ::PROTOBUF_NAMESPACE_ID::int32 target_id_; ::PROTOBUF_NAMESPACE_ID::int32 count_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; @@ -3201,6 +3219,60 @@ inline void ExistenceFilter::set_count(::PROTOBUF_NAMESPACE_ID::int32 value) { // @@protoc_insertion_point(field_set:google.firestore.v1.ExistenceFilter.count) } +// .google.firestore.v1.BloomFilter unchanged_names = 3; +inline bool ExistenceFilter::_internal_has_unchanged_names() const { + return this != internal_default_instance() && unchanged_names_ != nullptr; +} +inline bool ExistenceFilter::has_unchanged_names() const { + return _internal_has_unchanged_names(); +} +inline const ::google::firestore::v1::BloomFilter& ExistenceFilter::_internal_unchanged_names() const { + const ::google::firestore::v1::BloomFilter* p = unchanged_names_; + return p != nullptr ? *p : *reinterpret_cast( + &::google::firestore::v1::_BloomFilter_default_instance_); +} +inline const ::google::firestore::v1::BloomFilter& ExistenceFilter::unchanged_names() const { + // @@protoc_insertion_point(field_get:google.firestore.v1.ExistenceFilter.unchanged_names) + return _internal_unchanged_names(); +} +inline ::google::firestore::v1::BloomFilter* ExistenceFilter::release_unchanged_names() { + // @@protoc_insertion_point(field_release:google.firestore.v1.ExistenceFilter.unchanged_names) + + ::google::firestore::v1::BloomFilter* temp = unchanged_names_; + unchanged_names_ = nullptr; + return temp; +} +inline ::google::firestore::v1::BloomFilter* ExistenceFilter::_internal_mutable_unchanged_names() { + + if (unchanged_names_ == nullptr) { + auto* p = CreateMaybeMessage<::google::firestore::v1::BloomFilter>(GetArenaNoVirtual()); + unchanged_names_ = p; + } + return unchanged_names_; +} +inline ::google::firestore::v1::BloomFilter* ExistenceFilter::mutable_unchanged_names() { + // @@protoc_insertion_point(field_mutable:google.firestore.v1.ExistenceFilter.unchanged_names) + return _internal_mutable_unchanged_names(); +} +inline void ExistenceFilter::set_allocated_unchanged_names(::google::firestore::v1::BloomFilter* unchanged_names) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(unchanged_names_); + } + if (unchanged_names) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + if (message_arena != submessage_arena) { + unchanged_names = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, unchanged_names, submessage_arena); + } + + } else { + + } + unchanged_names_ = unchanged_names; + // @@protoc_insertion_point(field_set_allocated:google.firestore.v1.ExistenceFilter.unchanged_names) +} + #ifdef __GNUC__ #pragma GCC diagnostic pop #endif // __GNUC__ diff --git a/Firestore/Protos/nanopb/google/firestore/v1/bloom_filter.nanopb.cc b/Firestore/Protos/nanopb/google/firestore/v1/bloom_filter.nanopb.cc new file mode 100644 index 00000000000..45da032ef97 --- /dev/null +++ b/Firestore/Protos/nanopb/google/firestore/v1/bloom_filter.nanopb.cc @@ -0,0 +1,112 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.8 */ + +#include "bloom_filter.nanopb.h" + +#include "Firestore/core/src/nanopb/pretty_printing.h" + +namespace firebase { +namespace firestore { + +using nanopb::PrintEnumField; +using nanopb::PrintHeader; +using nanopb::PrintMessageField; +using nanopb::PrintPrimitiveField; +using nanopb::PrintTail; + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_firestore_v1_BitSequence_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_BitSequence, bitmap, bitmap, 0), + PB_FIELD( 2, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_BitSequence, padding, bitmap, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_BloomFilter_fields[3] = { + PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, google_firestore_v1_BloomFilter, bits, bits, &google_firestore_v1_BitSequence_fields), + PB_FIELD( 2, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_BloomFilter, hash_count, bits, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_BloomFilter, bits) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_BitSequence_google_firestore_v1_BloomFilter) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_BloomFilter, bits) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_BitSequence_google_firestore_v1_BloomFilter) +#endif + + +std::string google_firestore_v1_BitSequence::ToString(int indent) const { + std::string tostring_header = PrintHeader(indent, "BitSequence", this); + std::string tostring_result; + + tostring_result += PrintPrimitiveField("bitmap: ", + bitmap, indent + 1, false); + tostring_result += PrintPrimitiveField("padding: ", + padding, indent + 1, false); + + bool is_root = indent == 0; + if (!tostring_result.empty() || is_root) { + std::string tostring_tail = PrintTail(indent); + return tostring_header + tostring_result + tostring_tail; + } else { + return ""; + } +} + +std::string google_firestore_v1_BloomFilter::ToString(int indent) const { + std::string tostring_header = PrintHeader(indent, "BloomFilter", this); + std::string tostring_result; + + if (has_bits) { + tostring_result += PrintMessageField("bits ", bits, indent + 1, true); + } + tostring_result += PrintPrimitiveField("hash_count: ", + hash_count, indent + 1, false); + + std::string tostring_tail = PrintTail(indent); + return tostring_header + tostring_result + tostring_tail; +} + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/Firestore/Protos/nanopb/google/firestore/v1/bloom_filter.nanopb.h b/Firestore/Protos/nanopb/google/firestore/v1/bloom_filter.nanopb.h new file mode 100644 index 00000000000..925d70db281 --- /dev/null +++ b/Firestore/Protos/nanopb/google/firestore/v1/bloom_filter.nanopb.h @@ -0,0 +1,88 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.8 */ + +#ifndef PB_GOOGLE_FIRESTORE_V1_BLOOM_FILTER_NANOPB_H_INCLUDED +#define PB_GOOGLE_FIRESTORE_V1_BLOOM_FILTER_NANOPB_H_INCLUDED +#include + +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_firestore_v1_BitSequence { + pb_bytes_array_t *bitmap; + int32_t padding; + + std::string ToString(int indent = 0) const; +/* @@protoc_insertion_point(struct:google_firestore_v1_BitSequence) */ +} google_firestore_v1_BitSequence; + +typedef struct _google_firestore_v1_BloomFilter { + bool has_bits; + google_firestore_v1_BitSequence bits; + int32_t hash_count; + + std::string ToString(int indent = 0) const; +/* @@protoc_insertion_point(struct:google_firestore_v1_BloomFilter) */ +} google_firestore_v1_BloomFilter; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_firestore_v1_BitSequence_init_default {NULL, 0} +#define google_firestore_v1_BloomFilter_init_default {false, google_firestore_v1_BitSequence_init_default, 0} +#define google_firestore_v1_BitSequence_init_zero {NULL, 0} +#define google_firestore_v1_BloomFilter_init_zero {false, google_firestore_v1_BitSequence_init_zero, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_firestore_v1_BitSequence_bitmap_tag 1 +#define google_firestore_v1_BitSequence_padding_tag 2 +#define google_firestore_v1_BloomFilter_bits_tag 1 +#define google_firestore_v1_BloomFilter_hash_count_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_firestore_v1_BitSequence_fields[3]; +extern const pb_field_t google_firestore_v1_BloomFilter_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_firestore_v1_BitSequence_size depends on runtime parameters */ +/* google_firestore_v1_BloomFilter_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define BLOOM_FILTER_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc b/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc index 5004cfa9193..4013605af20 100644 --- a/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc +++ b/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc @@ -214,13 +214,14 @@ const pb_field_t google_firestore_v1_ListenResponse_fields[6] = { PB_LAST_FIELD }; -const pb_field_t google_firestore_v1_Target_fields[7] = { +const pb_field_t google_firestore_v1_Target_fields[8] = { PB_ONEOF_FIELD(target_type, 2, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_Target, query, query, &google_firestore_v1_Target_QueryTarget_fields), PB_ONEOF_FIELD(target_type, 3, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Target, documents, documents, &google_firestore_v1_Target_DocumentsTarget_fields), PB_ONEOF_FIELD(resume_type, 4, BYTES , ONEOF, POINTER , OTHER, google_firestore_v1_Target, resume_token, target_type.documents, 0), PB_ONEOF_FIELD(resume_type, 11, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Target, read_time, target_type.documents, &google_protobuf_Timestamp_fields), PB_FIELD( 5, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_Target, target_id, resume_type.read_time, 0), PB_FIELD( 6, BOOL , SINGULAR, STATIC , OTHER, google_firestore_v1_Target, once, target_id, 0), + PB_FIELD( 12, MESSAGE , OPTIONAL, STATIC , OTHER, google_firestore_v1_Target, expected_count, once, &google_protobuf_Int32Value_fields), PB_LAST_FIELD }; @@ -268,7 +269,7 @@ const pb_field_t google_firestore_v1_ListCollectionIdsResponse_fields[3] = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_GetDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_ListDocumentsRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_ListDocumentsRequest, mask) < 65536 && pb_membersize(google_firestore_v1_CreateDocumentRequest, document) < 65536 && pb_membersize(google_firestore_v1_CreateDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, document) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, update_mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, current_document) < 65536 && pb_membersize(google_firestore_v1_DeleteDocumentRequest, current_document) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, new_transaction) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, mask) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, found) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_BeginTransactionRequest, options) < 65536 && pb_membersize(google_firestore_v1_CommitResponse, commit_time) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, query_type.structured_query) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.new_transaction) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.read_time) < 65536 && pb_membersize(google_firestore_v1_RunQueryResponse, document) < 65536 && pb_membersize(google_firestore_v1_RunQueryResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, query_type.structured_aggregation_query) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.new_transaction) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.read_time) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, result) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_WriteResponse, commit_time) < 65536 && pb_membersize(google_firestore_v1_ListenRequest, add_target) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, target_change) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_change) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_delete) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, filter) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_remove) < 65536 && pb_membersize(google_firestore_v1_Target, target_type.query) < 65536 && pb_membersize(google_firestore_v1_Target, target_type.documents) < 65536 && pb_membersize(google_firestore_v1_Target, resume_type.read_time) < 65536 && pb_membersize(google_firestore_v1_Target_QueryTarget, structured_query) < 65536 && pb_membersize(google_firestore_v1_TargetChange, cause) < 65536 && pb_membersize(google_firestore_v1_TargetChange, read_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_GetDocumentRequest_google_firestore_v1_ListDocumentsRequest_google_firestore_v1_ListDocumentsResponse_google_firestore_v1_CreateDocumentRequest_google_firestore_v1_UpdateDocumentRequest_google_firestore_v1_DeleteDocumentRequest_google_firestore_v1_BatchGetDocumentsRequest_google_firestore_v1_BatchGetDocumentsResponse_google_firestore_v1_BeginTransactionRequest_google_firestore_v1_BeginTransactionResponse_google_firestore_v1_CommitRequest_google_firestore_v1_CommitResponse_google_firestore_v1_RollbackRequest_google_firestore_v1_RunQueryRequest_google_firestore_v1_RunQueryResponse_google_firestore_v1_RunAggregationQueryRequest_google_firestore_v1_RunAggregationQueryResponse_google_firestore_v1_WriteRequest_google_firestore_v1_WriteRequest_LabelsEntry_google_firestore_v1_WriteResponse_google_firestore_v1_ListenRequest_google_firestore_v1_ListenRequest_LabelsEntry_google_firestore_v1_ListenResponse_google_firestore_v1_Target_google_firestore_v1_Target_DocumentsTarget_google_firestore_v1_Target_QueryTarget_google_firestore_v1_TargetChange_google_firestore_v1_ListCollectionIdsRequest_google_firestore_v1_ListCollectionIdsResponse) +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_GetDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_ListDocumentsRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_ListDocumentsRequest, mask) < 65536 && pb_membersize(google_firestore_v1_CreateDocumentRequest, document) < 65536 && pb_membersize(google_firestore_v1_CreateDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, document) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, update_mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, current_document) < 65536 && pb_membersize(google_firestore_v1_DeleteDocumentRequest, current_document) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, new_transaction) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, mask) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, found) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_BeginTransactionRequest, options) < 65536 && pb_membersize(google_firestore_v1_CommitResponse, commit_time) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, query_type.structured_query) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.new_transaction) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.read_time) < 65536 && pb_membersize(google_firestore_v1_RunQueryResponse, document) < 65536 && pb_membersize(google_firestore_v1_RunQueryResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, query_type.structured_aggregation_query) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.new_transaction) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.read_time) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, result) < 65536 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_WriteResponse, commit_time) < 65536 && pb_membersize(google_firestore_v1_ListenRequest, add_target) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, target_change) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_change) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_delete) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, filter) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_remove) < 65536 && pb_membersize(google_firestore_v1_Target, target_type.query) < 65536 && pb_membersize(google_firestore_v1_Target, target_type.documents) < 65536 && pb_membersize(google_firestore_v1_Target, resume_type.read_time) < 65536 && pb_membersize(google_firestore_v1_Target, expected_count) < 65536 && pb_membersize(google_firestore_v1_Target_QueryTarget, structured_query) < 65536 && pb_membersize(google_firestore_v1_TargetChange, cause) < 65536 && pb_membersize(google_firestore_v1_TargetChange, read_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_GetDocumentRequest_google_firestore_v1_ListDocumentsRequest_google_firestore_v1_ListDocumentsResponse_google_firestore_v1_CreateDocumentRequest_google_firestore_v1_UpdateDocumentRequest_google_firestore_v1_DeleteDocumentRequest_google_firestore_v1_BatchGetDocumentsRequest_google_firestore_v1_BatchGetDocumentsResponse_google_firestore_v1_BeginTransactionRequest_google_firestore_v1_BeginTransactionResponse_google_firestore_v1_CommitRequest_google_firestore_v1_CommitResponse_google_firestore_v1_RollbackRequest_google_firestore_v1_RunQueryRequest_google_firestore_v1_RunQueryResponse_google_firestore_v1_RunAggregationQueryRequest_google_firestore_v1_RunAggregationQueryResponse_google_firestore_v1_WriteRequest_google_firestore_v1_WriteRequest_LabelsEntry_google_firestore_v1_WriteResponse_google_firestore_v1_ListenRequest_google_firestore_v1_ListenRequest_LabelsEntry_google_firestore_v1_ListenResponse_google_firestore_v1_Target_google_firestore_v1_Target_DocumentsTarget_google_firestore_v1_Target_QueryTarget_google_firestore_v1_TargetChange_google_firestore_v1_ListCollectionIdsRequest_google_firestore_v1_ListCollectionIdsResponse) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) @@ -279,7 +280,7 @@ PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_tim * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_time) < 256 && pb_membersize(google_firestore_v1_GetDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_ListDocumentsRequest, read_time) < 256 && pb_membersize(google_firestore_v1_ListDocumentsRequest, mask) < 256 && pb_membersize(google_firestore_v1_CreateDocumentRequest, document) < 256 && pb_membersize(google_firestore_v1_CreateDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, document) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, update_mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, current_document) < 256 && pb_membersize(google_firestore_v1_DeleteDocumentRequest, current_document) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, new_transaction) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, read_time) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, mask) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, found) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, read_time) < 256 && pb_membersize(google_firestore_v1_BeginTransactionRequest, options) < 256 && pb_membersize(google_firestore_v1_CommitResponse, commit_time) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, query_type.structured_query) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.new_transaction) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.read_time) < 256 && pb_membersize(google_firestore_v1_RunQueryResponse, document) < 256 && pb_membersize(google_firestore_v1_RunQueryResponse, read_time) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, query_type.structured_aggregation_query) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.new_transaction) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.read_time) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, result) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, read_time) < 256 && pb_membersize(google_firestore_v1_WriteResponse, commit_time) < 256 && pb_membersize(google_firestore_v1_ListenRequest, add_target) < 256 && pb_membersize(google_firestore_v1_ListenResponse, target_change) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_change) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_delete) < 256 && pb_membersize(google_firestore_v1_ListenResponse, filter) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_remove) < 256 && pb_membersize(google_firestore_v1_Target, target_type.query) < 256 && pb_membersize(google_firestore_v1_Target, target_type.documents) < 256 && pb_membersize(google_firestore_v1_Target, resume_type.read_time) < 256 && pb_membersize(google_firestore_v1_Target_QueryTarget, structured_query) < 256 && pb_membersize(google_firestore_v1_TargetChange, cause) < 256 && pb_membersize(google_firestore_v1_TargetChange, read_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_GetDocumentRequest_google_firestore_v1_ListDocumentsRequest_google_firestore_v1_ListDocumentsResponse_google_firestore_v1_CreateDocumentRequest_google_firestore_v1_UpdateDocumentRequest_google_firestore_v1_DeleteDocumentRequest_google_firestore_v1_BatchGetDocumentsRequest_google_firestore_v1_BatchGetDocumentsResponse_google_firestore_v1_BeginTransactionRequest_google_firestore_v1_BeginTransactionResponse_google_firestore_v1_CommitRequest_google_firestore_v1_CommitResponse_google_firestore_v1_RollbackRequest_google_firestore_v1_RunQueryRequest_google_firestore_v1_RunQueryResponse_google_firestore_v1_RunAggregationQueryRequest_google_firestore_v1_RunAggregationQueryResponse_google_firestore_v1_WriteRequest_google_firestore_v1_WriteRequest_LabelsEntry_google_firestore_v1_WriteResponse_google_firestore_v1_ListenRequest_google_firestore_v1_ListenRequest_LabelsEntry_google_firestore_v1_ListenResponse_google_firestore_v1_Target_google_firestore_v1_Target_DocumentsTarget_google_firestore_v1_Target_QueryTarget_google_firestore_v1_TargetChange_google_firestore_v1_ListCollectionIdsRequest_google_firestore_v1_ListCollectionIdsResponse) +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_time) < 256 && pb_membersize(google_firestore_v1_GetDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_ListDocumentsRequest, read_time) < 256 && pb_membersize(google_firestore_v1_ListDocumentsRequest, mask) < 256 && pb_membersize(google_firestore_v1_CreateDocumentRequest, document) < 256 && pb_membersize(google_firestore_v1_CreateDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, document) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, update_mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, current_document) < 256 && pb_membersize(google_firestore_v1_DeleteDocumentRequest, current_document) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, new_transaction) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, read_time) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, mask) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, found) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, read_time) < 256 && pb_membersize(google_firestore_v1_BeginTransactionRequest, options) < 256 && pb_membersize(google_firestore_v1_CommitResponse, commit_time) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, query_type.structured_query) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.new_transaction) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.read_time) < 256 && pb_membersize(google_firestore_v1_RunQueryResponse, document) < 256 && pb_membersize(google_firestore_v1_RunQueryResponse, read_time) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, query_type.structured_aggregation_query) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.new_transaction) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryRequest, consistency_selector.read_time) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, result) < 256 && pb_membersize(google_firestore_v1_RunAggregationQueryResponse, read_time) < 256 && pb_membersize(google_firestore_v1_WriteResponse, commit_time) < 256 && pb_membersize(google_firestore_v1_ListenRequest, add_target) < 256 && pb_membersize(google_firestore_v1_ListenResponse, target_change) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_change) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_delete) < 256 && pb_membersize(google_firestore_v1_ListenResponse, filter) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_remove) < 256 && pb_membersize(google_firestore_v1_Target, target_type.query) < 256 && pb_membersize(google_firestore_v1_Target, target_type.documents) < 256 && pb_membersize(google_firestore_v1_Target, resume_type.read_time) < 256 && pb_membersize(google_firestore_v1_Target, expected_count) < 256 && pb_membersize(google_firestore_v1_Target_QueryTarget, structured_query) < 256 && pb_membersize(google_firestore_v1_TargetChange, cause) < 256 && pb_membersize(google_firestore_v1_TargetChange, read_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_GetDocumentRequest_google_firestore_v1_ListDocumentsRequest_google_firestore_v1_ListDocumentsResponse_google_firestore_v1_CreateDocumentRequest_google_firestore_v1_UpdateDocumentRequest_google_firestore_v1_DeleteDocumentRequest_google_firestore_v1_BatchGetDocumentsRequest_google_firestore_v1_BatchGetDocumentsResponse_google_firestore_v1_BeginTransactionRequest_google_firestore_v1_BeginTransactionResponse_google_firestore_v1_CommitRequest_google_firestore_v1_CommitResponse_google_firestore_v1_RollbackRequest_google_firestore_v1_RunQueryRequest_google_firestore_v1_RunQueryResponse_google_firestore_v1_RunAggregationQueryRequest_google_firestore_v1_RunAggregationQueryResponse_google_firestore_v1_WriteRequest_google_firestore_v1_WriteRequest_LabelsEntry_google_firestore_v1_WriteResponse_google_firestore_v1_ListenRequest_google_firestore_v1_ListenRequest_LabelsEntry_google_firestore_v1_ListenResponse_google_firestore_v1_Target_google_firestore_v1_Target_DocumentsTarget_google_firestore_v1_Target_QueryTarget_google_firestore_v1_TargetChange_google_firestore_v1_ListCollectionIdsRequest_google_firestore_v1_ListCollectionIdsResponse) #endif @@ -833,14 +834,13 @@ std::string google_firestore_v1_Target::ToString(int indent) const { tostring_result += PrintPrimitiveField("target_id: ", target_id, indent + 1, false); tostring_result += PrintPrimitiveField("once: ", once, indent + 1, false); - - bool is_root = indent == 0; - if (!tostring_result.empty() || is_root) { - std::string tostring_tail = PrintTail(indent); - return tostring_header + tostring_result + tostring_tail; - } else { - return ""; + if (has_expected_count) { + tostring_result += PrintMessageField("expected_count ", + expected_count, indent + 1, true); } + + std::string tostring_tail = PrintTail(indent); + return tostring_header + tostring_result + tostring_tail; } std::string google_firestore_v1_Target_DocumentsTarget::ToString(int indent) const { diff --git a/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h b/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h index fe5e523164d..b2c87a26be2 100644 --- a/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h +++ b/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h @@ -37,6 +37,8 @@ #include "google/protobuf/timestamp.nanopb.h" +#include "google/protobuf/wrappers.nanopb.h" + #include "google/rpc/status.nanopb.h" #include @@ -373,6 +375,8 @@ typedef struct _google_firestore_v1_Target { } resume_type; int32_t target_id; bool once; + bool has_expected_count; + google_protobuf_Int32Value expected_count; std::string ToString(int indent = 0) const; /* @@protoc_insertion_point(struct:google_firestore_v1_Target) */ @@ -418,7 +422,7 @@ typedef struct _google_firestore_v1_ListenRequest { #define google_firestore_v1_ListenRequest_init_default {NULL, 0, {google_firestore_v1_Target_init_default}, 0, NULL} #define google_firestore_v1_ListenRequest_LabelsEntry_init_default {NULL, NULL} #define google_firestore_v1_ListenResponse_init_default {0, {google_firestore_v1_TargetChange_init_default}} -#define google_firestore_v1_Target_init_default {0, {google_firestore_v1_Target_QueryTarget_init_default}, 0, {NULL}, 0, 0} +#define google_firestore_v1_Target_init_default {0, {google_firestore_v1_Target_QueryTarget_init_default}, 0, {NULL}, 0, 0, false, google_protobuf_Int32Value_init_default} #define google_firestore_v1_Target_DocumentsTarget_init_default {0, NULL} #define google_firestore_v1_Target_QueryTarget_init_default {NULL, 0, {google_firestore_v1_StructuredQuery_init_default}} #define google_firestore_v1_TargetChange_init_default {_google_firestore_v1_TargetChange_TargetChangeType_MIN, 0, NULL, false, google_rpc_Status_init_default, NULL, google_protobuf_Timestamp_init_default} @@ -447,7 +451,7 @@ typedef struct _google_firestore_v1_ListenRequest { #define google_firestore_v1_ListenRequest_init_zero {NULL, 0, {google_firestore_v1_Target_init_zero}, 0, NULL} #define google_firestore_v1_ListenRequest_LabelsEntry_init_zero {NULL, NULL} #define google_firestore_v1_ListenResponse_init_zero {0, {google_firestore_v1_TargetChange_init_zero}} -#define google_firestore_v1_Target_init_zero {0, {google_firestore_v1_Target_QueryTarget_init_zero}, 0, {NULL}, 0, 0} +#define google_firestore_v1_Target_init_zero {0, {google_firestore_v1_Target_QueryTarget_init_zero}, 0, {NULL}, 0, 0, false, google_protobuf_Int32Value_init_zero} #define google_firestore_v1_Target_DocumentsTarget_init_zero {0, NULL} #define google_firestore_v1_Target_QueryTarget_init_zero {NULL, 0, {google_firestore_v1_StructuredQuery_init_zero}} #define google_firestore_v1_TargetChange_init_zero {_google_firestore_v1_TargetChange_TargetChangeType_MIN, 0, NULL, false, google_rpc_Status_init_zero, NULL, google_protobuf_Timestamp_init_zero} @@ -555,6 +559,7 @@ typedef struct _google_firestore_v1_ListenRequest { #define google_firestore_v1_Target_read_time_tag 11 #define google_firestore_v1_Target_target_id_tag 5 #define google_firestore_v1_Target_once_tag 6 +#define google_firestore_v1_Target_expected_count_tag 12 #define google_firestore_v1_ListenRequest_add_target_tag 2 #define google_firestore_v1_ListenRequest_remove_target_tag 3 #define google_firestore_v1_ListenRequest_database_tag 1 @@ -584,7 +589,7 @@ extern const pb_field_t google_firestore_v1_WriteResponse_fields[5]; extern const pb_field_t google_firestore_v1_ListenRequest_fields[5]; extern const pb_field_t google_firestore_v1_ListenRequest_LabelsEntry_fields[3]; extern const pb_field_t google_firestore_v1_ListenResponse_fields[6]; -extern const pb_field_t google_firestore_v1_Target_fields[7]; +extern const pb_field_t google_firestore_v1_Target_fields[8]; extern const pb_field_t google_firestore_v1_Target_DocumentsTarget_fields[2]; extern const pb_field_t google_firestore_v1_Target_QueryTarget_fields[3]; extern const pb_field_t google_firestore_v1_TargetChange_fields[6]; diff --git a/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc b/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc index c0d352bf75a..407c3d9b38a 100644 --- a/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc +++ b/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc @@ -92,9 +92,10 @@ const pb_field_t google_firestore_v1_DocumentRemove_fields[4] = { PB_LAST_FIELD }; -const pb_field_t google_firestore_v1_ExistenceFilter_fields[3] = { +const pb_field_t google_firestore_v1_ExistenceFilter_fields[4] = { PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, google_firestore_v1_ExistenceFilter, target_id, target_id, 0), PB_FIELD( 2, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_ExistenceFilter, count, target_id, 0), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_firestore_v1_ExistenceFilter, unchanged_names, count, &google_firestore_v1_BloomFilter_fields), PB_LAST_FIELD }; @@ -109,7 +110,7 @@ const pb_field_t google_firestore_v1_ExistenceFilter_fields[3] = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 65536 && pb_membersize(google_firestore_v1_Write, transform) < 65536 && pb_membersize(google_firestore_v1_Write, update_mask) < 65536 && pb_membersize(google_firestore_v1_Write, current_document) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, increment) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, maximum) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, minimum) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array) < 65536 && pb_membersize(google_firestore_v1_WriteResult, update_time) < 65536 && pb_membersize(google_firestore_v1_DocumentChange, document) < 65536 && pb_membersize(google_firestore_v1_DocumentDelete, read_time) < 65536 && pb_membersize(google_firestore_v1_DocumentRemove, read_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_Write_google_firestore_v1_DocumentTransform_google_firestore_v1_DocumentTransform_FieldTransform_google_firestore_v1_WriteResult_google_firestore_v1_DocumentChange_google_firestore_v1_DocumentDelete_google_firestore_v1_DocumentRemove_google_firestore_v1_ExistenceFilter) +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 65536 && pb_membersize(google_firestore_v1_Write, transform) < 65536 && pb_membersize(google_firestore_v1_Write, update_mask) < 65536 && pb_membersize(google_firestore_v1_Write, current_document) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, increment) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, maximum) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, minimum) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array) < 65536 && pb_membersize(google_firestore_v1_WriteResult, update_time) < 65536 && pb_membersize(google_firestore_v1_DocumentChange, document) < 65536 && pb_membersize(google_firestore_v1_DocumentDelete, read_time) < 65536 && pb_membersize(google_firestore_v1_DocumentRemove, read_time) < 65536 && pb_membersize(google_firestore_v1_ExistenceFilter, unchanged_names) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_Write_google_firestore_v1_DocumentTransform_google_firestore_v1_DocumentTransform_FieldTransform_google_firestore_v1_WriteResult_google_firestore_v1_DocumentChange_google_firestore_v1_DocumentDelete_google_firestore_v1_DocumentRemove_google_firestore_v1_ExistenceFilter) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) @@ -120,7 +121,7 @@ PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 65536 && pb * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 256 && pb_membersize(google_firestore_v1_Write, transform) < 256 && pb_membersize(google_firestore_v1_Write, update_mask) < 256 && pb_membersize(google_firestore_v1_Write, current_document) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, increment) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, maximum) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, minimum) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array) < 256 && pb_membersize(google_firestore_v1_WriteResult, update_time) < 256 && pb_membersize(google_firestore_v1_DocumentChange, document) < 256 && pb_membersize(google_firestore_v1_DocumentDelete, read_time) < 256 && pb_membersize(google_firestore_v1_DocumentRemove, read_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_Write_google_firestore_v1_DocumentTransform_google_firestore_v1_DocumentTransform_FieldTransform_google_firestore_v1_WriteResult_google_firestore_v1_DocumentChange_google_firestore_v1_DocumentDelete_google_firestore_v1_DocumentRemove_google_firestore_v1_ExistenceFilter) +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 256 && pb_membersize(google_firestore_v1_Write, transform) < 256 && pb_membersize(google_firestore_v1_Write, update_mask) < 256 && pb_membersize(google_firestore_v1_Write, current_document) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, increment) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, maximum) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, minimum) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array) < 256 && pb_membersize(google_firestore_v1_WriteResult, update_time) < 256 && pb_membersize(google_firestore_v1_DocumentChange, document) < 256 && pb_membersize(google_firestore_v1_DocumentDelete, read_time) < 256 && pb_membersize(google_firestore_v1_DocumentRemove, read_time) < 256 && pb_membersize(google_firestore_v1_ExistenceFilter, unchanged_names) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_Write_google_firestore_v1_DocumentTransform_google_firestore_v1_DocumentTransform_FieldTransform_google_firestore_v1_WriteResult_google_firestore_v1_DocumentChange_google_firestore_v1_DocumentDelete_google_firestore_v1_DocumentRemove_google_firestore_v1_ExistenceFilter) #endif @@ -316,14 +317,13 @@ std::string google_firestore_v1_ExistenceFilter::ToString(int indent) const { target_id, indent + 1, false); tostring_result += PrintPrimitiveField("count: ", count, indent + 1, false); - - bool is_root = indent == 0; - if (!tostring_result.empty() || is_root) { - std::string tostring_tail = PrintTail(indent); - return tostring_header + tostring_result + tostring_tail; - } else { - return ""; + if (has_unchanged_names) { + tostring_result += PrintMessageField("unchanged_names ", + unchanged_names, indent + 1, true); } + + std::string tostring_tail = PrintTail(indent); + return tostring_header + tostring_result + tostring_tail; } } // namespace firestore diff --git a/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h b/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h index 0669ae182c5..f7dc73102dc 100644 --- a/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h +++ b/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h @@ -21,6 +21,8 @@ #define PB_GOOGLE_FIRESTORE_V1_WRITE_NANOPB_H_INCLUDED #include +#include "google/firestore/v1/bloom_filter.nanopb.h" + #include "google/firestore/v1/common.nanopb.h" #include "google/firestore/v1/document.nanopb.h" @@ -108,6 +110,8 @@ typedef struct _google_firestore_v1_DocumentTransform_FieldTransform { typedef struct _google_firestore_v1_ExistenceFilter { int32_t target_id; int32_t count; + bool has_unchanged_names; + google_firestore_v1_BloomFilter unchanged_names; std::string ToString(int indent = 0) const; /* @@protoc_insertion_point(struct:google_firestore_v1_ExistenceFilter) */ @@ -152,7 +156,7 @@ typedef struct _google_firestore_v1_WriteResult { #define google_firestore_v1_DocumentChange_init_default {google_firestore_v1_Document_init_default, 0, NULL, 0, NULL} #define google_firestore_v1_DocumentDelete_init_default {NULL, false, google_protobuf_Timestamp_init_default, 0, NULL} #define google_firestore_v1_DocumentRemove_init_default {NULL, 0, NULL, google_protobuf_Timestamp_init_default} -#define google_firestore_v1_ExistenceFilter_init_default {0, 0} +#define google_firestore_v1_ExistenceFilter_init_default {0, 0, false, google_firestore_v1_BloomFilter_init_default} #define google_firestore_v1_Write_init_zero {0, {google_firestore_v1_Document_init_zero}, false, google_firestore_v1_DocumentMask_init_zero, false, google_firestore_v1_Precondition_init_zero, 0, NULL} #define google_firestore_v1_DocumentTransform_init_zero {NULL, 0, NULL} #define google_firestore_v1_DocumentTransform_FieldTransform_init_zero {NULL, 0, {_google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_MIN}} @@ -160,7 +164,7 @@ typedef struct _google_firestore_v1_WriteResult { #define google_firestore_v1_DocumentChange_init_zero {google_firestore_v1_Document_init_zero, 0, NULL, 0, NULL} #define google_firestore_v1_DocumentDelete_init_zero {NULL, false, google_protobuf_Timestamp_init_zero, 0, NULL} #define google_firestore_v1_DocumentRemove_init_zero {NULL, 0, NULL, google_protobuf_Timestamp_init_zero} -#define google_firestore_v1_ExistenceFilter_init_zero {0, 0} +#define google_firestore_v1_ExistenceFilter_init_zero {0, 0, false, google_firestore_v1_BloomFilter_init_zero} /* Field tags (for use in manual encoding/decoding) */ #define google_firestore_v1_DocumentTransform_document_tag 1 @@ -183,6 +187,7 @@ typedef struct _google_firestore_v1_WriteResult { #define google_firestore_v1_DocumentTransform_FieldTransform_field_path_tag 1 #define google_firestore_v1_ExistenceFilter_target_id_tag 1 #define google_firestore_v1_ExistenceFilter_count_tag 2 +#define google_firestore_v1_ExistenceFilter_unchanged_names_tag 3 #define google_firestore_v1_Write_update_tag 1 #define google_firestore_v1_Write_delete_tag 2 #define google_firestore_v1_Write_verify_tag 5 @@ -201,7 +206,7 @@ extern const pb_field_t google_firestore_v1_WriteResult_fields[3]; extern const pb_field_t google_firestore_v1_DocumentChange_fields[4]; extern const pb_field_t google_firestore_v1_DocumentDelete_fields[4]; extern const pb_field_t google_firestore_v1_DocumentRemove_fields[4]; -extern const pb_field_t google_firestore_v1_ExistenceFilter_fields[3]; +extern const pb_field_t google_firestore_v1_ExistenceFilter_fields[4]; /* Maximum encoded size of messages (where known) */ /* google_firestore_v1_Write_size depends on runtime parameters */ @@ -211,7 +216,7 @@ extern const pb_field_t google_firestore_v1_ExistenceFilter_fields[3]; /* google_firestore_v1_DocumentChange_size depends on runtime parameters */ /* google_firestore_v1_DocumentDelete_size depends on runtime parameters */ /* google_firestore_v1_DocumentRemove_size depends on runtime parameters */ -#define google_firestore_v1_ExistenceFilter_size 22 +#define google_firestore_v1_ExistenceFilter_size (28 + google_firestore_v1_BloomFilter_size) /* Message IDs (where set with "msgid" option) */ #ifdef PB_MSGID diff --git a/Firestore/Protos/protos/google/firestore/v1/bloom_filter.options b/Firestore/Protos/protos/google/firestore/v1/bloom_filter.options new file mode 100644 index 00000000000..652655cd9d5 --- /dev/null +++ b/Firestore/Protos/protos/google/firestore/v1/bloom_filter.options @@ -0,0 +1,21 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# In proto3 mode, Nanopb doesn't allow distinguishing between unset fields and +# fields having default values, even for non-primitive types. Using the +# workaround suggested in +# https://github.com/nanopb/nanopb/issues/255#issuecomment-291842903 + +# `bits` might not be set if the BloomFilter is empty. +google.firestore.v1.BloomFilter.bits proto3:false \ No newline at end of file diff --git a/Firestore/Protos/protos/google/firestore/v1/bloom_filter.proto b/Firestore/Protos/protos/google/firestore/v1/bloom_filter.proto new file mode 100644 index 00000000000..a417bee5ec1 --- /dev/null +++ b/Firestore/Protos/protos/google/firestore/v1/bloom_filter.proto @@ -0,0 +1,73 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.firestore.v1; + +option csharp_namespace = "Google.Cloud.Firestore.V1"; +option go_package = "google.golang.org/genproto/googleapis/firestore/v1;firestore"; +option java_multiple_files = true; +option java_outer_classname = "BloomFilterProto"; +option java_package = "com.google.firestore.v1"; +option objc_class_prefix = "GCFS"; +option php_namespace = "Google\\Cloud\\Firestore\\V1"; +option ruby_package = "Google::Cloud::Firestore::V1"; + +// A sequence of bits, encoded in a byte array. +// +// Each byte in the `bitmap` byte array stores 8 bits of the sequence. The only +// exception is the last byte, which may store 8 _or fewer_ bits. The `padding` +// defines the number of bits of the last byte to be ignored as "padding". The +// values of these "padding" bits are unspecified and must be ignored. +// +// To retrieve the first bit, bit 0, calculate: (bitmap[0] & 0x01) != 0. +// To retrieve the second bit, bit 1, calculate: (bitmap[0] & 0x02) != 0. +// To retrieve the third bit, bit 2, calculate: (bitmap[0] & 0x04) != 0. +// To retrieve the fourth bit, bit 3, calculate: (bitmap[0] & 0x08) != 0. +// To retrieve bit n, calculate: (bitmap[n / 8] & (0x01 << (n % 8))) != 0. +// +// The "size" of a `BitSequence` (the number of bits it contains) is calculated +// by this formula: (bitmap.length * 8) - padding. +message BitSequence { + // The bytes that encode the bit sequence. + // May have a length of zero. + bytes bitmap = 1; + + // The number of bits of the last byte in `bitmap` to ignore as "padding". + // If the length of `bitmap` is zero, then this value must be 0. + // Otherwise, this value must be between 0 and 7, inclusive. + int32 padding = 2; +} + +// A bloom filter (https://en.wikipedia.org/wiki/Bloom_filter). +// +// The bloom filter hashes the entries with MD5 and treats the resulting 128-bit +// hash as 2 distinct 64-bit hash values, interpreted as unsigned integers +// using 2's complement encoding. +// +// These two hash values, named h1 and h2, are then used to compute the +// `hash_count` hash values using the formula, starting at i=0: +// +// h(i) = h1 + (i * h2) +// +// These resulting values are then taken modulo the number of bits in the bloom +// filter to get the bits of the bloom filter to test for the given entry. +message BloomFilter { + // The bloom filter data. + BitSequence bits = 1; + + // The number of hashes used by the algorithm. + int32 hash_count = 2; +} diff --git a/Firestore/Protos/protos/google/firestore/v1/firestore.options b/Firestore/Protos/protos/google/firestore/v1/firestore.options index a577ead78df..14984149d50 100644 --- a/Firestore/Protos/protos/google/firestore/v1/firestore.options +++ b/Firestore/Protos/protos/google/firestore/v1/firestore.options @@ -21,3 +21,8 @@ # cause is not set if everything is OK, serializer needs to be able to tell # that is the case. google.firestore.v1.TargetChange.cause proto3:false + +# expected_count is set only if there is a resume token present in the +# Target. The backend may differentiate between an expected_count of 0 and +# expected_count being omitted. +google.firestore.v1.Target.expected_count proto3:false diff --git a/Firestore/Protos/protos/google/firestore/v1/firestore.proto b/Firestore/Protos/protos/google/firestore/v1/firestore.proto index 79944816bba..9dafa8858c3 100644 --- a/Firestore/Protos/protos/google/firestore/v1/firestore.proto +++ b/Firestore/Protos/protos/google/firestore/v1/firestore.proto @@ -25,6 +25,7 @@ import "google/firestore/v1/query.proto"; import "google/firestore/v1/write.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; import "google/rpc/status.proto"; option csharp_namespace = "Google.Cloud.Firestore.V1Beta1"; @@ -746,6 +747,14 @@ message Target { // If the target should be removed once it is current and consistent. bool once = 6; + + // The number of documents that last matched the query at the resume token or + // read time. + // + // This value is only relevant when a `resume_type` is provided. This value + // being present and greater than zero signals that the client wants + // `ExistenceFilter.unchanged_names` to be included in the response. + google.protobuf.Int32Value expected_count = 12; } // Targets being watched have changed. diff --git a/Firestore/Protos/protos/google/firestore/v1/write.options b/Firestore/Protos/protos/google/firestore/v1/write.options index 91805bd55a9..b7955f853c6 100644 --- a/Firestore/Protos/protos/google/firestore/v1/write.options +++ b/Firestore/Protos/protos/google/firestore/v1/write.options @@ -29,3 +29,7 @@ google.firestore.v1.Write.update_mask proto3:false # update_time should not be set for deletes. google.firestore.v1.WriteResult.update_time proto3:false + +# `unchanged_names` field might not be set if ListenRequest doesn't have +# `expected_count` field. +google.firestore.v1.ExistenceFilter.unchanged_names proto3:false \ No newline at end of file diff --git a/Firestore/Protos/protos/google/firestore/v1/write.proto b/Firestore/Protos/protos/google/firestore/v1/write.proto index 0d85b4953ad..9fe53f7bdd1 100644 --- a/Firestore/Protos/protos/google/firestore/v1/write.proto +++ b/Firestore/Protos/protos/google/firestore/v1/write.proto @@ -17,6 +17,7 @@ syntax = "proto3"; package google.firestore.v1; +import "google/firestore/v1/bloom_filter.proto"; import "google/firestore/v1/common.proto"; import "google/firestore/v1/document.proto"; import "google/protobuf/timestamp.proto"; @@ -260,4 +261,18 @@ message ExistenceFilter { // If different from the count of documents in the client that match, the // client must manually determine which documents no longer match the target. int32 count = 2; + + // A bloom filter that contains the UTF-8 byte encodings of the resource names + // of the documents that match [target_id][google.firestore.v1.ExistenceFilter.target_id], in the + // form `projects/{project_id}/databases/{database_id}/documents/{document_path}` + // that have NOT changed since the query results indicated by the resume token + // or timestamp given in `Target.resume_type`. + // + // This bloom filter may be omitted at the server's discretion, such as if it + // is deemed that the client will not make use of it or if it is too + // computationally expensive to calculate or transmit. Clients must gracefully + // handle this field being absent by falling back to the logic used before + // this field existed; that is, re-add the target without a resume token to + // figure out which documents in the client's cache are out of sync. + BloomFilter unchanged_names = 3; } diff --git a/Firestore/core/src/core/sync_engine.cc b/Firestore/core/src/core/sync_engine.cc index 63a9bc0d443..3a68dff69f8 100644 --- a/Firestore/core/src/core/sync_engine.cc +++ b/Firestore/core/src/core/sync_engine.cc @@ -113,7 +113,6 @@ TargetId SyncEngine::Listen(Query query) { TargetData target_data = local_store_->AllocateTarget(query.ToTarget()); TargetId target_id = target_data.target_id(); nanopb::ByteString resume_token = target_data.resume_token(); - remote_store_->Listen(std::move(target_data)); ViewSnapshot view_snapshot = InitializeViewAndComputeSnapshot( query, target_id, std::move(resume_token)); @@ -122,6 +121,7 @@ TargetId SyncEngine::Listen(Query query) { snapshots.push_back(std::move(view_snapshot)); sync_engine_callback_->OnViewSnapshots(std::move(snapshots)); + remote_store_->Listen(std::move(target_data)); return target_id; } @@ -345,7 +345,7 @@ void SyncEngine::HandleRejectedListen(TargetId target_id, Status error) { // copy-initialization" error. DocumentKeySet limbo_documents{limbo_key}; RemoteEvent::TargetChangeMap target_changes; - RemoteEvent::TargetSet target_mismatches; + RemoteEvent::TargetMismatchMap target_mismatches; DocumentUpdateMap document_updates{{limbo_key, doc}}; RemoteEvent event{SnapshotVersion::None(), std::move(target_changes), diff --git a/Firestore/core/src/local/local_serializer.cc b/Firestore/core/src/local/local_serializer.cc index 92d82380513..14d1a5502b9 100644 --- a/Firestore/core/src/local/local_serializer.cc +++ b/Firestore/core/src/local/local_serializer.cc @@ -289,7 +289,8 @@ TargetData LocalSerializer::DecodeTargetData( if (!reader->status().ok()) return TargetData(); return TargetData(std::move(target), target_id, sequence_number, QueryPurpose::Listen, version, - last_limbo_free_snapshot_version, std::move(resume_token)); + last_limbo_free_snapshot_version, std::move(resume_token), + /*expected_count=*/absl::nullopt); } Message LocalSerializer::EncodeMutationBatch( diff --git a/Firestore/core/src/local/target_data.cc b/Firestore/core/src/local/target_data.cc index e5759d84c85..4512e2f5d89 100644 --- a/Firestore/core/src/local/target_data.cc +++ b/Firestore/core/src/local/target_data.cc @@ -39,6 +39,8 @@ const char* ToString(QueryPurpose purpose) { return "Listen"; case QueryPurpose::ExistenceFilterMismatch: return "ExistenceFilterMismatch"; + case QueryPurpose::ExistenceFilterMismatchBloom: + return "ExistenceFilterMismatchBloom"; case QueryPurpose::LimboResolution: return "LimboResolution"; } @@ -60,7 +62,8 @@ TargetData::TargetData(Target target, QueryPurpose purpose, SnapshotVersion snapshot_version, SnapshotVersion last_limbo_free_snapshot_version, - ByteString resume_token) + ByteString resume_token, + absl::optional expected_count) : target_(std::move(target)), target_id_(target_id), sequence_number_(sequence_number), @@ -68,7 +71,8 @@ TargetData::TargetData(Target target, snapshot_version_(std::move(snapshot_version)), last_limbo_free_snapshot_version_( std::move(last_limbo_free_snapshot_version)), - resume_token_(std::move(resume_token)) { + resume_token_(std::move(resume_token)), + expected_count_(std::move(expected_count)) { } TargetData::TargetData(Target target, @@ -81,35 +85,46 @@ TargetData::TargetData(Target target, purpose, SnapshotVersion::None(), SnapshotVersion::None(), - ByteString()) { + ByteString(), + /*expected_count=*/absl::nullopt) { } TargetData TargetData::Invalid() { return TargetData({}, /*target_id=*/-1, /*sequence_number=*/-1, QueryPurpose::Listen, SnapshotVersion(SnapshotVersion::None()), - SnapshotVersion(SnapshotVersion::None()), {}); + SnapshotVersion(SnapshotVersion::None()), {}, + /*expected_count=*/absl::nullopt); } TargetData TargetData::WithSequenceNumber( ListenSequenceNumber sequence_number) const { return TargetData(target_, target_id_, sequence_number, purpose_, snapshot_version_, last_limbo_free_snapshot_version_, - resume_token_); + resume_token_, expected_count_); } TargetData TargetData::WithResumeToken(ByteString resume_token, SnapshotVersion snapshot_version) const { return TargetData(target_, target_id_, sequence_number_, purpose_, std::move(snapshot_version), - last_limbo_free_snapshot_version_, std::move(resume_token)); + last_limbo_free_snapshot_version_, std::move(resume_token), + /*expected_count=*/absl::nullopt); +} + +TargetData TargetData::WithExpectedCount( + absl::optional expected_count) const { + return TargetData(target_, target_id_, sequence_number_, purpose_, + snapshot_version_, last_limbo_free_snapshot_version_, + resume_token_, std::move(expected_count)); } TargetData TargetData::WithLastLimboFreeSnapshotVersion( SnapshotVersion last_limbo_free_snapshot_version) const { return TargetData(target_, target_id_, sequence_number_, purpose_, snapshot_version_, - std::move(last_limbo_free_snapshot_version), resume_token_); + std::move(last_limbo_free_snapshot_version), resume_token_, + expected_count_); } bool operator==(const TargetData& lhs, const TargetData& rhs) { @@ -117,12 +132,13 @@ bool operator==(const TargetData& lhs, const TargetData& rhs) { lhs.sequence_number() == rhs.sequence_number() && lhs.purpose() == rhs.purpose() && lhs.snapshot_version() == rhs.snapshot_version() && - lhs.resume_token() == rhs.resume_token(); + lhs.resume_token() == rhs.resume_token() && + lhs.expected_count() == rhs.expected_count(); } size_t TargetData::Hash() const { return util::Hash(target_, target_id_, sequence_number_, purpose_, - snapshot_version_, resume_token_); + snapshot_version_, resume_token_, expected_count_); } std::string TargetData::ToString() const { @@ -138,7 +154,11 @@ std::ostream& operator<<(std::ostream& os, const TargetData& value) { << ", version=" << value.snapshot_version_ << ", last_limbo_free_snapshot_version=" << value.last_limbo_free_snapshot_version_ - << ", resume_token=" << value.resume_token_ << ")"; + << ", resume_token=" << value.resume_token_ << ", expected_count=" + << (value.expected_count_.has_value() + ? std::to_string(value.expected_count_.value()) + : "null") + << ")"; } } // namespace local diff --git a/Firestore/core/src/local/target_data.h b/Firestore/core/src/local/target_data.h index 5206145b052..5a6a53370e0 100644 --- a/Firestore/core/src/local/target_data.h +++ b/Firestore/core/src/local/target_data.h @@ -41,6 +41,12 @@ enum class QueryPurpose { */ ExistenceFilterMismatch, + /** + * The query was used refill a query if there is an existence filter mismatch + * and the bloom filter application returned a false positive result. + */ + ExistenceFilterMismatchBloom, + /** The query was used to resolve a limbo document. */ LimboResolution, }; @@ -67,6 +73,9 @@ class TargetData { * target to be resumed after disconnecting without retransmitting all the * data that matches the query. The resume token essentially identifies a * point in time from which the server should resume sending results. + * @param expected_count The number of documents that last matched the query + * at the resume token or read time. Documents are counted only when making a + * listen request with resume token or read time, otherwise, keep it null. */ TargetData(core::Target target, model::TargetId target_id, @@ -74,7 +83,8 @@ class TargetData { QueryPurpose purpose, model::SnapshotVersion snapshot_version, model::SnapshotVersion last_limbo_free_snapshot_version, - nanopb::ByteString resume_token); + nanopb::ByteString resume_token, + absl::optional expected_count); /** * Convenience constructor for use when creating a TargetData for the first @@ -142,6 +152,15 @@ class TargetData { return resume_token_; } + /** + * The number of documents that last matched the query at the resume token or + * read time. Documents are counted only when making a listen request with + * resume token or read time, otherwise, keep it null. + */ + const absl::optional& expected_count() const { + return expected_count_; + } + /** Creates a new target data instance with an updated sequence number. */ TargetData WithSequenceNumber( model::ListenSequenceNumber sequence_number) const; @@ -153,6 +172,9 @@ class TargetData { TargetData WithResumeToken(nanopb::ByteString resume_token, model::SnapshotVersion snapshot_version) const; + /** Creates a new target data instance with an updated expected count. */ + TargetData WithExpectedCount(absl::optional expected_count) const; + /** * Creates a new target data instance with an updated last limbo free snapshot * version. @@ -176,6 +198,7 @@ class TargetData { model::SnapshotVersion snapshot_version_; model::SnapshotVersion last_limbo_free_snapshot_version_; nanopb::ByteString resume_token_; + absl::optional expected_count_; }; inline bool operator!=(const TargetData& lhs, const TargetData& rhs) { diff --git a/Firestore/core/src/nanopb/fields_array.h b/Firestore/core/src/nanopb/fields_array.h index 1a43b76133b..3b89b2ecd06 100644 --- a/Firestore/core/src/nanopb/fields_array.h +++ b/Firestore/core/src/nanopb/fields_array.h @@ -227,6 +227,21 @@ inline const pb_field_t* FieldsArray< return google_firestore_v1_StructuredAggregationQuery_Aggregation_Count_fields; } +template <> +inline const pb_field_t* FieldsArray() { + return google_firestore_v1_ExistenceFilter_fields; +} + +template <> +inline const pb_field_t* FieldsArray() { + return google_firestore_v1_BloomFilter_fields; +} + +template <> +inline const pb_field_t* FieldsArray() { + return google_firestore_v1_BitSequence_fields; +} + } // namespace nanopb } // namespace firestore } // namespace firebase diff --git a/Firestore/core/src/remote/bloom_filter.cc b/Firestore/core/src/remote/bloom_filter.cc new file mode 100644 index 00000000000..ddf84b866e9 --- /dev/null +++ b/Firestore/core/src/remote/bloom_filter.cc @@ -0,0 +1,150 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/remote/bloom_filter.h" + +#include + +#include "Firestore/core/src/util/hard_assert.h" +#include "Firestore/core/src/util/md5.h" +#include "Firestore/core/src/util/statusor.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using nanopb::ByteString; +using util::Status; +using util::StatusOr; + +namespace { +bool HasSameBits(const BloomFilter& lhs, const BloomFilter& rhs) { + if (lhs.bit_count() != rhs.bit_count()) { + return false; + } + if (lhs.bit_count() == 0) { + return true; + } + + const auto byte_count = static_cast(lhs.bitmap().size()); + const uint8_t* bitmap1 = lhs.bitmap().data(); + const uint8_t* bitmap2 = rhs.bitmap().data(); + + // Compare all bytes from the bitmap, except for the last byte. + for (int32_t i = 0; i < byte_count - 1; ++i) { + if (bitmap1[i] != bitmap2[i]) { + return false; + } + } + + // Compare the last byte, ignoring the padding. + const int32_t padding = (byte_count * 8) - lhs.bit_count(); + const uint8_t last_byte1 = bitmap1[byte_count - 1] << padding; + const uint8_t last_byte2 = bitmap2[byte_count - 1] << padding; + + return (last_byte1 == last_byte2); +} +} // namespace + +BloomFilter::Hash BloomFilter::Md5HashDigest(absl::string_view key) const { + std::array md5_digest{util::CalculateMd5Digest(key)}; + + // TODO(Mila): Handle big endian processor b/271174523. + uint64_t* hash128 = reinterpret_cast(md5_digest.data()); + static_assert(sizeof(uint64_t[2]) == sizeof(uint8_t[16]), ""); + + return Hash{hash128[0], hash128[1]}; +} + +int32_t BloomFilter::GetBitIndex(const Hash& hash, int32_t hash_index) const { + HARD_ASSERT(hash_index >= 0); + uint64_t hash_index_uint64 = static_cast(hash_index); + uint64_t bit_count_uint64 = static_cast(bit_count_); + + uint64_t combined_hash = hash.h1 + (hash_index_uint64 * hash.h2); + uint64_t bit_index = combined_hash % bit_count_uint64; + + HARD_ASSERT(bit_index <= INT32_MAX); + return bit_index; +} + +bool BloomFilter::IsBitSet(int32_t index) const { + uint8_t byte_at_index = bitmap_.data()[index / 8]; + int32_t offset = index % 8; + return (byte_at_index & (static_cast(0x01) << offset)) != 0; +} + +BloomFilter::BloomFilter(ByteString bitmap, int32_t padding, int32_t hash_count) + : bit_count_(static_cast(bitmap.size()) * 8 - padding), + hash_count_(hash_count), + bitmap_(std::move(bitmap)) { + HARD_ASSERT(padding >= 0 && padding < 8); + HARD_ASSERT(hash_count_ >= 0); + // Only empty bloom filter can have 0 hash count. + HARD_ASSERT(bitmap_.size() == 0 || hash_count_ != 0); + // Empty bloom filter should have 0 padding. + HARD_ASSERT(bitmap_.size() != 0 || padding == 0); + HARD_ASSERT(bit_count_ >= 0); +} + +StatusOr BloomFilter::Create(ByteString bitmap, + int32_t padding, + int32_t hash_count) { + if (padding < 0 || padding >= 8) { + return Status(firestore::Error::kErrorInvalidArgument, + "Invalid padding: " + std::to_string(padding)); + } + if (hash_count < 0) { + return Status(firestore::Error::kErrorInvalidArgument, + "Invalid hash count: " + std::to_string(hash_count)); + } + if (bitmap.size() > 0 && hash_count == 0) { + // Only empty bloom filter can have 0 hash count. + return Status(firestore::Error::kErrorInvalidArgument, + "Invalid hash count: " + std::to_string(hash_count)); + } + if (bitmap.size() == 0 && padding != 0) { + // Empty bloom filter should have 0 padding. + return Status(firestore::Error::kErrorInvalidArgument, + "Expected padding of 0 when bitmap length is 0, but got " + + std::to_string(padding)); + } + + return BloomFilter(std::move(bitmap), padding, hash_count); +} + +bool BloomFilter::MightContain(absl::string_view value) const { + // Empty bitmap should return false on membership check. + if (bit_count_ == 0) return false; + Hash hash = Md5HashDigest(value); + // The `hash_count_` and `bit_count_` fields are guaranteed to be + // non-negative when the `BloomFilter` object is constructed. + for (int32_t i = 0; i < hash_count_; ++i) { + int32_t index = GetBitIndex(hash, i); + if (!IsBitSet(index)) { + return false; + } + } + return true; +} + +bool operator==(const BloomFilter& lhs, const BloomFilter& rhs) { + return lhs.hash_count() == rhs.hash_count() && HasSameBits(lhs, rhs); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/remote/bloom_filter.h b/Firestore/core/src/remote/bloom_filter.h new file mode 100644 index 00000000000..ce4e6a58296 --- /dev/null +++ b/Firestore/core/src/remote/bloom_filter.h @@ -0,0 +1,124 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_REMOTE_BLOOM_FILTER_H_ +#define FIRESTORE_CORE_SRC_REMOTE_BLOOM_FILTER_H_ + +#include +#include "Firestore/core/src/nanopb/byte_string.h" +#include "Firestore/core/src/util/statusor.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace remote { + +class BloomFilter final { + public: + BloomFilter(nanopb::ByteString bitmap, int32_t padding, int32_t hash_count); + + // Copyable & movable. + BloomFilter(const BloomFilter&) = default; + BloomFilter(BloomFilter&&) = default; + BloomFilter& operator=(const BloomFilter&) = default; + BloomFilter& operator=(BloomFilter&&) = default; + + /** + * Creates a BloomFilter object or returns a status. + * + * @return a new BloomFilter if the inputs are valid, otherwise returns a not + * `ok()` status. + */ + static util::StatusOr Create(nanopb::ByteString bitmap, + int32_t padding, + int32_t hash_count); + + /** + * Check whether the given string is a possible member of the bloom filter. It + * might return false positive result, ie, the given string is not a member of + * the bloom filter, but the method returned true. + * + * @param value the string to be tested for membership. + * @return true if the given string might be contained in the bloom filter, or + * false if the given string is definitely not contained in the bloom filter. + */ + bool MightContain(absl::string_view value) const; + + /** + * The number of bits in the bloom filter. Guaranteed to be non-negative, and + * less than the max number of bits the bitmap can represent, i.e., + * bitmap().size() * 8. + */ + int32_t bit_count() const { + return bit_count_; + } + + /** + * The number of hash functions used to construct the filter. Guaranteed to + * be non-negative. + */ + int32_t hash_count() const { + return hash_count_; + } + + /** Bloom filter's bitmap. */ + const nanopb::ByteString& bitmap() const { + return bitmap_; + } + + private: + /** + * When checking membership of a key in bitmap, the first step is to generate + * a 128-bit hash, and treat it as 2 distinct 64-bit hash values, named `h1` + * and `h2`, interpreted as unsigned integers using 2's complement encoding. + */ + struct Hash { + uint64_t h1; + uint64_t h2; + }; + + /** + * Calculate the MD5 digest of the given string, and return a Hash object. + */ + Hash Md5HashDigest(absl::string_view key) const; + + /** + * Calculate the ith hash value based on the hashed 64 bit unsigned integers, + * and calculate its corresponding bit index in the bitmap to be checked. + */ + int32_t GetBitIndex(const Hash& hash, int32_t hash_index) const; + + /** Return whether the bit at the given index in the bitmap is set to 1. */ + bool IsBitSet(int32_t index) const; + + int32_t bit_count_ = 0; + + int32_t hash_count_ = 0; + + nanopb::ByteString bitmap_; +}; + +bool operator==(const BloomFilter& lhs, const BloomFilter& rhs); + +inline bool operator!=(const BloomFilter& lhs, const BloomFilter& rhs) { + return !(lhs == rhs); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_REMOTE_BLOOM_FILTER_H_ diff --git a/Firestore/core/src/remote/datastore.cc b/Firestore/core/src/remote/datastore.cc index 6889a15fedd..47a8fb716b5 100644 --- a/Firestore/core/src/remote/datastore.cc +++ b/Firestore/core/src/remote/datastore.cc @@ -103,6 +103,7 @@ Datastore::Datastore( auth_credentials_{std::move(auth_credentials)}, rpc_executor_{CreateExecutor()}, connectivity_monitor_{connectivity_monitor}, + database_info_{database_info}, grpc_connection_{database_info, worker_queue, &grpc_queue_, connectivity_monitor_, firebase_metadata_provider}, datastore_serializer_{database_info} { diff --git a/Firestore/core/src/remote/datastore.h b/Firestore/core/src/remote/datastore.h index d2cd7a8e88d..7de64663d11 100644 --- a/Firestore/core/src/remote/datastore.h +++ b/Firestore/core/src/remote/datastore.h @@ -141,6 +141,10 @@ class Datastore : public std::enable_shared_from_this { static std::string GetAllowlistedHeadersAsString( const GrpcCall::Metadata& headers); + const core::DatabaseInfo& database_info() const { + return database_info_; + } + Datastore(const Datastore& other) = delete; Datastore(Datastore&& other) = delete; Datastore& operator=(const Datastore& other) = delete; @@ -213,6 +217,7 @@ class Datastore : public std::enable_shared_from_this { std::unique_ptr rpc_executor_; grpc::CompletionQueue grpc_queue_; ConnectivityMonitor* connectivity_monitor_ = nullptr; + core::DatabaseInfo database_info_; GrpcConnection grpc_connection_; std::vector> active_calls_; diff --git a/Firestore/core/src/remote/existence_filter.h b/Firestore/core/src/remote/existence_filter.h index 3f4019c8987..b7b1ada9742 100644 --- a/Firestore/core/src/remote/existence_filter.h +++ b/Firestore/core/src/remote/existence_filter.h @@ -17,26 +17,53 @@ #ifndef FIRESTORE_CORE_SRC_REMOTE_EXISTENCE_FILTER_H_ #define FIRESTORE_CORE_SRC_REMOTE_EXISTENCE_FILTER_H_ +#include + +#include "Firestore/core/src/nanopb/byte_string.h" +#include "Firestore/core/src/remote/bloom_filter.h" + namespace firebase { namespace firestore { namespace remote { +struct BloomFilterParameters { + nanopb::ByteString bitmap; + int32_t padding; + int32_t hash_count; +}; + +inline bool operator==(const BloomFilterParameters& lhs, + const BloomFilterParameters& rhs) { + return lhs.padding == rhs.padding && lhs.hash_count == rhs.hash_count && + lhs.bitmap == rhs.bitmap; +} + class ExistenceFilter { public: ExistenceFilter() = default; - explicit ExistenceFilter(int count) : count_{count} { + + ExistenceFilter(int count, + absl::optional bloom_filter_parameters) + : count_{count}, + bloom_filter_parameters_{std::move(bloom_filter_parameters)} { } int count() const { return count_; } + const absl::optional& bloom_filter_parameters() const { + return bloom_filter_parameters_; + } + private: int count_ = 0; + absl::optional bloom_filter_parameters_; }; inline bool operator==(const ExistenceFilter& lhs, const ExistenceFilter& rhs) { - return lhs.count() == rhs.count(); + return lhs.count() == rhs.count() && + lhs.bloom_filter_parameters() == rhs.bloom_filter_parameters(); } } // namespace remote diff --git a/Firestore/core/src/remote/remote_event.cc b/Firestore/core/src/remote/remote_event.cc index 0c08d983dbf..df9ee5848cb 100644 --- a/Firestore/core/src/remote/remote_event.cc +++ b/Firestore/core/src/remote/remote_event.cc @@ -16,9 +16,11 @@ #include "Firestore/core/src/remote/remote_event.h" +#include #include #include "Firestore/core/src/local/target_data.h" +#include "Firestore/core/src/util/log.h" #include "Firestore/core/src/util/testing_hooks.h" namespace firebase { @@ -29,6 +31,7 @@ using core::DocumentViewChange; using core::Target; using local::QueryPurpose; using local::TargetData; +using model::DatabaseId; using model::DocumentKey; using model::DocumentKeySet; using model::MutableDocument; @@ -209,6 +212,29 @@ std::vector WatchChangeAggregator::GetTargetIds( return result; } +namespace { + +TestingHooks::ExistenceFilterMismatchInfo +create_existence_filter_mismatch_info_for_testing_hooks( + BloomFilterApplicationStatus status, + int local_cache_count, + const ExistenceFilterWatchChange& existence_filter) { + absl::optional bloom_filter; + if (existence_filter.filter().bloom_filter_parameters().has_value()) { + const BloomFilterParameters& bloom_filter_parameters = + existence_filter.filter().bloom_filter_parameters().value(); + bloom_filter = {status == BloomFilterApplicationStatus::kSuccess, + bloom_filter_parameters.hash_count, + static_cast(bloom_filter_parameters.bitmap.size()), + bloom_filter_parameters.padding}; + } + + return {local_cache_count, existence_filter.filter().count(), + std::move(bloom_filter)}; +} + +} // namespace + void WatchChangeAggregator::HandleExistenceFilter( const ExistenceFilterWatchChange& existence_filter) { TargetId target_id = existence_filter.target_id(); @@ -237,17 +263,82 @@ void WatchChangeAggregator::HandleExistenceFilter( } else { int current_size = GetCurrentDocumentCountForTarget(target_id); if (current_size != expected_count) { - // Existence filter mismatch: We reset the mapping and raise a new - // snapshot with `isFromCache:true`. - ResetTarget(target_id); - pending_target_resets_.insert(target_id); + // Apply bloom filter to identify and mark removed documents. + BloomFilterApplicationStatus status = + ApplyBloomFilter(existence_filter, current_size); + if (status != BloomFilterApplicationStatus::kSuccess) { + // If bloom filter application fails, we reset the mapping and + // trigger re-run of the query. + ResetTarget(target_id); + const QueryPurpose purpose = + status == BloomFilterApplicationStatus::kFalsePositive + ? QueryPurpose::ExistenceFilterMismatchBloom + : QueryPurpose::ExistenceFilterMismatch; + pending_target_resets_.insert({target_id, purpose}); + } + TestingHooks::GetInstance().NotifyOnExistenceFilterMismatch( - {current_size, expected_count}); + create_existence_filter_mismatch_info_for_testing_hooks( + status, current_size, existence_filter)); } } } } +BloomFilterApplicationStatus WatchChangeAggregator::ApplyBloomFilter( + const ExistenceFilterWatchChange& existence_filter, int current_count) { + const absl::optional& bloom_filter_parameters = + existence_filter.filter().bloom_filter_parameters(); + if (!bloom_filter_parameters.has_value()) { + return BloomFilterApplicationStatus::kSkipped; + } + + util::StatusOr maybe_bloom_filter = + BloomFilter::Create(bloom_filter_parameters.value().bitmap, + bloom_filter_parameters.value().padding, + bloom_filter_parameters.value().hash_count); + if (!maybe_bloom_filter.ok()) { + LOG_WARN("Creating BloomFilter failed: %s", + maybe_bloom_filter.status().error_message()); + return BloomFilterApplicationStatus::kSkipped; + } + + BloomFilter bloom_filter = std::move(maybe_bloom_filter).ValueOrDie(); + + if (bloom_filter.bit_count() == 0) { + return BloomFilterApplicationStatus::kSkipped; + } + + int removed_document_count = + FilterRemovedDocuments(bloom_filter, existence_filter.target_id()); + + int expected_count = existence_filter.filter().count(); + if (expected_count != (current_count - removed_document_count)) { + return BloomFilterApplicationStatus::kFalsePositive; + } + return BloomFilterApplicationStatus::kSuccess; +} + +int WatchChangeAggregator::FilterRemovedDocuments( + const BloomFilter& bloom_filter, int target_id) { + const DocumentKeySet existing_keys = + target_metadata_provider_->GetRemoteKeysForTarget(target_id); + int removalCount = 0; + for (const DocumentKey& key : existing_keys) { + const DatabaseId& database_id = target_metadata_provider_->GetDatabaseId(); + std::string document_path = util::StringFormat( + "projects/%s/databases/%s/documents/%s", database_id.project_id(), + database_id.database_id(), key.ToString()); + + if (!bloom_filter.MightContain(document_path)) { + RemoveDocumentFromTarget(target_id, key, + /*updatedDocument=*/absl::nullopt); + removalCount++; + } + } + return removalCount; +} + RemoteEvent WatchChangeAggregator::CreateRemoteEvent( const SnapshotVersion& snapshot_version) { std::unordered_map target_changes; diff --git a/Firestore/core/src/remote/remote_event.h b/Firestore/core/src/remote/remote_event.h index bdec91a1703..0d5331a0d7c 100644 --- a/Firestore/core/src/remote/remote_event.h +++ b/Firestore/core/src/remote/remote_event.h @@ -41,6 +41,8 @@ class TargetData; namespace remote { +enum class BloomFilterApplicationStatus { kSuccess, kSkipped, kFalsePositive }; + /** * Interface implemented by `RemoteStore` to expose target metadata to the * `WatchChangeAggregator`. @@ -62,6 +64,9 @@ class TargetMetadataProvider { */ virtual absl::optional GetTargetDataForTarget( model::TargetId target_id) const = 0; + + /** Returns the database ID of the Firestore instance. */ + virtual const model::DatabaseId& GetDatabaseId() const = 0; }; /** @@ -243,11 +248,12 @@ class TargetState { class RemoteEvent { public: using TargetChangeMap = std::unordered_map; - using TargetSet = std::unordered_set; + using TargetMismatchMap = + std::unordered_map; RemoteEvent(model::SnapshotVersion snapshot_version, TargetChangeMap target_changes, - TargetSet target_mismatches, + TargetMismatchMap target_mismatches, model::DocumentUpdateMap document_updates, model::DocumentKeySet limbo_document_changes) : snapshot_version_{snapshot_version}, @@ -268,10 +274,11 @@ class RemoteEvent { } /** - * A set of targets that is known to be inconsistent. Listens for these - * targets should be re-established without resume tokens. + * A map of targets that is known to be inconsistent, and the purpose for + * re-listening. Listens for these targets should be re-established without + * resume tokens. */ - const TargetSet& target_mismatches() const { + const TargetMismatchMap& target_mismatches() const { return target_mismatches_; } @@ -293,7 +300,7 @@ class RemoteEvent { private: model::SnapshotVersion snapshot_version_; TargetChangeMap target_changes_; - TargetSet target_mismatches_; + TargetMismatchMap target_mismatches_; model::DocumentUpdateMap document_updates_; model::DocumentKeySet limbo_document_changes_; }; @@ -410,6 +417,19 @@ class WatchChangeAggregator { bool TargetContainsDocument(model::TargetId target_id, const model::DocumentKey& key); + /** + * Apply bloom filter to remove the deleted documents, and return the + * application status. + */ + BloomFilterApplicationStatus ApplyBloomFilter( + const ExistenceFilterWatchChange& existence_filter, int current_count); + + /** + * Filter out removed documents based on bloom filter membership result and + * return number of documents removed. + */ + int FilterRemovedDocuments(const BloomFilter& bloom_filter, int target_id); + /** The internal state of all tracked targets. */ std::unordered_map target_states_; @@ -423,11 +443,11 @@ class WatchChangeAggregator { pending_document_target_mappings_; /** - * A list of targets with existence filter mismatches. These targets are known + * A map of targets with existence filter mismatches. These targets are known * to be inconsistent and their listens needs to be re-established by * `RemoteStore`. */ - RemoteEvent::TargetSet pending_target_resets_; + RemoteEvent::TargetMismatchMap pending_target_resets_; TargetMetadataProvider* target_metadata_provider_ = nullptr; }; diff --git a/Firestore/core/src/remote/remote_store.cc b/Firestore/core/src/remote/remote_store.cc index 54e5fea5899..d166e2302ce 100644 --- a/Firestore/core/src/remote/remote_store.cc +++ b/Firestore/core/src/remote/remote_store.cc @@ -194,7 +194,16 @@ void RemoteStore::SendWatchRequest(const TargetData& target_data) { // We need to increment the expected number of pending responses we're due // from watch so we wait for the ack to process any messages from this target. watch_change_aggregator_->RecordPendingTargetRequest(target_data.target_id()); - watch_stream_->WatchQuery(target_data); + + // Add expectedCount to target if there is a resume token. + if (!target_data.resume_token().empty()) { + int32_t expectedCount = + GetRemoteKeysForTarget(target_data.target_id()).size(); + TargetData new_target_data = target_data.WithExpectedCount(expectedCount); + watch_stream_->WatchQuery(new_target_data); + } else { + watch_stream_->WatchQuery(target_data); + } } void RemoteStore::SendUnwatchRequest(TargetId target_id) { @@ -319,7 +328,10 @@ void RemoteStore::RaiseWatchSnapshot(const SnapshotVersion& snapshot_version) { // Re-establish listens for the targets that have been invalidated by // existence filter mismatches. - for (TargetId target_id : remote_event.target_mismatches()) { + for (const auto& entry : remote_event.target_mismatches()) { + const TargetId& target_id = entry.first; + const QueryPurpose& purpose = entry.second; + auto found = listen_targets_.find(target_id); if (found == listen_targets_.end()) { // A watched target might have been removed already. @@ -343,8 +355,7 @@ void RemoteStore::RaiseWatchSnapshot(const SnapshotVersion& snapshot_version) { // that we flag the first re-listen this way without impacting future // listens of this target (that might happen e.g. on reconnect). TargetData request_target_data(target_data.target(), target_id, - target_data.sequence_number(), - QueryPurpose::ExistenceFilterMismatch); + target_data.sequence_number(), purpose); SendWatchRequest(request_target_data); } @@ -561,6 +572,10 @@ absl::optional RemoteStore::GetTargetDataForTarget( : absl::optional{}; } +const model::DatabaseId& RemoteStore::GetDatabaseId() const { + return datastore_->database_info().database_id(); +} + void RemoteStore::RestartNetwork() { is_network_enabled_ = false; DisableNetworkInternal(); diff --git a/Firestore/core/src/remote/remote_store.h b/Firestore/core/src/remote/remote_store.h index 96538be23fb..ae6bd7023bc 100644 --- a/Firestore/core/src/remote/remote_store.h +++ b/Firestore/core/src/remote/remote_store.h @@ -197,6 +197,7 @@ class RemoteStore : public TargetMetadataProvider, model::TargetId target_id) const override; absl::optional GetTargetDataForTarget( model::TargetId target_id) const override; + const model::DatabaseId& GetDatabaseId() const override; void RunAggregateQuery(const core::Query& query, const std::vector& aggregates, diff --git a/Firestore/core/src/remote/serializer.cc b/Firestore/core/src/remote/serializer.cc index c68c67c8f40..f301a65e37f 100644 --- a/Firestore/core/src/remote/serializer.cc +++ b/Firestore/core/src/remote/serializer.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include "Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h" #include "Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h" @@ -638,11 +639,21 @@ google_firestore_v1_Target Serializer::EncodeTarget( result.which_resume_type = google_firestore_v1_Target_resume_token_tag; result.resume_type.resume_token = nanopb::CopyBytesArray(target_data.resume_token().get()); + + if (target_data.expected_count().has_value()) { + result.has_expected_count = true; + result.expected_count.value = target_data.expected_count().value(); + } } else if (target_data.snapshot_version().CompareTo( SnapshotVersion::None()) == ComparisonResult::Descending) { result.which_resume_type = google_firestore_v1_Target_read_time_tag; result.resume_type.read_time = EncodeVersion(target_data.snapshot_version()); + + if (target_data.expected_count().has_value()) { + result.has_expected_count = true; + result.expected_count.value = target_data.expected_count().value(); + } } return result; @@ -1277,6 +1288,8 @@ std::string Serializer::EncodeLabel(QueryPurpose purpose) const { return ""; case QueryPurpose::ExistenceFilterMismatch: return "existence-filter-mismatch"; + case QueryPurpose::ExistenceFilterMismatchBloom: + return "existence-filter-mismatch-bloom"; case QueryPurpose::LimboResolution: return "limbo-document"; } @@ -1431,9 +1444,28 @@ std::unique_ptr Serializer::DecodeDocumentRemove( std::unique_ptr Serializer::DecodeExistenceFilterWatchChange( ReadContext*, const google_firestore_v1_ExistenceFilter& filter) const { - ExistenceFilter existence_filter{filter.count}; - return absl::make_unique(existence_filter, - filter.target_id); + return absl::make_unique( + DecodeExistenceFilter(filter), filter.target_id); +} + +ExistenceFilter Serializer::DecodeExistenceFilter( + const google_firestore_v1_ExistenceFilter& filter) const { + if (!filter.has_unchanged_names) { + return {filter.count, absl::nullopt}; + } + + int32_t hash_count = filter.unchanged_names.hash_count; + int32_t padding = 0; + ByteString bitmap; + if (filter.unchanged_names.has_bits) { + padding = filter.unchanged_names.bits.padding; + // TODO(b/274668697) Steal the bytes using ByteString::Take() instead of + // copying them. To do this, the `filter` argument will need to be + // non-const, which will affect the caller(s), and their caller(s), etc. + bitmap = ByteString(filter.unchanged_names.bits.bitmap); + } + return {filter.count, + BloomFilterParameters{std::move(bitmap), padding, hash_count}}; } bool Serializer::IsLocalResourceName(const ResourcePath& path) const { diff --git a/Firestore/core/src/remote/serializer.h b/Firestore/core/src/remote/serializer.h index ab9370b441a..c42c6c3ac1b 100644 --- a/Firestore/core/src/remote/serializer.h +++ b/Firestore/core/src/remote/serializer.h @@ -341,6 +341,9 @@ class Serializer { util::ReadContext* context, const google_firestore_v1_ExistenceFilter& filter) const; + ExistenceFilter DecodeExistenceFilter( + const google_firestore_v1_ExistenceFilter& filter) const; + model::DatabaseId database_id_; // TODO(varconst): Android caches the result of calling `EncodeDatabaseName` // as well, consider implementing that. diff --git a/Firestore/core/src/remote/watch_change.h b/Firestore/core/src/remote/watch_change.h index ba2951c66c2..20e6121a7b5 100644 --- a/Firestore/core/src/remote/watch_change.h +++ b/Firestore/core/src/remote/watch_change.h @@ -115,7 +115,7 @@ bool operator==(const DocumentWatchChange& lhs, const DocumentWatchChange& rhs); class ExistenceFilterWatchChange : public WatchChange { public: ExistenceFilterWatchChange(ExistenceFilter filter, model::TargetId target_id) - : filter_{filter}, target_id_{target_id} { + : filter_{std::move(filter)}, target_id_{target_id} { } Type type() const override { diff --git a/Firestore/core/src/util/md5.cc b/Firestore/core/src/util/md5.cc new file mode 100644 index 00000000000..4e3a2c400bd --- /dev/null +++ b/Firestore/core/src/util/md5.cc @@ -0,0 +1,306 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/util/md5.h" + +#include + +namespace firebase { +namespace firestore { +namespace util { + +// The contents of this anonymous namespace were copied, and slightly adapted, +// from +// https://source.chromium.org/chromium/chromium/src/+/main:base/hash/md5_nacl.cc;drc=e4622aaeccea84652488d1822c28c78b7115684f +namespace { + +// Copyright 2011 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The original file was copied from sqlite, and was in the public domain. + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +// The output of an MD5 operation. +struct MD5Digest { + uint8_t a[16]; +}; + +// Used for storing intermediate data during an MD5 computation. Callers +// should not access the data. +typedef char MD5Context[88]; + +struct Context { + uint32_t buf[4]; + uint32_t bits[2]; + uint8_t in[64]; +}; + +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(uint8_t* buf, unsigned longs) { + do { + uint32_t temp = + static_cast(static_cast(buf[3]) << 8 | buf[2]) + << 16 | + (static_cast(buf[1]) << 8 | buf[0]); + *reinterpret_cast(buf) = temp; + buf += 4; + } while (--longs); +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32_t buf[4], const uint32_t in[16]) { + uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(MD5Context* context) { + struct Context* ctx = reinterpret_cast(context); + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(MD5Context* context, absl::string_view data) { + struct Context* ctx = reinterpret_cast(context); + const uint8_t* buf = reinterpret_cast(data.data()); + size_t len = data.size(); + + /* Update bitcount */ + + uint32_t t = ctx->bits[0]; + if ((ctx->bits[0] = t + (static_cast(len) << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += static_cast(len >> 29); + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + uint8_t* p = static_cast(ctx->in + t); + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, reinterpret_cast(ctx->in)); + buf += t; + len -= t; + } + + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, reinterpret_cast(ctx->in)); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(MD5Digest* digest, MD5Context* context) { + struct Context* ctx = reinterpret_cast(context); + unsigned count; + uint8_t* p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, reinterpret_cast(ctx->in)); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + memcpy(&ctx->in[14 * sizeof(ctx->bits[0])], &ctx->bits[0], + sizeof(ctx->bits[0])); + memcpy(&ctx->in[15 * sizeof(ctx->bits[1])], &ctx->bits[1], + sizeof(ctx->bits[1])); + + MD5Transform(ctx->buf, reinterpret_cast(ctx->in)); + byteReverse(reinterpret_cast(ctx->buf), 4); + memcpy(digest->a, ctx->buf, 16); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +} // namespace + +std::array CalculateMd5Digest(absl::string_view s) { + MD5Context ctx; + MD5Init(&ctx); + MD5Update(&ctx, s); + std::array digest; + static_assert(sizeof(uint8_t[16]) == sizeof(MD5Digest), ""); + MD5Final(reinterpret_cast(digest.data()), &ctx); + return digest; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/util/md5.h b/Firestore/core/src/util/md5.h new file mode 100644 index 00000000000..d2738245750 --- /dev/null +++ b/Firestore/core/src/util/md5.h @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_UTIL_MD5_H_ +#define FIRESTORE_CORE_SRC_UTIL_MD5_H_ + +#include +#include + +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Calculates and returns the md5 digest of the given string. + */ +std::array CalculateMd5Digest(absl::string_view); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_UTIL_MD5_H_ diff --git a/Firestore/core/src/util/testing_hooks.h b/Firestore/core/src/util/testing_hooks.h index 1e1ea0b1788..60dde001a9b 100644 --- a/Firestore/core/src/util/testing_hooks.h +++ b/Firestore/core/src/util/testing_hooks.h @@ -24,6 +24,7 @@ #include "Firestore/core/src/api/listener_registration.h" #include "Firestore/core/src/util/no_destructor.h" +#include "absl/types/optional.h" namespace firebase { namespace firestore { @@ -39,6 +40,28 @@ class TestingHooks final { /** Returns the singleton instance of this class. */ static TestingHooks& GetInstance(); + /** + * Information about the bloom filter provided by Watch in the ExistenceFilter + * message's `unchangedNames` field. + */ + struct BloomFilterInfo { + /** + * Whether a full requery was averted by using the bloom filter. If false, + * then something happened, such as a false positive, to prevent using the + * bloom filter to avoid a full requery. + */ + bool applied = false; + + /** The number of hash functions used in the bloom filter. */ + int hash_count = -1; + + /** The number of bytes in the bloom filter's bitmask. */ + int bitmap_length = -1; + + /** The number of bits of padding in the last byte of the bloom filter. */ + int padding = -1; + }; + /** * Information about an existence filter mismatch, as specified to callbacks * registered with `OnExistenceFilterMismatch()`. @@ -52,6 +75,13 @@ class TestingHooks final { * specified in the `ExistenceFilter` message's `count` field. */ int existence_filter_count = -1; + + /** + * Information about the bloom filter provided by Watch in the + * ExistenceFilter message's `unchangedNames` field. If empty, then that + * means that Watch did _not_ provide a bloom filter. + */ + absl::optional bloom_filter; }; using ExistenceFilterMismatchCallback = diff --git a/Firestore/core/test/unit/local/local_serializer_test.cc b/Firestore/core/test/unit/local/local_serializer_test.cc index 1e76027f732..ab760e73a57 100644 --- a/Firestore/core/test/unit/local/local_serializer_test.cc +++ b/Firestore/core/test/unit/local/local_serializer_test.cc @@ -286,7 +286,10 @@ class LocalSerializerTest : public ::testing::Test { serializer.DecodeTargetData(&reader, *message); EXPECT_OK(reader.status()); - EXPECT_EQ(target_data, actual_target_data); + // Set the expected_count in expected TargetData to null, as serializing + // a TargetData into local Target proto will drop the expected_count and + // the deserialized actual TargetData will not include expected_count. + EXPECT_EQ(target_data.WithExpectedCount(absl::nullopt), actual_target_data); } ByteString EncodeTargetData(local::LocalSerializer* localSerializer, @@ -466,10 +469,46 @@ TEST_F(LocalSerializerTest, EncodesTargetData) { SnapshotVersion limbo_free_version = testutil::Version(1000); ByteString resume_token = testutil::ResumeToken(1039); + TargetData target_data( + query.ToTarget(), target_id, sequence_number, QueryPurpose::Listen, + SnapshotVersion(version), SnapshotVersion(limbo_free_version), + ByteString(resume_token), /*expected_count=*/absl::nullopt); + + ::firestore::client::Target expected; + expected.set_target_id(target_id); + expected.set_last_listen_sequence_number(sequence_number); + expected.mutable_snapshot_version()->set_nanos(1039000); + expected.mutable_last_limbo_free_snapshot_version()->set_nanos(1000000); + expected.set_resume_token(resume_token.data(), resume_token.size()); + v1::Target::QueryTarget* query_proto = expected.mutable_query(); + + // Add expected collection. + query_proto->set_parent("projects/p/databases/d/documents"); + v1::StructuredQuery::CollectionSelector from; + from.set_collection_id("room"); + *query_proto->mutable_structured_query()->add_from() = std::move(from); + + // Add default order_by. + v1::StructuredQuery::Order order; + order.mutable_field()->set_field_path(FieldPath::kDocumentKeyPath); + order.set_direction(v1::StructuredQuery::ASCENDING); + *query_proto->mutable_structured_query()->add_order_by() = std::move(order); + + ExpectRoundTrip(target_data, expected); +} + +TEST_F(LocalSerializerTest, EncodesTargetDataWillDropExpectedCount) { + core::Query query = Query("room"); + TargetId target_id = 42; + ListenSequenceNumber sequence_number = 10; + SnapshotVersion version = testutil::Version(1039); + SnapshotVersion limbo_free_version = testutil::Version(1000); + ByteString resume_token = testutil::ResumeToken(1039); + TargetData target_data(query.ToTarget(), target_id, sequence_number, QueryPurpose::Listen, SnapshotVersion(version), SnapshotVersion(limbo_free_version), - ByteString(resume_token)); + ByteString(resume_token), /*expected_count=*/1234); ::firestore::client::Target expected; expected.set_target_id(target_id); @@ -530,10 +569,36 @@ TEST_F(LocalSerializerTest, EncodesTargetDataWithDocumentQuery) { SnapshotVersion limbo_free_version = testutil::Version(1000); ByteString resume_token = testutil::ResumeToken(1039); + TargetData target_data( + query.ToTarget(), target_id, sequence_number, QueryPurpose::Listen, + SnapshotVersion(version), SnapshotVersion(limbo_free_version), + ByteString(resume_token), /*expected_count=*/absl::nullopt); + + ::firestore::client::Target expected; + expected.set_target_id(target_id); + expected.set_last_listen_sequence_number(sequence_number); + expected.mutable_snapshot_version()->set_nanos(1039000); + expected.mutable_last_limbo_free_snapshot_version()->set_nanos(1000000); + expected.set_resume_token(resume_token.data(), resume_token.size()); + v1::Target::DocumentsTarget* documents_proto = expected.mutable_documents(); + documents_proto->add_documents("projects/p/databases/d/documents/room/1"); + + ExpectRoundTrip(target_data, expected); +} + +TEST_F(LocalSerializerTest, + EncodesTargetDataWithDocumentQueryWillDropExpectedCount) { + core::Query query = Query("room/1"); + TargetId target_id = 42; + ListenSequenceNumber sequence_number = 10; + SnapshotVersion version = testutil::Version(1039); + SnapshotVersion limbo_free_version = testutil::Version(1000); + ByteString resume_token = testutil::ResumeToken(1039); + TargetData target_data(query.ToTarget(), target_id, sequence_number, QueryPurpose::Listen, SnapshotVersion(version), SnapshotVersion(limbo_free_version), - ByteString(resume_token)); + ByteString(resume_token), /*expected_count=*/1234); ::firestore::client::Target expected; expected.set_target_id(target_id); diff --git a/Firestore/core/test/unit/local/local_store_test.cc b/Firestore/core/test/unit/local/local_store_test.cc index 76020a5f257..b22553e7d4a 100644 --- a/Firestore/core/test/unit/local/local_store_test.cc +++ b/Firestore/core/test/unit/local/local_store_test.cc @@ -152,7 +152,8 @@ RemoteEvent ExistenceFilterEvent(TargetId target_id, remote::FakeTargetMetadataProvider metadata_provider; metadata_provider.SetSyncedKeys(synced_keys, target_data); - ExistenceFilter existence_filter{remote_count}; + ExistenceFilter existence_filter{remote_count, + /*bloom_filter=*/absl::nullopt}; WatchChangeAggregator aggregator{&metadata_provider}; ExistenceFilterWatchChange existence_filter_watch_change{existence_filter, target_id}; diff --git a/Firestore/core/test/unit/local/target_cache_test.cc b/Firestore/core/test/unit/local/target_cache_test.cc index f42c17f0b94..262d46edfca 100644 --- a/Firestore/core/test/unit/local/target_cache_test.cc +++ b/Firestore/core/test/unit/local/target_cache_test.cc @@ -79,7 +79,7 @@ TargetData TargetCacheTestBase::MakeTargetData( ByteString resume_token = ResumeToken(version); return TargetData(query.ToTarget(), target_id, sequence_number, QueryPurpose::Listen, Version(version), Version(version), - resume_token); + resume_token, /*expected_count=*/absl::nullopt); } void TargetCacheTestBase::AddMatchingKey(const DocumentKey& key, diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json new file mode 100644 index 00000000000..23f0f12b267 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json @@ -0,0 +1 @@ +{ "bits": { "bitmap": "RswZ", "padding": 1 }, "hashCount": 16 } diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json new file mode 100644 index 00000000000..5a41f842376 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_0001_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "10"} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json new file mode 100644 index 00000000000..43d07db5e6d --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"mwE=","padding":5},"hashCount":8} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_membership_test_result.json new file mode 100644 index 00000000000..5a41f842376 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_01_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "10"} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json new file mode 100644 index 00000000000..c03535eafc3 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"","padding":0},"hashCount":0} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_membership_test_result.json new file mode 100644 index 00000000000..fcbc34d14ac --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_1_1_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "00"} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json new file mode 100644 index 00000000000..04b77bf83ab --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json @@ -0,0 +1,7 @@ +{ + "bits": { + "bitmap": "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", + "padding": 1 + }, + "hashCount": 13 +} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json new file mode 100644 index 00000000000..25628a9889d --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_0001_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json new file mode 100644 index 00000000000..d1448123cdc --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"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","padding":1},"hashCount":7} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json new file mode 100644 index 00000000000..c8bef092c6b --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_01_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000100000000000000000000000000000000000000000000000000100000000000000000000000000000000000010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000010010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000010000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000001000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000100000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000100000000000000000000000000000000001000000000000000000000000101000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000100000000001000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000100000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000010000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000010000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000100000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000001000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000001000000000000100000000000000000000000000000000000000001100000000010000000000000000000000000000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000010000000000000000000010000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000100000000000000000100100000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000001000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000010000000000000000000010000000000000000000000000000000000000000000000000000000000000000000001000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000100000000000000000000000000000100000010000000000000000000000000000000000001000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000001000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000001000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000010000000000001000000000000000000000000000010000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000100000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000001000000000000000000000000000000000000001000000000000000000000000010000000000000000000000000000000000000001000000000000000000000000000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100001000000000000000000010000000000000000000000000000000000000000000000001000001000000000000000000000000000000000000000000001000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000010000000000010000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000001000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000001000000000000000000000100000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010000000000010010000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000001000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000010010000000010000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000100000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000001000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000010000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000010000000000000000000000000000000000000100000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000010000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000100000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000010000000000000000010000000000000000000000000000000000000000000000000000001000000000000000000000000001000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000100000000000100000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000001000000000000000000000000000000000000000000000000000001000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000100000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000100000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000010000000001000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010000000000000000000000000000010000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000010010000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000001000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json new file mode 100644 index 00000000000..c03535eafc3 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"","padding":0},"hashCount":0} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json new file mode 100644 index 00000000000..8872f804c6c --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_50000_1_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json new file mode 100644 index 00000000000..41f4c45b813 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"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","padding":7},"hashCount":13} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json new file mode 100644 index 00000000000..e93415cc7e6 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_0001_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json new file mode 100644 index 00000000000..0cd630436d1 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"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","padding":3},"hashCount":7} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json new file mode 100644 index 00000000000..416b190ec53 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_01_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000100000000000000000000000000000000110000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000001000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000010000000000000000000000000100000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000001000000000000000000000000000000000000000000000010100000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000010000000000000000000000000000000000000000000000000100000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000"} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json new file mode 100644 index 00000000000..c03535eafc3 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"","padding":0},"hashCount":0} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json new file mode 100644 index 00000000000..d568ff095e5 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_5000_1_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json new file mode 100644 index 00000000000..b206a483c54 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"vusW6Yc2oIsxmEapab4xh7Qqznx2LAVmFrA3SquH85kFR8l+/MpCIokPAAMuIAmKqcrwBtx/I8ds9Uw9ApHW2KZ/BMTbijPDac2Hm0oQvWFkUjycX7gNQrkjDIsRBdO/IaYDwAh74QwofDQLYxrSNgAdT+stIC7UKnpxZl1tRKTnIa0JQXrRChmxvO4r6WQI9QR76uk55KNZFQ5YmgvT6uYeTafiJEZb61Q9V3OOks44hV83F/8/rgPvRoweLHFJ+ezSJ04P9A+a1DHlMtpriDsxVIAgJm/CKuPkBC1jitppF9CagnLPidC65F1OPSE+8RAzHaEfuic32yNJEuQZfb1hq4pwE62hQ0/ulczuNFsQykikNcGBAWWDHWK4ur6dwjQSP7tOq3m4fLK3xYQt41OpIdPzPfn1Y4NC+BFdKQZUhIxEpTX2TPFoGsW9iSqRvF2zzWstAjcOyvT/yJ36ijEjVV9O+/NWfZvxUft26/NNDRPhpnxXHFGei10qKGMYym/seFr5+Hm2bpczLfpZtfQt/IHKg8Lyr8uMoAK5YhYrTqKY5DDo2jCPGnIbgwYJUDQRL34Eegvnd6T0A6XaU0y+SXbbfbk2vHybVZwuGEobTYZabE2bNg0rmdYx4LJvODl2ZFN7WZ5isyUAtBJJa16Py2PfLBxfrCScVpQJr6Xdka6eUrHA4wAT7V+r3NCZslUJyQky4lDjtacCVsRo2ONMGuWkUh9xqynRCQ85d21St+xAo4pl/V0ld1FeU6sOVGzV5oHosji3S4DFZZ+UZbKdAQwqR+UY+DRN0Vt51MZheZ1YYJd80ZX4DTshs6feSJpktuOBWJGftFzdbIIclJG29KKbwSpR25wGKnFafI2rwItNizCTVkxa/aQnTYF4PGhBmLu0zfEpaIz3pmpMUO7TPE1aYjyV8xakSJA4iDMQI3Z7n/6eF7PFxy/qUNuzHzmV3PoyvOjIC8GNnWaUdw9SlwTr/2LUzQ4fhucCykIAHcgawtcD/7whga1Z/LfOPROF1JfKw7a8H0vERX3WC427LHjbvbhAw0KnSfyIPMok49H20i3oZOdHQE0wxYj/1APD8JfU/TlMW1umRVARZ8ohWLF0oZcohEqexajnKREArfVvvBroyFvI5yRgR4vQapTI0RPCmi4tNbw11Zgy43snKG2pVYR2S4I/Dg9rcK4Plr301TIbFRAT0CE+vqUAjg56lkxcDnUxMW/p9qDU2bILaypkXyr16SiZxc9bMvYEVVBztcbyU6uI+JLFruiPl4mHHv6IylJIc7HJ1vL1gnRTP3bBBvw5qyEl0KS6woregx1RAbPszwxRrTR+zfxV9tUKuC59BZHlmpC5YFAK2wLyU1d5rQyhMN4ySA8POYD6rj80DEZHXQzoTvfQIitPp42unEQRGMKQt/PqljT8A/lBU5DZcc8M3hkFklDpDyIXKuwLkd1zuiPrwzkC27GZ0SZEvQvUi3xVefevyFdY8lAeAlP17z57E+vKDjG9Guo+sX7I1qByNUBpMSO4UkOMP9otRBToRjxD1Rb+lEdGCUwcFm677KL6hR9e3Om9PWkZF6LpWqH+qnt9+lPVxgY=","padding":5},"hashCount":13} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json new file mode 100644 index 00000000000..3bcbf418c24 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_0001_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json new file mode 100644 index 00000000000..35de64eee0a --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"n+36qf4UgWXLxRabHwqwva8jpXlZ7yfdCjRNwHQ5MBmgc35tGNWFvTgrWyfmznuz1j0wMabH29pR84MjjWGgAxLhDXU3dyYTY505812+BYTO5GXEAyGoUZhcBlUZPK+RAqSZ+9e3q9Gxpmoes/4iCbxJFc5eew0+95v5Z0h5fvlF2Y9iRBDu2PWC1pVGuc/j3W+34+5IwPtDLPbtfvYhnohTfXP02vsf2/77YqEtfmMVFfIMZJ5e7uLOA+rcmQC5fFfxjubJfKR5R+Rzw/UWd0Eg3gi+FCUIk/WUP5938R4tPH3fnrtQjclvsZhtj5dak7WWw1Ph4ZFdJE2XdFBH1JSvggI5tFKH5WUeIBlHYj+V3HomQ2gDrwMXGsIJokcwQi1qTUjECnwYGlOl/FRjZQg7h3QoSkyxgBnp6w7XKttc/EJf+279WLkvm6K/sTuQiFsOGqdQQ+c6osu9SzICn7Rtu4+RzmfxgCx1i2rX1OvVt+DLWa8/K5TlLvVM7GqXiHeaLuvkaz4uR754T1Iurp8/Ps2yJdXYHLyGndJa+7DJ1BPsGK8ZYbYFN7jGamHF9de+3K/syp1raDltsNUxUGAaMBghK1nIRDtHLSHBtVkuxvUkP3iVIkm6pEp0K/2npYUEAsbYVkug4Iv7qhnLTGwMUXP3piTMySLLoZ9bGY0k13FMX7h/s79dJDcIIf4fR9S0SN6fWXKdZOBLFzyXGcxbD+o0o3NO/UOZDgmTet2or8rvipr4tGDyGluUnW1o/fWPlGvEIo/7Ep6avGyw7jilLKYiunAA","padding":7},"hashCount":7} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_membership_test_result.json new file mode 100644 index 00000000000..2a851465e72 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_01_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json new file mode 100644 index 00000000000..c03535eafc3 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json @@ -0,0 +1 @@ +{"bits":{"bitmap":"","padding":0},"hashCount":0} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_membership_test_result.json b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_membership_test_result.json new file mode 100644 index 00000000000..d59b3592362 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_golden_test_data/Validation_BloomFilterTest_MD5_500_1_membership_test_result.json @@ -0,0 +1 @@ +{"membershipTestResults" : "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/Firestore/core/test/unit/remote/bloom_filter_test.cc b/Firestore/core/test/unit/remote/bloom_filter_test.cc new file mode 100644 index 00000000000..aaf57b98064 --- /dev/null +++ b/Firestore/core/test/unit/remote/bloom_filter_test.cc @@ -0,0 +1,356 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/remote/bloom_filter.h" + +#include +#include + +#include "Firestore/core/src/util/hard_assert.h" +#include "Firestore/core/src/util/json_reader.h" +#include "Firestore/core/src/util/path.h" +#include "absl/strings/escaping.h" +#include "gtest/gtest.h" + +namespace firebase { +namespace firestore { +namespace remote { +namespace { + +using nanopb::ByteString; +using nlohmann::json; +using util::JsonReader; +using util::Path; +using util::Status; +using util::StatusOr; + +TEST(BloomFilterUnitTest, CanInstantiateEmptyBloomFilter) { + BloomFilter bloom_filter(ByteString{}, 0, 0); + EXPECT_EQ(bloom_filter.bit_count(), 0); +} + +TEST(BloomFilterUnitTest, CanInstantiateNonEmptyBloomFilter) { + { + BloomFilter bloom_filter(ByteString{1}, 0, 1); + EXPECT_EQ(bloom_filter.bit_count(), 8); + } + { + BloomFilter bloom_filter(ByteString{1}, 7, 1); + EXPECT_EQ(bloom_filter.bit_count(), 1); + } +} + +TEST(BloomFilterUnitTest, CreateShouldReturnBloomFilterOnValidInputs) { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{1}, 1, 1); + ASSERT_TRUE(maybe_bloom_filter.ok()); + BloomFilter bloom_filter = maybe_bloom_filter.ValueOrDie(); + EXPECT_EQ(bloom_filter.bit_count(), 7); +} + +TEST(BloomFilterUnitTest, CreateShouldBeAbleToCreatEmptyBloomFilter) { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{}, 0, 0); + ASSERT_TRUE(maybe_bloom_filter.ok()); + BloomFilter bloom_filter = maybe_bloom_filter.ValueOrDie(); + EXPECT_EQ(bloom_filter.bit_count(), 0); +} + +TEST(BloomFilterUnitTest, CreateShouldReturnNotOKStatusOnNegativePadding) { + { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{}, -1, 0); + ASSERT_FALSE(maybe_bloom_filter.ok()); + EXPECT_EQ(maybe_bloom_filter.status().error_message(), + "Invalid padding: -1"); + } + { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{1}, -1, 1); + ASSERT_FALSE(maybe_bloom_filter.ok()); + EXPECT_EQ(maybe_bloom_filter.status().error_message(), + "Invalid padding: -1"); + } +} + +TEST(BloomFilterUnitTest, CreateShouldReturnNotOKStatusOnNegativeHashCount) { + { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{}, 0, -1); + ASSERT_FALSE(maybe_bloom_filter.ok()); + EXPECT_EQ(maybe_bloom_filter.status().error_message(), + "Invalid hash count: -1"); + } + { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{1}, 1, -1); + ASSERT_FALSE(maybe_bloom_filter.ok()); + EXPECT_EQ(maybe_bloom_filter.status().error_message(), + "Invalid hash count: -1"); + } +} + +TEST(BloomFilterUnitTest, CreateShouldReturnNotOKStatusOnZeroHashCount) { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{1}, 1, 0); + ASSERT_FALSE(maybe_bloom_filter.ok()); + EXPECT_EQ(maybe_bloom_filter.status().error_message(), + "Invalid hash count: 0"); +} + +TEST(BloomFilterUnitTest, CreateShouldReturnNotOKStatusIfPaddingIsTooLarge) { + StatusOr maybe_bloom_filter = + BloomFilter::Create(ByteString{1}, 8, 1); + ASSERT_FALSE(maybe_bloom_filter.ok()); + EXPECT_EQ(maybe_bloom_filter.status().error_message(), "Invalid padding: 8"); +} + +TEST(BloomFilterTest, CheckBloomFiltersEqualityWithSameInput) { + BloomFilter bloom_filter1(ByteString{1}, 1, 1); + BloomFilter bloom_filter2(ByteString{1}, 1, 1); + EXPECT_TRUE(bloom_filter1 == bloom_filter2); + EXPECT_FALSE(bloom_filter1 != bloom_filter2); +} + +TEST(BloomFilterTest, CheckBloomFiltersEqualityWithDifferentBitmap) { + { + BloomFilter bloom_filter1(ByteString{1}, 1, 1); + BloomFilter bloom_filter2(ByteString{2}, 1, 1); + EXPECT_FALSE(bloom_filter1 == bloom_filter2); + EXPECT_TRUE(bloom_filter1 != bloom_filter2); + } + { + BloomFilter bloom_filter1(ByteString{1}, 1, 1); + BloomFilter bloom_filter2(ByteString{1, 1}, 1, 1); + EXPECT_FALSE(bloom_filter1 == bloom_filter2); + EXPECT_TRUE(bloom_filter1 != bloom_filter2); + } +} + +TEST(BloomFilterTest, CheckBloomFiltersEqualityWithDifferentPadding) { + BloomFilter bloom_filter1(ByteString{1}, 1, 1); + BloomFilter bloom_filter2(ByteString{1}, 2, 1); + EXPECT_FALSE(bloom_filter1 == bloom_filter2); + EXPECT_TRUE(bloom_filter1 != bloom_filter2); +} + +TEST(BloomFilterTest, CheckBloomFiltersEqualityWithDifferentHashCount) { + BloomFilter bloom_filter1(ByteString{1}, 1, 1); + BloomFilter bloom_filter2(ByteString{1}, 1, 2); + EXPECT_FALSE(bloom_filter1 == bloom_filter2); + EXPECT_TRUE(bloom_filter1 != bloom_filter2); +} + +TEST(BloomFilterTest, + BloomFiltersEqualityCheckShouldIgnoreBitsInPaddingIndexes) { + // In BloomFilter bitmap, padding is guaranteed to be less than 8, and + // starts counting from the leftmost indexes of the last byte. + { + BloomFilter bloom_filter1(ByteString{255, 127}, 1, + 1); // bitmap -> 11111111 01111111 + BloomFilter bloom_filter2(ByteString{255, 255}, 1, + 1); // bitmap -> 11111111 11111111 + EXPECT_TRUE(bloom_filter1 == bloom_filter2); + EXPECT_FALSE(bloom_filter1 != bloom_filter2); + } + { + BloomFilter bloom_filter1(ByteString{255, 207}, 4, + 1); // bitmap -> 11111111 11001111 + BloomFilter bloom_filter2(ByteString{255, 255}, 4, + 1); // bitmap -> 11111111 11111111 + EXPECT_TRUE(bloom_filter1 == bloom_filter2); + EXPECT_FALSE(bloom_filter1 != bloom_filter2); + } +} + +TEST(BloomFilterTest, MightContainCanProcessNonStandardCharacters) { + // A non-empty BloomFilter object with 1 insertion : "ÀÒ∑" + BloomFilter bloom_filter(ByteString{237, 5}, 5, 8); + EXPECT_TRUE(bloom_filter.MightContain("ÀÒ∑")); + EXPECT_FALSE(bloom_filter.MightContain("Ò∑À")); +} + +TEST(BloomFilterUnitTest, MightContainOnEmptyBloomFilterShouldReturnFalse) { + BloomFilter bloom_filter(ByteString{}, 0, 0); + EXPECT_FALSE(bloom_filter.MightContain("")); + EXPECT_FALSE(bloom_filter.MightContain("a")); +} + +TEST(BloomFilterUnitTest, + MightContainWithEmptyStringMightReturnFalsePositiveResult) { + { + BloomFilter bloom_filter(ByteString{1}, 1, 1); + EXPECT_FALSE(bloom_filter.MightContain("")); + } + { + BloomFilter bloom_filter(ByteString{255}, 0, 16); + EXPECT_TRUE(bloom_filter.MightContain("")); + } +} + +class BloomFilterGoldenTest : public ::testing::Test { + public: + static void RunGoldenTest(const std::string& test_file) { + BloomFilter bloom_filter = LoadBloomFilter(test_file); + std::string membership_result = LoadMembershipResult(test_file); + + for (size_t i = 0; i < membership_result.length(); i++) { + bool expectedResult = membership_result[i] == '1'; + bool mightContainResult = + bloom_filter.MightContain(kGoldenDocumentPrefix + std::to_string(i)); + + EXPECT_EQ(mightContainResult, expectedResult); + } + } + + private: + static const char* kGoldenDocumentPrefix; + + static Path GetGoldenTestFolder() { + return Path::FromUtf8(__FILE__).Dirname().AppendUtf8( + "bloom_filter_golden_test_data/"); + } + + static json ReadFile(const std::string& file_name) { + Path file_path = GetGoldenTestFolder().AppendUtf8(file_name); + std::ifstream stream(file_path.native_value()); + HARD_ASSERT(stream.good()); + return nlohmann::json::parse(stream); + } + + static BloomFilter LoadBloomFilter(const std::string& file_name) { + json test_file = ReadFile(file_name); + + JsonReader reader; + nlohmann::json bits = reader.OptionalObject("bits", test_file, {}); + std::string bitmap = reader.OptionalString("bitmap", bits, ""); + int padding = reader.OptionalInt("padding", bits, 0); + int hash_count = reader.OptionalInt("hashCount", test_file, 0); + std::string decoded; + absl::Base64Unescape(bitmap, &decoded); + ByteString decoded_map(decoded); + + StatusOr maybe_bloom_filter = + BloomFilter::Create(std::move(decoded_map), padding, hash_count); + HARD_ASSERT(maybe_bloom_filter.ok(), + "Bloom filter input file %s has invalid values. Error: %s", + file_name, maybe_bloom_filter.status().error_message()); + + return maybe_bloom_filter.ValueOrDie(); + } + + static std::string LocateResultFile(std::string file_name) { + const std::string substring = "bloom_filter_proto"; + size_t start_pos = file_name.find(substring); + HARD_ASSERT(start_pos != std::string::npos, + "Test file name %s is not valid, expected to include %s", + file_name, substring); + + return file_name.replace(start_pos, substring.size(), + "membership_test_result"); + } + + static std::string LoadMembershipResult(const std::string& file_name) { + std::string result_file_name = LocateResultFile(file_name); + json result_file = ReadFile(result_file_name); + + JsonReader reader; + std::string membership_result = reader.OptionalString( + "membershipTestResults", result_file, "[invalid]"); + HARD_ASSERT( + membership_result != "[invalid]", + "Membership result file %s doesn't contain membershipTestResults.", + result_file_name); + return membership_result; + } +}; + +const char* BloomFilterGoldenTest::kGoldenDocumentPrefix = + "projects/project-1/databases/database-1/documents/coll/doc"; + +/** + * Golden tests are generated by backend based on inserting n number of document + * paths into a bloom filter. + * + *

Full document path is generated by concatenating documentPrefix and number + * n, eg, projects/project-1/databases/database-1/documents/coll/doc12. + * + *

The test result is generated by checking the membership of documents from + * documentPrefix+0 to documentPrefix+2n. The membership results from 0 to n is + * expected to be true, and the membership results from n to 2n is expected to + * be false with some false positive results. + */ +TEST_F(BloomFilterGoldenTest, GoldenTest1Document1FalsePositiveRate) { + RunGoldenTest("Validation_BloomFilterTest_MD5_1_1_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest1Document01FalsePositiveRate) { + RunGoldenTest("Validation_BloomFilterTest_MD5_1_01_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest1Document0001FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_1_0001_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest500Document1FalsePositiveRate) { + RunGoldenTest("Validation_BloomFilterTest_MD5_500_1_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest500Document01FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_500_01_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest500Document0001FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_500_0001_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest5000Document1FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_5000_1_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest5000Document01FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_5000_01_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest5000Document0001FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_5000_0001_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest50000Document1FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_50000_1_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest50000Document01FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_50000_01_bloom_filter_proto.json"); +} + +TEST_F(BloomFilterGoldenTest, GoldenTest50000Document0001FalsePositiveRate) { + RunGoldenTest( + "Validation_BloomFilterTest_MD5_50000_0001_bloom_filter_proto.json"); +} + +} // namespace +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/test/unit/remote/fake_target_metadata_provider.cc b/Firestore/core/test/unit/remote/fake_target_metadata_provider.cc index cf330a5100b..88d1407d559 100644 --- a/Firestore/core/test/unit/remote/fake_target_metadata_provider.cc +++ b/Firestore/core/test/unit/remote/fake_target_metadata_provider.cc @@ -102,6 +102,10 @@ absl::optional FakeTargetMetadataProvider::GetTargetDataForTarget( return it->second; } +const model::DatabaseId& FakeTargetMetadataProvider::GetDatabaseId() const { + return database_id_; +} + } // namespace remote } // namespace firestore } // namespace firebase diff --git a/Firestore/core/test/unit/remote/fake_target_metadata_provider.h b/Firestore/core/test/unit/remote/fake_target_metadata_provider.h index 6b231774578..d59bcd92f0d 100644 --- a/Firestore/core/test/unit/remote/fake_target_metadata_provider.h +++ b/Firestore/core/test/unit/remote/fake_target_metadata_provider.h @@ -18,6 +18,7 @@ #define FIRESTORE_CORE_TEST_UNIT_REMOTE_FAKE_TARGET_METADATA_PROVIDER_H_ #include +#include #include #include "Firestore/core/src/local/target_data.h" @@ -73,10 +74,21 @@ class FakeTargetMetadataProvider : public TargetMetadataProvider { model::TargetId target_id) const override; absl::optional GetTargetDataForTarget( model::TargetId target_id) const override; + const model::DatabaseId& GetDatabaseId() const override; + + /** + * Sets the database_id to a custom value, used for getting Document's full + * path. + */ + void SetDatabaseId(model::DatabaseId database_id) { + database_id_ = std::move(database_id); + } private: std::unordered_map synced_keys_; std::unordered_map target_data_; + model::DatabaseId database_id_ = + model::DatabaseId("test-project", "(default)"); }; } // namespace remote diff --git a/Firestore/core/test/unit/remote/remote_event_test.cc b/Firestore/core/test/unit/remote/remote_event_test.cc index 8764a3aae90..9c25aa198c5 100644 --- a/Firestore/core/test/unit/remote/remote_event_test.cc +++ b/Firestore/core/test/unit/remote/remote_event_test.cc @@ -105,6 +105,10 @@ class RemoteEventTest : public testing::Test { DocumentKeySet existing_keys, const std::vector>& watch_changes); + void OverrideDefaultDatabaseId(model::DatabaseId database_id) { + target_metadata_provider_.SetDatabaseId(std::move(database_id)); + } + ByteString resume_token1_; FakeTargetMetadataProvider target_metadata_provider_; std::unordered_map no_outstanding_responses_; @@ -547,7 +551,117 @@ TEST_F(RemoteEventTest, ExistenceFilterMismatchClearsTarget) { // The existence filter mismatch will remove the document from target 1, // but not synthesize a document delete. - ExistenceFilterWatchChange change4{ExistenceFilter{1}, 1}; + ExistenceFilterWatchChange change4{ + ExistenceFilter{1, /*bloom_filter=*/absl::nullopt}, 1}; + aggregator.HandleExistenceFilter(change4); + + event = aggregator.CreateRemoteEvent(testutil::Version(4)); + + TargetChange target_change3{ByteString(), false, DocumentKeySet{}, + DocumentKeySet{}, + DocumentKeySet{doc1.key(), doc2.key()}}; + ASSERT_TRUE(event.target_changes().at(1) == target_change3); + + ASSERT_EQ(event.target_changes().size(), 1); + ASSERT_EQ(event.target_mismatches().size(), 1); + ASSERT_EQ(event.document_updates().size(), 0); +} + +TEST_F(RemoteEventTest, ExistenceFilterMismatchWithBloomFilterSuccess) { + std::unordered_map target_map = ActiveQueries({1, 2}); + + MutableDocument doc1 = Doc("docs/1", 1, Map("value", 1)); + auto change1 = MakeDocChange({1}, {}, doc1.key(), doc1); + MutableDocument doc2 = Doc("docs/2", 2, Map("value", 2)); + auto change2 = MakeDocChange({1}, {}, doc2.key(), doc2); + auto change3 = + MakeTargetChange(WatchTargetChangeState::Current, {1}, resume_token1_); + + WatchChangeAggregator aggregator = CreateAggregator( + target_map, no_outstanding_responses_, + DocumentKeySet{doc1.key(), doc2.key()}, + Changes(std::move(change1), std::move(change2), std::move(change3))); + + // The BloomFilterParameters value below is created based on the document + // paths that are constructed using the following pattern: + // "projects/test-project/databases/test-database/documents/"+document_key. + // Override the database ID to ensure that the document path matches the + // pattern above. + OverrideDefaultDatabaseId(model::DatabaseId("test-project", "test-database")); + + RemoteEvent event = aggregator.CreateRemoteEvent(testutil::Version(3)); + + ASSERT_EQ(event.snapshot_version(), testutil::Version(3)); + ASSERT_EQ(event.document_updates().size(), 2); + ASSERT_EQ(event.document_updates().at(doc1.key()), doc1); + ASSERT_EQ(event.document_updates().at(doc2.key()), doc2); + + ASSERT_EQ(event.target_changes().size(), 2); + + TargetChange target_change1{resume_token1_, true, DocumentKeySet{}, + DocumentKeySet{doc1.key(), doc2.key()}, + DocumentKeySet{}}; + ASSERT_TRUE(event.target_changes().at(1) == target_change1); + + TargetChange target_change2{resume_token1_, false, DocumentKeySet{}, + DocumentKeySet{}, DocumentKeySet{}}; + ASSERT_TRUE(event.target_changes().at(2) == target_change2); + + // The given BloomFilter will return false on MightContain(doc1) and true on + // MightContain(doc2). + ExistenceFilterWatchChange change4{ + ExistenceFilter{1, BloomFilterParameters{{0x0E, 0x0F}, 1, 7}}, 1}; + // The existence filter identifies that doc1 is deleted, and skips the full + // re-query. + aggregator.HandleExistenceFilter(change4); + + event = aggregator.CreateRemoteEvent(testutil::Version(4)); + + ASSERT_EQ(event.target_changes().size(), 1); + ASSERT_EQ(event.target_mismatches().size(), 0); + ASSERT_EQ(event.document_updates().size(), 0); +} + +TEST_F(RemoteEventTest, + ExistenceFilterMismatchWithBloomFilterFalsePositiveResult) { + std::unordered_map target_map = ActiveQueries({1, 2}); + + MutableDocument doc1 = Doc("docs/1", 1, Map("value", 1)); + auto change1 = MakeDocChange({1}, {}, doc1.key(), doc1); + MutableDocument doc2 = Doc("docs/2", 2, Map("value", 2)); + auto change2 = MakeDocChange({1}, {}, doc2.key(), doc2); + auto change3 = + MakeTargetChange(WatchTargetChangeState::Current, {1}, resume_token1_); + + WatchChangeAggregator aggregator = CreateAggregator( + target_map, no_outstanding_responses_, + DocumentKeySet{doc1.key(), doc2.key()}, + Changes(std::move(change1), std::move(change2), std::move(change3))); + + RemoteEvent event = aggregator.CreateRemoteEvent(testutil::Version(3)); + + ASSERT_EQ(event.snapshot_version(), testutil::Version(3)); + ASSERT_EQ(event.document_updates().size(), 2); + ASSERT_EQ(event.document_updates().at(doc1.key()), doc1); + ASSERT_EQ(event.document_updates().at(doc2.key()), doc2); + + ASSERT_EQ(event.target_changes().size(), 2); + + TargetChange target_change1{resume_token1_, true, DocumentKeySet{}, + DocumentKeySet{doc1.key(), doc2.key()}, + DocumentKeySet{}}; + ASSERT_TRUE(event.target_changes().at(1) == target_change1); + + TargetChange target_change2{resume_token1_, false, DocumentKeySet{}, + DocumentKeySet{}, DocumentKeySet{}}; + ASSERT_TRUE(event.target_changes().at(2) == target_change2); + + // The given BloomFilter will return true on both MightContain(doc1) and + // MightContain(doc2). + ExistenceFilterWatchChange change4{ + ExistenceFilter{1, BloomFilterParameters{{0x42, 0xFE}, 2, 7}}, 1}; + // The existence filter cannot identify which doc is deleted. It will remove + // the document from target 1, but not synthesize a document delete. aggregator.HandleExistenceFilter(change4); event = aggregator.CreateRemoteEvent(testutil::Version(4)); @@ -578,7 +692,8 @@ TEST_F(RemoteEventTest, ExistenceFilterMismatchRemovesCurrentChanges) { // The existence filter mismatch will remove the document from target 1, but // not synthesize a document delete. - ExistenceFilterWatchChange existence_filter{ExistenceFilter{0}, 1}; + ExistenceFilterWatchChange existence_filter{ + ExistenceFilter{0, /*bloom_filter=*/absl::nullopt}, 1}; aggregator.HandleExistenceFilter(existence_filter); RemoteEvent event = aggregator.CreateRemoteEvent(testutil::Version(3)); diff --git a/Firestore/core/test/unit/remote/serializer_test.cc b/Firestore/core/test/unit/remote/serializer_test.cc index d0c07d83721..bea30617594 100644 --- a/Firestore/core/test/unit/remote/serializer_test.cc +++ b/Firestore/core/test/unit/remote/serializer_test.cc @@ -75,6 +75,7 @@ namespace { namespace v1 = google::firestore::v1; using core::Bound; +using google::protobuf::Int32Value; using google::protobuf::util::MessageDifferencer; using local::QueryPurpose; using local::TargetData; @@ -1525,7 +1526,7 @@ TEST_F(SerializerTest, EncodesResumeTokens) { core::Query q = Query("docs"); TargetData model(q.ToTarget(), 1, 0, QueryPurpose::Listen, SnapshotVersion::None(), SnapshotVersion::None(), - Bytes({1, 2, 3})); + Bytes({1, 2, 3}), /*expected_count=*/absl::nullopt); v1::Target proto; proto.mutable_query()->set_parent(ResourceName("")); @@ -1548,6 +1549,63 @@ TEST_F(SerializerTest, EncodesResumeTokens) { ExpectRoundTrip(model, proto); } +TEST_F(SerializerTest, EncodesExpectedCount) { + core::Query q = Query("docs"); + TargetData model(q.ToTarget(), 1, 0, QueryPurpose::Listen, + SnapshotVersion::None(), SnapshotVersion::None(), + Bytes({1, 2, 3}), /*expected_count=*/1234); + + v1::Target proto; + proto.mutable_query()->set_parent(ResourceName("")); + proto.set_target_id(1); + + v1::StructuredQuery::CollectionSelector from; + from.set_collection_id("docs"); + *proto.mutable_query()->mutable_structured_query()->add_from() = + std::move(from); + + v1::StructuredQuery::Order order; + order.mutable_field()->set_field_path(FieldPath::kDocumentKeyPath); + order.set_direction(v1::StructuredQuery::ASCENDING); + *proto.mutable_query()->mutable_structured_query()->add_order_by() = + std::move(order); + + proto.set_resume_token("\001\002\003"); + + google::protobuf::Int32Value int32_value; + google::protobuf::Int32Value* expected_count = int32_value.New(); + expected_count->set_value(1234); + proto.set_allocated_expected_count(expected_count); + + EXPECT_TRUE(proto.has_expected_count()); + ExpectRoundTrip(model, proto); +} + +TEST_F(SerializerTest, EncodeExpectedCountSkippedWithoutResumeToken) { + core::Query q = Query("docs"); + TargetData model(q.ToTarget(), 1, 0, QueryPurpose::Listen, + SnapshotVersion::None(), SnapshotVersion::None(), + ByteString(), /*expected_count=*/1234); + + v1::Target proto; + proto.mutable_query()->set_parent(ResourceName("")); + proto.set_target_id(1); + + v1::StructuredQuery::CollectionSelector from; + from.set_collection_id("docs"); + *proto.mutable_query()->mutable_structured_query()->add_from() = + std::move(from); + + v1::StructuredQuery::Order order; + order.mutable_field()->set_field_path(FieldPath::kDocumentKeyPath); + order.set_direction(v1::StructuredQuery::ASCENDING); + *proto.mutable_query()->mutable_structured_query()->add_order_by() = + std::move(order); + + EXPECT_FALSE(proto.has_expected_count()); + ExpectRoundTrip(model, proto); +} + TEST_F(SerializerTest, EncodesListenRequestLabels) { core::Query q = Query("docs"); @@ -1716,7 +1774,8 @@ TEST_F(SerializerTest, DecodesListenResponseWithDocumentRemove) { } TEST_F(SerializerTest, DecodesListenResponseWithExistenceFilter) { - ExistenceFilterWatchChange model(ExistenceFilter(2), 100); + ExistenceFilterWatchChange model( + ExistenceFilter(2, /*bloom_filter=*/absl::nullopt), 100); v1::ListenResponse proto; @@ -1727,6 +1786,26 @@ TEST_F(SerializerTest, DecodesListenResponseWithExistenceFilter) { ExpectDeserializationRoundTrip(model, proto); } +TEST_F(SerializerTest, + DecodesListenResponseWithExistenceFilterWhenBloomFilterNotNull) { + ExistenceFilterWatchChange model( + ExistenceFilter(555, BloomFilterParameters{{0x42, 0xFE}, 7, 33}), 999); + + v1::ListenResponse proto; + proto.mutable_filter()->set_count(555); + proto.mutable_filter()->set_target_id(999); + + v1::BloomFilter* bloom_filter = + proto.mutable_filter()->mutable_unchanged_names(); + bloom_filter->set_hash_count(33); + bloom_filter->mutable_bits()->set_padding(7); + bloom_filter->mutable_bits()->set_bitmap("\x42\xFE"); + + SCOPED_TRACE( + "DecodesListenResponseWithExistenceFilterWhenBloomFilterNotNull"); + ExpectDeserializationRoundTrip(model, proto); +} + TEST_F(SerializerTest, DecodesVersion) { auto version = Version(123456789); SnapshotVersion model(version.timestamp()); diff --git a/Firestore/core/test/unit/remote/watch_change_test.cc b/Firestore/core/test/unit/remote/watch_change_test.cc index 67a7e7d3a6f..fe48c8ee2e5 100644 --- a/Firestore/core/test/unit/remote/watch_change_test.cc +++ b/Firestore/core/test/unit/remote/watch_change_test.cc @@ -41,10 +41,22 @@ TEST(WatchChangeTest, CanCreateDocumentWatchChange) { } TEST(WatchChangeTest, CanCreateExistenceFilterWatchChange) { - ExistenceFilter filter{7}; - ExistenceFilterWatchChange change{filter, 5}; - EXPECT_EQ(change.filter().count(), 7); - EXPECT_EQ(change.target_id(), 5); + { + ExistenceFilter filter{7, /*bloom_filter=*/absl::nullopt}; + ExistenceFilterWatchChange change{filter, 5}; + EXPECT_EQ(change.filter().count(), 7); + EXPECT_EQ(change.filter().bloom_filter_parameters(), absl::nullopt); + EXPECT_EQ(change.target_id(), 5); + } + { + BloomFilterParameters bloom_filter_parameters{{0x42, 0xFE}, 7, 33}; + ExistenceFilter filter{7, bloom_filter_parameters}; + ExistenceFilterWatchChange change{std::move(filter), 5}; + EXPECT_EQ(change.filter().count(), 7); + EXPECT_EQ(change.filter().bloom_filter_parameters(), + bloom_filter_parameters); + EXPECT_EQ(change.target_id(), 5); + } } TEST(WatchChangeTest, CanCreateWatchTargetChange) { diff --git a/Firestore/core/test/unit/testutil/md5_testing.cc b/Firestore/core/test/unit/testutil/md5_testing.cc new file mode 100644 index 00000000000..d6b9b7e3713 --- /dev/null +++ b/Firestore/core/test/unit/testutil/md5_testing.cc @@ -0,0 +1,78 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/test/unit/testutil/md5_testing.h" + +#include "Firestore/core/src/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace testutil { +namespace md5 { + +std::uint8_t UnsignedCharFromHexDigit(char digit) { + switch (digit) { + case '0': + return 0x0; + case '1': + return 0x1; + case '2': + return 0x2; + case '3': + return 0x3; + case '4': + return 0x4; + case '5': + return 0x5; + case '6': + return 0x6; + case '7': + return 0x7; + case '8': + return 0x8; + case '9': + return 0x9; + case 'a': + return 0xA; + case 'b': + return 0xB; + case 'c': + return 0xC; + case 'd': + return 0xD; + case 'e': + return 0xE; + case 'f': + return 0xF; + } + HARD_FAIL("unrecognized hex digit: %s", std::to_string(digit)); +} + +std::array Uint8ArrayFromHexDigest(const std::string& s) { + HARD_ASSERT(s.length() == 32); + std::array result; + for (int i = 0; i < 16; ++i) { + std::uint8_t c1 = UnsignedCharFromHexDigit(s[i * 2]); + std::uint8_t c2 = UnsignedCharFromHexDigit(s[(i * 2) + 1]); + result[i] = (c1 << 4) | c2; + } + return result; +} + +} // namespace md5 +} // namespace testutil +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/test/unit/testutil/md5_testing.h b/Firestore/core/test/unit/testutil/md5_testing.h new file mode 100644 index 00000000000..21944f7a023 --- /dev/null +++ b/Firestore/core/test/unit/testutil/md5_testing.h @@ -0,0 +1,50 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_TEST_UNIT_TESTUTIL_MD5_TESTING_H_ +#define FIRESTORE_CORE_TEST_UNIT_TESTUTIL_MD5_TESTING_H_ + +#include +#include +#include + +namespace firebase { +namespace firestore { +namespace testutil { +namespace md5 { + +// Gets the unsigned char corresponding to the given hex digit. +// The digit must be one of '0', '1', ... , '9', 'a', 'b', ... , 'f'. +// The lower 4 bits of the returned value will be set and the rest will be 0. +std::uint8_t UnsignedCharFromHexDigit(char digit); + +// Calculates the 16-byte uint8_t array represented by the given hex +// string. The given string must be exactly 32 characters and each character +// must be one that is accepted by the UnsignedCharFromHexDigit() function. +// e.g. "fc3ff98e8c6a0d3087d515c0473f8677". +// The `md5sum` command from GNU coreutils can be used to generate a string to +// specify to this function. +// e.g. +// $ printf 'hello world!' | md5sum - +// fc3ff98e8c6a0d3087d515c0473f8677 - +std::array Uint8ArrayFromHexDigest(const std::string&); + +} // namespace md5 +} // namespace testutil +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_TEST_UNIT_TESTUTIL_MD5_TESTING_H_ diff --git a/Firestore/core/test/unit/util/md5_test.cc b/Firestore/core/test/unit/util/md5_test.cc new file mode 100644 index 00000000000..7c2545a44e2 --- /dev/null +++ b/Firestore/core/test/unit/util/md5_test.cc @@ -0,0 +1,95 @@ +/* + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "Firestore/core/src/util/md5.h" +#include "Firestore/core/test/unit/testutil/md5_testing.h" + +#include "gtest/gtest.h" + +using firebase::firestore::testutil::md5::Uint8ArrayFromHexDigest; +using firebase::firestore::util::CalculateMd5Digest; + +namespace { + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfEmptyString) { + EXPECT_EQ(CalculateMd5Digest(""), + Uint8ArrayFromHexDigest("d41d8cd98f00b204e9800998ecf8427e")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfA) { + EXPECT_EQ(CalculateMd5Digest("a"), + Uint8ArrayFromHexDigest("0cc175b9c0f1b6a831c399e269772661")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfABC) { + EXPECT_EQ(CalculateMd5Digest("abc"), + Uint8ArrayFromHexDigest("900150983cd24fb0d6963f7d28e17f72")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfHelloWorld) { + EXPECT_EQ(CalculateMd5Digest("hello world!"), + Uint8ArrayFromHexDigest("fc3ff98e8c6a0d3087d515c0473f8677")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfMessageDigest) { + EXPECT_EQ(CalculateMd5Digest("message digest"), + Uint8ArrayFromHexDigest("f96b697d7cb7938d525a2f31aaf161d0")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfLowercaseAlphabet) { + EXPECT_EQ(CalculateMd5Digest("abcdefghijklmnopqrstuvwxyz"), + Uint8ArrayFromHexDigest("c3fcd3d76192e4007dfb496cca67e13b")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfAlphabetLowerUpperNums) { + EXPECT_EQ( + CalculateMd5Digest( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), + Uint8ArrayFromHexDigest("d174ab98d277d9f5a5611c2c9f419d9f")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfDigits) { + EXPECT_EQ(CalculateMd5Digest("12345678901234567890123456789012345678901234567" + "890123456789012345678901234567890"), + Uint8ArrayFromHexDigest("57edf4a22be3c955ac49da2e2107b67a")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfTheQuickBrownFox) { + EXPECT_EQ(CalculateMd5Digest("the quick brown fox jumps over the lazy dog"), + Uint8ArrayFromHexDigest("77add1d5f41223d5582fca736a5cb335")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfShortStringWithAllChars) { + std::string s; + for (int i = 0; i < 512; ++i) { + s += static_cast(i); + } + EXPECT_EQ(CalculateMd5Digest(s), + Uint8ArrayFromHexDigest("f5c8e3c31c044bae0e65569560b54332")); +} + +TEST(CalculateMd5DigestTest, ShouldReturnMd5DigestOfLongStringWithAllChars) { + std::string s; + for (int i = 0; i < 8192; ++i) { + s += static_cast(i); + } + EXPECT_EQ(CalculateMd5Digest(s), + Uint8ArrayFromHexDigest("6556112372898c69e1de0bf689d8db26")); +} + +} // namespace diff --git a/Firestore/core/test/unit/util/testing_hooks_test.cc b/Firestore/core/test/unit/util/testing_hooks_test.cc index be7b9a2c8e6..0032e82fc15 100644 --- a/Firestore/core/test/unit/util/testing_hooks_test.cc +++ b/Firestore/core/test/unit/util/testing_hooks_test.cc @@ -52,6 +52,18 @@ class TestingHooksTest : public ::testing::Test, public AsyncTest { TestingHooks::ExistenceFilterMismatchInfo info = accumulator->Shift(); EXPECT_EQ(info.local_cache_count, expected.local_cache_count); EXPECT_EQ(info.existence_filter_count, expected.existence_filter_count); + EXPECT_EQ(info.bloom_filter.has_value(), expected.bloom_filter.has_value()); + if (info.bloom_filter.has_value() && expected.bloom_filter.has_value()) { + const TestingHooks::BloomFilterInfo& info_bloom_filter = + info.bloom_filter.value(); + const TestingHooks::BloomFilterInfo& expected_bloom_filter = + expected.bloom_filter.value(); + EXPECT_EQ(info_bloom_filter.applied, expected_bloom_filter.applied); + EXPECT_EQ(info_bloom_filter.hash_count, expected_bloom_filter.hash_count); + EXPECT_EQ(info_bloom_filter.bitmap_length, + expected_bloom_filter.bitmap_length); + EXPECT_EQ(info_bloom_filter.padding, expected_bloom_filter.padding); + } } std::future NotifyOnExistenceFilterMismatchAsync( @@ -74,10 +86,11 @@ TEST_F(TestingHooksTest, OnExistenceFilterMismatchCallbackShouldGetNotified) { TestingHooks::GetInstance().OnExistenceFilterMismatch( accumulator->AsCallback()); Defer unregister_listener([=] { listener_registration->Remove(); }); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; - NotifyOnExistenceFilterMismatchAsync({123, 456}); + NotifyOnExistenceFilterMismatchAsync({123, 456, bloom_filter_info}); - AssertAccumulatedObject(accumulator, {123, 456}); + AssertAccumulatedObject(accumulator, {123, 456, bloom_filter_info}); } TEST_F(TestingHooksTest, @@ -87,13 +100,14 @@ TEST_F(TestingHooksTest, TestingHooks::GetInstance().OnExistenceFilterMismatch( accumulator->AsCallback()); Defer unregister_listener([=] { listener_registration->Remove(); }); - - NotifyOnExistenceFilterMismatchAsync({111, 222}); - AssertAccumulatedObject(accumulator, {111, 222}); - NotifyOnExistenceFilterMismatchAsync({333, 444}); - AssertAccumulatedObject(accumulator, {333, 444}); - NotifyOnExistenceFilterMismatchAsync({555, 666}); - AssertAccumulatedObject(accumulator, {555, 666}); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; + + NotifyOnExistenceFilterMismatchAsync({111, 222, bloom_filter_info}); + AssertAccumulatedObject(accumulator, {111, 222, bloom_filter_info}); + NotifyOnExistenceFilterMismatchAsync({333, 444, bloom_filter_info}); + AssertAccumulatedObject(accumulator, {333, 444, bloom_filter_info}); + NotifyOnExistenceFilterMismatchAsync({555, 666, bloom_filter_info}); + AssertAccumulatedObject(accumulator, {555, 666, bloom_filter_info}); } TEST_F(TestingHooksTest, @@ -108,11 +122,12 @@ TEST_F(TestingHooksTest, TestingHooks::GetInstance().OnExistenceFilterMismatch( accumulator2->AsCallback()); Defer unregister_listener2([=] { listener_registration2->Remove(); }); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; - NotifyOnExistenceFilterMismatchAsync({123, 456}); + NotifyOnExistenceFilterMismatchAsync({123, 456, bloom_filter_info}); - AssertAccumulatedObject(accumulator1, {123, 456}); - AssertAccumulatedObject(accumulator2, {123, 456}); + AssertAccumulatedObject(accumulator1, {123, 456, bloom_filter_info}); + AssertAccumulatedObject(accumulator2, {123, 456, bloom_filter_info}); } TEST_F(TestingHooksTest, @@ -126,11 +141,12 @@ TEST_F(TestingHooksTest, TestingHooks::GetInstance().OnExistenceFilterMismatch( accumulator->AsCallback()); Defer unregister_listener2([=] { listener_registration1->Remove(); }); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; - NotifyOnExistenceFilterMismatchAsync({123, 456}); + NotifyOnExistenceFilterMismatchAsync({123, 456, bloom_filter_info}); - AssertAccumulatedObject(accumulator, {123, 456}); - AssertAccumulatedObject(accumulator, {123, 456}); + AssertAccumulatedObject(accumulator, {123, 456, bloom_filter_info}); + AssertAccumulatedObject(accumulator, {123, 456, bloom_filter_info}); std::this_thread::sleep_for(250ms); EXPECT_TRUE(accumulator->IsEmpty()); } @@ -142,8 +158,9 @@ TEST_F(TestingHooksTest, TestingHooks::GetInstance().OnExistenceFilterMismatch( accumulator->AsCallback()); registration->Remove(); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; - NotifyOnExistenceFilterMismatchAsync({123, 456}); + NotifyOnExistenceFilterMismatchAsync({123, 456, bloom_filter_info}); std::this_thread::sleep_for(250ms); EXPECT_TRUE(accumulator->IsEmpty()); @@ -165,13 +182,14 @@ TEST_F(TestingHooksTest, OnExistenceFilterMismatchRemoveShouldOnlyRemoveOne) { TestingHooks::GetInstance().OnExistenceFilterMismatch( accumulator3->AsCallback()); Defer unregister_listener3([=] { listener_registration3->Remove(); }); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; listener_registration2->Remove(); - NotifyOnExistenceFilterMismatchAsync({123, 456}); + NotifyOnExistenceFilterMismatchAsync({123, 456, bloom_filter_info}); - AssertAccumulatedObject(accumulator1, {123, 456}); - AssertAccumulatedObject(accumulator3, {123, 456}); + AssertAccumulatedObject(accumulator1, {123, 456, bloom_filter_info}); + AssertAccumulatedObject(accumulator3, {123, 456, bloom_filter_info}); std::this_thread::sleep_for(250ms); EXPECT_TRUE(accumulator2->IsEmpty()); } @@ -185,8 +203,9 @@ TEST_F(TestingHooksTest, OnExistenceFilterMismatchMultipleRemovesHaveNoEffect) { listener_registration->Remove(); listener_registration->Remove(); listener_registration->Remove(); + TestingHooks::BloomFilterInfo bloom_filter_info{true, 10, 11, 12}; - NotifyOnExistenceFilterMismatchAsync({123, 456}); + NotifyOnExistenceFilterMismatchAsync({123, 456, bloom_filter_info}); std::this_thread::sleep_for(250ms); EXPECT_TRUE(accumulator->IsEmpty());