Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

thread safe memoization #11781

Merged
merged 17 commits into from
Sep 13, 2023
14 changes: 14 additions & 0 deletions Firestore/Example/Firestore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
095A878BB33211AB52BFAD9F /* leveldb_document_overlay_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AE89CFF09C6804573841397F /* leveldb_document_overlay_cache_test.cc */; };
0963F6D7B0F9AE1E24B82866 /* path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 403DBF6EFB541DFD01582AA3 /* path_test.cc */; };
096BA3A3703AC1491F281618 /* index.pb.cc in Sources */ = {isa = PBXBuildFile; fileRef = 395E8B07639E69290A929695 /* index.pb.cc */; };
09B83B26E47B6F6668DF54B8 /* thread_safe_memoizer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */; };
09BE8C01EC33D1FD82262D5D /* aggregate_query_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AF924C79F49F793992A84879 /* aggregate_query_test.cc */; };
0A4E1B5E3E853763AE6ED7AE /* grpc_stream_tester.cc in Sources */ = {isa = PBXBuildFile; fileRef = 87553338E42B8ECA05BA987E /* grpc_stream_tester.cc */; };
0A52B47C43B7602EE64F53A7 /* cc_compilation_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1B342370EAE3AA02393E33EB /* cc_compilation_test.cc */; };
Expand Down Expand Up @@ -229,6 +230,7 @@
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 */; };
20A93AC59CD5A7AC41F10412 /* thread_safe_memoizer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */; };
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 */; };
Expand Down Expand Up @@ -500,6 +502,7 @@
50454F81EC4584D4EB5F5ED5 /* serializer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 61F72C5520BC48FD001A68CB /* serializer_test.cc */; };
50B749CA98365368AE34B71C /* filter_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = F02F734F272C3C70D1307076 /* filter_test.cc */; };
50C852E08626CFA7DC889EEA /* field_index_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = BF76A8DA34B5B67B4DD74666 /* field_index_test.cc */; };
51018EA27CF914DD1CC79CB3 /* thread_safe_memoizer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */; };
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 */; };
Expand Down Expand Up @@ -662,6 +665,7 @@
5B4391097A6DF86EC3801DEE /* string_win_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 79507DF8378D3C42F5B36268 /* string_win_test.cc */; };
5B62003FEA9A3818FDF4E2DD /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; };
5B89B1BA0AD400D9BF581420 /* listen_spec_test.json in Resources */ = {isa = PBXBuildFile; fileRef = 54DA12A01F315EE100DD57A1 /* listen_spec_test.json */; };
5BB33F0BC7960D26062B07D3 /* thread_safe_memoizer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */; };
5BC8406FD842B2FC2C200B2F /* stream_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 5B5414D28802BC76FDADABD6 /* stream_test.cc */; };
5BE49546D57C43DDFCDB6FBD /* to_string_apple_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = B68B1E002213A764008977EF /* to_string_apple_test.mm */; };
5C9B5696644675636A052018 /* token_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = A082AFDD981B07B5AD78FDE8 /* token_test.cc */; };
Expand Down Expand Up @@ -789,6 +793,7 @@
6D7F70938662E8CA334F11C2 /* target_cache_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5C37696557C81A6C2B7271A /* target_cache_test.cc */; };
6DBB3DB3FD6B4981B7F26A55 /* FIRQuerySnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04F202154AA00B64F25 /* FIRQuerySnapshotTests.mm */; };
6DCA8E54E652B78EFF3EEDAC /* XCTestCase+Await.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E0372021401E00B64F25 /* XCTestCase+Await.mm */; };
6DFD49CCE2281CE243FEBB63 /* thread_safe_memoizer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */; };
6E10507432E1D7AE658D16BD /* FSTSpecTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E03020213FFC00B64F25 /* FSTSpecTests.mm */; };
6E4854B19B120C6F0F8192CC /* FSTAPIHelpers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5492E04E202154AA00B64F25 /* FSTAPIHelpers.mm */; };
6E59498D20F55BA800ECD9A5 /* FuzzingResources in Resources */ = {isa = PBXBuildFile; fileRef = 6ED6DEA120F5502700FC6076 /* FuzzingResources */; };
Expand Down Expand Up @@ -1162,6 +1167,7 @@
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 */; };
B31B5E0D4EA72C5916CC71F5 /* thread_safe_memoizer_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */; };
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 */; };
Expand Down Expand Up @@ -1675,6 +1681,7 @@
132E32997D781B896672D30A /* reference_set_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reference_set_test.cc; sourceTree = "<group>"; };
166CE73C03AB4366AAC5201C /* leveldb_index_manager_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; path = leveldb_index_manager_test.cc; sourceTree = "<group>"; };
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 = "<group>"; };
1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */ = {isa = PBXFileReference; includeInIndex = 1; path = thread_safe_memoizer_test.cc; sourceTree = "<group>"; };
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 = "<group>"; };
1B9F95EC29FAD3F100EEC075 /* FIRAggregateQueryUnitTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FIRAggregateQueryUnitTests.mm; sourceTree = "<group>"; };
1C01D8CE367C56BB2624E299 /* index.pb.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = index.pb.h; path = admin/index.pb.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2361,6 +2368,7 @@
79507DF8378D3C42F5B36268 /* string_win_test.cc */,
899FC22684B0F7BEEAE13527 /* task_test.cc */,
A002425BC4FC4E805F4175B6 /* testing_hooks_test.cc */,
1A8141230C7E3986EACEF0B6 /* thread_safe_memoizer_test.cc */,
B68B1E002213A764008977EF /* to_string_apple_test.mm */,
B696858D2214B53900271095 /* to_string_test.cc */,
);
Expand Down Expand Up @@ -4260,6 +4268,7 @@
88929ED628DA8DD9592974ED /* task_test.cc in Sources */,
9B2C6A48A4DBD36080932B4E /* testing_hooks_test.cc in Sources */,
32A95242C56A1A230231DB6A /* testutil.cc in Sources */,
51018EA27CF914DD1CC79CB3 /* thread_safe_memoizer_test.cc in Sources */,
5497CB78229DECDE000FB92F /* time_testing.cc in Sources */,
ACC9369843F5ED3BD2284078 /* timestamp_test.cc in Sources */,
2AAEABFD550255271E3BAC91 /* to_string_apple_test.mm in Sources */,
Expand Down Expand Up @@ -4477,6 +4486,7 @@
67CF9FAA890307780731E1DA /* task_test.cc in Sources */,
24B75C63BDCD5551B2F69901 /* testing_hooks_test.cc in Sources */,
8388418F43042605FB9BFB92 /* testutil.cc in Sources */,
5BB33F0BC7960D26062B07D3 /* thread_safe_memoizer_test.cc in Sources */,
5497CB79229DECDE000FB92F /* time_testing.cc in Sources */,
26CB3D7C871BC56456C6021E /* timestamp_test.cc in Sources */,
5BE49546D57C43DDFCDB6FBD /* to_string_apple_test.mm in Sources */,
Expand Down Expand Up @@ -4715,6 +4725,7 @@
76A5447D76F060E996555109 /* task_test.cc in Sources */,
D0DA42DC66C4FE508A63B269 /* testing_hooks_test.cc in Sources */,
409C0F2BFC2E1BECFFAC4D32 /* testutil.cc in Sources */,
B31B5E0D4EA72C5916CC71F5 /* thread_safe_memoizer_test.cc in Sources */,
6300709ECDE8E0B5A8645F8D /* time_testing.cc in Sources */,
0CEE93636BA4852D3C5EC428 /* timestamp_test.cc in Sources */,
95DCD082374F871A86EF905F /* to_string_apple_test.mm in Sources */,
Expand Down Expand Up @@ -4953,6 +4964,7 @@
93C8F772F4DC5A985FA3D815 /* task_test.cc in Sources */,
F6738D3B72352BBEFB87172C /* testing_hooks_test.cc in Sources */,
A17DBC8F24127DA8A381F865 /* testutil.cc in Sources */,
09B83B26E47B6F6668DF54B8 /* thread_safe_memoizer_test.cc in Sources */,
A25FF76DEF542E01A2DF3B0E /* time_testing.cc in Sources */,
1E42CD0F60EB22A5D0C86D1F /* timestamp_test.cc in Sources */,
F9705E595FC3818F13F6375A /* to_string_apple_test.mm in Sources */,
Expand Down Expand Up @@ -5180,6 +5192,7 @@
662793139A36E5CFC935B949 /* task_test.cc in Sources */,
F184E5367DF3CA158EDE8532 /* testing_hooks_test.cc in Sources */,
54A0352A20A3B3BD003E0143 /* testutil.cc in Sources */,
20A93AC59CD5A7AC41F10412 /* thread_safe_memoizer_test.cc in Sources */,
5497CB77229DECDE000FB92F /* time_testing.cc in Sources */,
ABF6506C201131F8005F2C74 /* timestamp_test.cc in Sources */,
B68B1E012213A765008977EF /* to_string_apple_test.mm in Sources */,
Expand Down Expand Up @@ -5437,6 +5450,7 @@
C57B15CADD8C3E806B154C19 /* task_test.cc in Sources */,
5360D52DCAD1069B1E4B0B9D /* testing_hooks_test.cc in Sources */,
CA989C0E6020C372A62B7062 /* testutil.cc in Sources */,
6DFD49CCE2281CE243FEBB63 /* thread_safe_memoizer_test.cc in Sources */,
2D220B9ABFA36CD7AC43D0A7 /* time_testing.cc in Sources */,
D91D86B29B86A60C05879A48 /* timestamp_test.cc in Sources */,
60260A06871DCB1A5F3448D3 /* to_string_apple_test.mm in Sources */,
Expand Down
12 changes: 6 additions & 6 deletions Firestore/core/src/core/composite_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,14 @@ const model::FieldPath* CompositeFilter::Rep::GetFirstInequalityField() const {

const std::vector<FieldFilter>& CompositeFilter::Rep::GetFlattenedFilters()
const {
if (Filter::Rep::memoized_flattened_filters_.empty() && !filters().empty()) {
for (const auto& filter : filters()) {
return memoized_flattened_filters_->memoize([&]() {
dconeybe marked this conversation as resolved.
Show resolved Hide resolved
std::vector<FieldFilter> flattened_filters;
for (const auto& filter : filters())
std::copy(filter.GetFlattenedFilters().begin(),
filter.GetFlattenedFilters().end(),
std::back_inserter(Filter::Rep::memoized_flattened_filters_));
}
}
return Filter::Rep::memoized_flattened_filters_;
std::back_inserter(flattened_filters));
return flattened_filters;
});
}

} // namespace core
Expand Down
7 changes: 3 additions & 4 deletions Firestore/core/src/core/field_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,10 @@ FieldFilter::FieldFilter(std::shared_ptr<const Filter::Rep> rep)

