Skip to content

Commit ee377d6

Browse files
Review #2
1 parent f51d4b0 commit ee377d6

File tree

3 files changed

+31
-23
lines changed

3 files changed

+31
-23
lines changed

Firestore/core/src/model/object_value.cc

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace model {
3232
namespace {
3333

3434
using nanopb::FieldsArray;
35-
using nanopb::FreeNanopbMessage;
35+
using nanopb::FreeFieldsArray;
3636
using nanopb::MakeArray;
3737
using nanopb::MakeBytesArray;
3838
using nanopb::MakeString;
@@ -73,7 +73,7 @@ google_firestore_v1_MapValue_FieldsEntry* FindEntry(
7373
}
7474

7575
size_t CalculateSizeOfUnion(
76-
google_firestore_v1_MapValue* map_value,
76+
const google_firestore_v1_MapValue& map_value,
7777
const std::map<std::string, google_firestore_v1_Value>& upserts,
7878
const std::set<std::string>& deletes) {
7979
// Compute the size of the map after applying all mutations. The final size is
@@ -104,7 +104,7 @@ void ApplyChanges(
104104
auto source_count = parent->fields_count;
105105
auto* source_fields = parent->fields;
106106

107-
size_t target_count = CalculateSizeOfUnion(parent, upserts, deletes);
107+
size_t target_count = CalculateSizeOfUnion(*parent, upserts, deletes);
108108
auto* target_fields =
109109
MakeArray<google_firestore_v1_MapValue_FieldsEntry>(target_count);
110110

@@ -115,24 +115,26 @@ void ApplyChanges(
115115
for (pb_size_t source_index = 0, target_index = 0;
116116
target_index < target_count;) {
117117
if (source_index < source_count) {
118-
std::string key = MakeString(source_fields[source_index].key);
118+
auto& source_entry = source_fields[source_index];
119+
auto& target_entry = target_fields[target_index];
120+
121+
std::string source_key = MakeString(source_entry.key);
119122

120123
// Check if the source key is deleted
121-
if (delete_it != deletes.end() && *delete_it == key) {
122-
FreeNanopbMessage(google_firestore_v1_MapValue_FieldsEntry_fields,
123-
source_fields + source_index);
124+
if (delete_it != deletes.end() && *delete_it == source_key) {
125+
FreeFieldsArray(&source_entry);
124126

125127
++delete_it;
126128
++source_index;
127129
continue;
128130
}
129131

130132
// Check if the source key is updated by the next upsert
131-
if (upsert_it != upserts.end() && upsert_it->first == key) {
132-
FreeNanopbMessage(google_firestore_v1_Value_fields,
133-
&source_fields[source_index].value);
134-
target_fields[target_index].key = source_fields[source_index].key;
135-
target_fields[target_index].value = DeepClone(upsert_it->second);
133+
if (upsert_it != upserts.end() && upsert_it->first == source_key) {
134+
FreeFieldsArray(&source_entry.value);
135+
136+
target_entry.key = source_entry.key;
137+
target_entry.value = DeepClone(upsert_it->second);
136138

137139
++upsert_it;
138140
++source_index;
@@ -141,8 +143,8 @@ void ApplyChanges(
141143
}
142144

143145
// Check if the source key comes before the next upsert
144-
if (upsert_it == upserts.end() || upsert_it->first > key) {
145-
target_fields[target_index] = source_fields[source_index];
146+
if (upsert_it == upserts.end() || upsert_it->first > source_key) {
147+
target_entry = source_entry;
146148

147149
++source_index;
148150
++target_index;
@@ -151,8 +153,8 @@ void ApplyChanges(
151153
}
152154

153155
// Otherwise, insert the next upsert.
154-
target_fields[target_index].key = MakeBytesArray(upsert_it->first);
155-
target_fields[target_index].value = DeepClone(upsert_it->second);
156+
target_entry.key = MakeBytesArray(upsert_it->first);
157+
target_entry.value = DeepClone(upsert_it->second);
156158

157159
++upsert_it;
158160
++target_index;
@@ -181,11 +183,11 @@ FieldMask MutableObjectValue::ExtractFieldMask(
181183

182184
for (size_t i = 0; i < value.fields_count; ++i) {
183185
const google_firestore_v1_MapValue_FieldsEntry& entry = value.fields[i];
184-
FieldPath current_path({MakeString(entry.key)});
186+
FieldPath current_path{MakeString(entry.key)};
185187

186188
if (entry.value.which_value_type !=
187189
google_firestore_v1_Value_map_value_tag) {
188-
fields.insert(std::move((current_path)));
190+
fields.insert(std::move(current_path));
189191
continue;
190192
}
191193

@@ -263,7 +265,7 @@ void MutableObjectValue::SetAll(const FieldMask& field_mask,
263265
}
264266

265267
void MutableObjectValue::Delete(const FieldPath& path) {
266-
HARD_ASSERT(!path.empty(), "Cannot set field for empty path on ObjectValue");
268+
HARD_ASSERT(!path.empty(), "Cannot delete field with empty path");
267269

268270
google_firestore_v1_Value* nested_value = value_.get();
269271
for (const std::string& segment : path.PopLast()) {
@@ -302,8 +304,7 @@ google_firestore_v1_MapValue* MutableObjectValue::ParentMap(
302304
google_firestore_v1_Value_map_value_tag) {
303305
// Since the element is not a map value, free all existing data and
304306
// change it to a map type.
305-
FreeNanopbMessage(FieldsArray<google_firestore_v1_Value>(),
306-
&entry->value);
307+
FreeFieldsArray(&entry->value);
307308
entry->value.which_value_type = google_firestore_v1_Value_map_value_tag;
308309
}
309310

Firestore/core/src/nanopb/fields_array.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ inline const pb_field_t* FieldsArray<google_protobuf_Empty>() {
157157
return google_protobuf_Empty_fields;
158158
}
159159

160+
template <typename T>
161+
void FreeFieldsArray(T* message) {
162+
FreeNanopbMessage(FieldsArray<T>(), message);
163+
}
164+
160165
} // namespace nanopb
161166
} // namespace firestore
162167
} // namespace firebase

Firestore/core/test/unit/model/value_util_test.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,15 @@ class ValueUtilTest : public ::testing::Test {
139139
[&] {
140140
nanopb::Message<google_firestore_v1_Value> clone2{DeepClone(value)};
141141
EXPECT_TRUE(value == *clone2)
142-
<< "Equality failed for '" << CanonicalId(value) << "' (before free)";
142+
<< "Equality failed for '" << CanonicalId(value) << "' and '"
143+
<< CanonicalId(*clone2) << "'";
143144
clone1 = nanopb::Message<google_firestore_v1_Value>{DeepClone(*clone2)};
144145
}();
145146

146147
// `clone2` is destroyed at this point, but `clone1` should be still valid.
147148
EXPECT_TRUE(value == *clone1)
148-
<< "Equality failed for '" << CanonicalId(value) << "' (after free)";
149+
<< "Equality failed for '" << CanonicalId(value) << "' and '"
150+
<< CanonicalId(*clone1) << "'";
149151
}
150152

151153
private:

0 commit comments

Comments
 (0)