Skip to content

Commit b61e698

Browse files
committed
Rework FieldMask to use a (ordered) set of FieldPaths
Rather than a vector. Port of firebase/firebase-android-sdk#137
1 parent 013565e commit b61e698

File tree

3 files changed

+30
-20
lines changed

3 files changed

+30
-20
lines changed

Firestore/core/src/firebase/firestore/model/field_mask.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <initializer_list>
2121
#include <string>
2222
#include <utility>
23-
#include <vector>
23+
#include <set>
2424

2525
#include "Firestore/core/src/firebase/firestore/model/field_path.h"
2626
#include "Firestore/core/src/firebase/firestore/util/hashing.h"
@@ -41,11 +41,14 @@ namespace model {
4141
*/
4242
class FieldMask {
4343
public:
44-
using const_iterator = std::vector<FieldPath>::const_iterator;
44+
using const_iterator = std::set<FieldPath>::const_iterator;
4545

4646
FieldMask(std::initializer_list<FieldPath> list) : fields_{list} {
4747
}
48-
explicit FieldMask(std::vector<FieldPath> fields)
48+
template<class InputIt>
49+
FieldMask(InputIt first, InputIt last) : fields_{first, last} {
50+
}
51+
explicit FieldMask(std::set<FieldPath> fields)
4952
: fields_{std::move(fields)} {
5053
}
5154

@@ -94,7 +97,7 @@ class FieldMask {
9497
friend bool operator==(const FieldMask& lhs, const FieldMask& rhs);
9598

9699
private:
97-
std::vector<FieldPath> fields_;
100+
std::set<FieldPath> fields_;
98101
};
99102

100103
inline bool operator==(const FieldMask& lhs, const FieldMask& rhs) {

Firestore/core/test/firebase/firestore/model/field_mask_test.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#include "Firestore/core/src/firebase/firestore/model/field_mask.h"
1818

19-
#include <vector>
19+
#include <set>
2020

2121
#include "Firestore/core/src/firebase/firestore/model/field_path.h"
2222
#include "gtest/gtest.h"
@@ -28,27 +28,30 @@ namespace model {
2828
TEST(FieldMask, ConstructorAndEqual) {
2929
FieldMask mask_a{FieldPath::FromServerFormat("foo"),
3030
FieldPath::FromServerFormat("bar")};
31-
std::vector<FieldPath> field_path_vector{FieldPath::FromServerFormat("foo"),
31+
std::set<FieldPath> field_path_set{FieldPath::FromServerFormat("foo"),
3232
FieldPath::FromServerFormat("bar")};
33-
FieldMask mask_b{field_path_vector};
34-
FieldMask mask_c{std::vector<FieldPath>{FieldPath::FromServerFormat("foo"),
33+
FieldMask mask_b{field_path_set};
34+
FieldMask mask_c{std::set<FieldPath>{FieldPath::FromServerFormat("foo"),
3535
FieldPath::FromServerFormat("bar")}};
36+
FieldMask mask_d{field_path_set.begin(), field_path_set.end()};
37+
3638
EXPECT_EQ(mask_a, mask_b);
3739
EXPECT_EQ(mask_b, mask_c);
40+
EXPECT_EQ(mask_c, mask_d);
3841
}
3942

4043
TEST(FieldMask, Getter) {
4144
FieldMask mask{FieldPath::FromServerFormat("foo"),
4245
FieldPath::FromServerFormat("bar")};
43-
EXPECT_EQ(std::vector<FieldPath>({FieldPath::FromServerFormat("foo"),
46+
EXPECT_EQ(std::set<FieldPath>({FieldPath::FromServerFormat("foo"),
4447
FieldPath::FromServerFormat("bar")}),
45-
std::vector<FieldPath>(mask.begin(), mask.end()));
48+
std::set<FieldPath>(mask.begin(), mask.end()));
4649
}
4750

4851
TEST(FieldMask, ToString) {
4952
FieldMask mask{FieldPath::FromServerFormat("foo"),
5053
FieldPath::FromServerFormat("bar")};
51-
EXPECT_EQ("{ foo bar }", mask.ToString());
54+
EXPECT_EQ("{ bar foo }", mask.ToString());
5255
}
5356

5457
} // namespace model

Firestore/core/test/firebase/firestore/testutil/testutil.cc

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,29 @@ std::unique_ptr<model::PatchMutation> PatchMutation(
2525
const model::ObjectValue::Map& values,
2626
const std::vector<model::FieldPath>* update_mask) {
2727
model::FieldValue object_value = model::FieldValue::FromMap({});
28-
std::vector<model::FieldPath> object_mask;
28+
std::set<model::FieldPath> object_mask;
2929

3030
for (const auto& kv : values) {
3131
model::FieldPath field_path = Field(kv.first);
32-
object_mask.push_back(field_path);
32+
object_mask.insert(field_path);
3333
if (kv.second.string_value() != kDeleteSentinel) {
3434
object_value = object_value.Set(field_path, kv.second);
3535
}
3636
}
3737

3838
bool merge = update_mask != nullptr;
3939

40-
// We sort the field_mask_paths to make the order deterministic in tests.
41-
std::sort(object_mask.begin(), object_mask.end());
42-
43-
return absl::make_unique<model::PatchMutation>(
44-
Key(path), std::move(object_value),
45-
model::FieldMask(merge ? *update_mask : object_mask),
46-
merge ? model::Precondition::None() : model::Precondition::Exists(true));
40+
if (merge) {
41+
return absl::make_unique<model::PatchMutation>(
42+
Key(path), std::move(object_value),
43+
model::FieldMask(update_mask->begin(), update_mask->end()),
44+
model::Precondition::None());
45+
} else {
46+
return absl::make_unique<model::PatchMutation>(
47+
Key(path), std::move(object_value),
48+
model::FieldMask(object_mask),
49+
model::Precondition::Exists(true));
50+
}
4751
}
4852

4953
} // namespace testutil

0 commit comments

Comments
 (0)