const std::vector<FieldFilter>& FieldFilter::Rep::GetFlattenedFilters() const {
// This is already a field filter, so we return a vector of size one.
if (Filter::Rep::memoized_flattened_filters_.empty()) {
Filter::Rep::memoized_flattened_filters_ = std::vector<FieldFilter>{
return memoized_flattened_filters_->memoize([&]() {
return std::vector<FieldFilter>{
FieldFilter(std::make_shared<const Rep>(*this))};
}
return Filter::Rep::memoized_flattened_filters_;
});
}

std::vector<Filter> FieldFilter::Rep::GetFilters() const {
Expand Down
9 changes: 9 additions & 0 deletions Firestore/core/src/core/filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

#include <ostream>

#include "Firestore/core/src/core/field_filter.h"
#include "Firestore/core/src/util/thread_safe_memoizer.h"

namespace firebase {
namespace firestore {
namespace core {
Expand All @@ -32,6 +35,12 @@ std::ostream& operator<<(std::ostream& os, const Filter& filter) {
return os << filter.ToString();
}

Filter::Rep::Rep()
milaGGL marked this conversation as resolved.
Show resolved Hide resolved
: memoized_flattened_filters_(
std::make_shared<
util::ThreadSafeMemoizer<std::vector<FieldFilter>>>()) {
}

} // namespace core
} // namespace firestore
} // namespace firebase
12 changes: 10 additions & 2 deletions Firestore/core/src/core/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
#include <vector>

#include "Firestore/core/src/model/model_fwd.h"
#include "Firestore/core/src/util/thread_safe_memoizer.h"

namespace firebase {
namespace firestore {

namespace core {

class FieldFilter;
Expand Down Expand Up @@ -122,6 +122,8 @@ class Filter {
protected:
class Rep {
public:
Rep();

virtual ~Rep() = default;

virtual Type type() const {
Expand Down Expand Up @@ -162,8 +164,14 @@ class Filter {
/**
* Memoized list of all field filters that can be found by
* traversing the tree of filters contained in this composite filter.
*
* Use a `std::shared_ptr<ThreadSafeMemoizer>` rather than using
* `ThreadSafeMemoizer` directly so that this class is copyable
* (`ThreadSafeMemoizer` is not copyable because of its `std::once_flag`
* member variable, which is not copyable).
*/
mutable std::vector<FieldFilter> memoized_flattened_filters_;
mutable std::shared_ptr<util::ThreadSafeMemoizer<std::vector<FieldFilter>>>
memoized_flattened_filters_;
};

explicit Filter(std::shared_ptr<const Rep>&& rep) : rep_(rep) {
Expand Down
41 changes: 16 additions & 25 deletions Firestore/core/src/core/query.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,21 @@ absl::optional<Operator> Query::FindOpInsideFilters(
}

const std::vector<OrderBy>& Query::normalized_order_bys() const {
if (memoized_normalized_order_bys_.empty()) {
return memoized_normalized_order_bys_->memoize([&]() {
std::vector<OrderBy> result;
const FieldPath* inequality_field = InequalityFilterField();
const FieldPath* first_order_by_field = FirstOrderByField();

if (inequality_field && !first_order_by_field) {
// In order to implicitly add key ordering, we must also add the
// inequality filter field for it to be a valid query. Note that the
// default inequality field and key ordering is ascending.
if (inequality_field->IsKeyFieldPath()) {
memoized_normalized_order_bys_ = {
result = {
OrderBy(FieldPath::KeyFieldPath(), Direction::Ascending),
};
} else {
memoized_normalized_order_bys_ = {
result = {
OrderBy(*inequality_field, Direction::Ascending),
OrderBy(FieldPath::KeyFieldPath(), Direction::Ascending),
};
Expand All @@ -114,8 +116,7 @@ const std::vector<OrderBy>& Query::normalized_order_bys() const {
first_order_by_field->CanonicalString(),
inequality_field->CanonicalString());

std::vector<OrderBy> result = explicit_order_bys_;

result = explicit_order_bys_;
bool found_explicit_key_order = false;
for (const OrderBy& order_by : explicit_order_bys_) {
if (order_by.field().IsKeyFieldPath()) {
Expand All @@ -132,11 +133,10 @@ const std::vector<OrderBy>& Query::normalized_order_bys() const {
: explicit_order_bys_.back().direction();
result.emplace_back(FieldPath::KeyFieldPath(), last_direction);
}

memoized_normalized_order_bys_ = std::move(result);
}
}
return memoized_normalized_order_bys_;

return result;
});
}

const FieldPath* Query::FirstOrderByField() const {
Expand Down Expand Up @@ -329,23 +329,16 @@ std::string Query::ToString() const {
}

const Target& Query::ToTarget() const& {
if (memoized_target == nullptr) {
memoized_target = ToTarget(normalized_order_bys());
}

return *memoized_target;
return memoized_target_->memoize(
[&]() { return ToTarget(normalized_order_bys()); });
}

const Target& Query::ToAggregateTarget() const& {
if (memoized_aggregate_target == nullptr) {
memoized_aggregate_target = ToTarget(explicit_order_bys_);
}

return *memoized_aggregate_target;
return memoized_aggregate_target_->memoize(
[&]() { return ToTarget(explicit_order_bys_); });
}

const std::shared_ptr<const Target> Query::ToTarget(
const std::vector<OrderBy>& order_bys) const& {
Target Query::ToTarget(const std::vector<OrderBy>& order_bys) const {
if (limit_type_ == LimitType::Last) {
// Flip the orderBy directions since we want the last results
std::vector<OrderBy> new_order_bys;
Expand All @@ -366,13 +359,11 @@ const std::shared_ptr<const Target> Query::ToTarget(
start_at_->position(), start_at_->inclusive())}
: absl::nullopt;

Target target(path(), collection_group(), filters(), new_order_bys, limit_,
return Target(path(), collection_group(), filters(), new_order_bys, limit_,
new_start_at, new_end_at);
return std::make_shared<Target>(std::move(target));
} else {
Target target(path(), collection_group(), filters(), order_bys, limit_,
return Target(path(), collection_group(), filters(), order_bys, limit_,
start_at(), end_at());
return std::make_shared<Target>(std::move(target));
}
}

Expand Down
Loading
Loading