Skip to content

Commit 1348bd0

Browse files
author
nullccxsy
committed
fix: fix comments, optimize smart pointer usage in schema_test.cc to reduce copies and unify initialization
- Switched field_ and schema_ members in test classes to std::unique_ptr for unique ownership and to avoid duplicate and avoid creating duplicate objects.
1 parent c59216a commit 1348bd0

File tree

3 files changed

+73
-103
lines changed

3 files changed

+73
-103
lines changed

src/iceberg/schema.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@
2323
#include <format>
2424
#include <functional>
2525

26-
#include <iceberg/util/string_utils.h>
27-
2826
#include "iceberg/type.h"
2927
#include "iceberg/util/formatter.h" // IWYU pragma: keep
3028
#include "iceberg/util/macros.h"
29+
#include "iceberg/util/string_utils.h"
3130
#include "iceberg/util/visit_type.h"
3231

3332
namespace iceberg {
@@ -47,7 +46,7 @@ class IdToFieldVisitor {
4746
class NameToIdVisitor {
4847
public:
4948
explicit NameToIdVisitor(
50-
std::unordered_map<std::string, int32_t>& name_to_id, bool case_sensitive_ = true,
49+
std::unordered_map<std::string, int32_t>& name_to_id, bool case_sensitive = true,
5150
std::function<std::string(std::string_view)> quoting_func = {});
5251
Status Visit(const ListType& type, const std::string& path,
5352
const std::string& short_path);

src/iceberg/schema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class ICEBERG_EXPORT Schema : public StructType {
5555

5656
[[nodiscard]] std::string ToString() const override;
5757

58-
/// \brief Find thd SchemaField By field name
58+
/// \brief Find the SchemaField by field name.
5959
///
6060
/// Short names for maps and lists are included for any name that does not conflict with
6161
/// a canonical name. For example, a list, 'l', of structs with field 'x' will produce
@@ -67,6 +67,7 @@ class ICEBERG_EXPORT Schema : public StructType {
6767
[[nodiscard]] Result<std::optional<std::reference_wrapper<const SchemaField>>>
6868
FindFieldByName(std::string_view name, bool case_sensitive = true) const;
6969

70+
/// \brief Find the SchemaField by field id.
7071
[[nodiscard]] Result<std::optional<std::reference_wrapper<const SchemaField>>>
7172
FindFieldById(int32_t field_id) const;
7273

test/schema_test.cc

Lines changed: 69 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -89,30 +89,25 @@ class BasicShortNameTest : public ::testing::Test {
8989
field2_ = std::make_unique<iceberg::SchemaField>(2, "Bar", iceberg::string(), true);
9090
field3_ = std::make_unique<iceberg::SchemaField>(3, "Foobar", iceberg::int32(), true);
9191

92-
auto structtype = iceberg::StructType(
92+
auto structtype = std::make_shared<iceberg::StructType>(
9393
std::vector<iceberg::SchemaField>{*field1_, *field2_, *field3_});
9494

95-
auto listype = iceberg::ListType(iceberg::SchemaField::MakeRequired(
96-
4, "element", std::make_shared<iceberg::StructType>(structtype)));
95+
field4_ = std::make_unique<iceberg::SchemaField>(4, "element", structtype, false);
9796

98-
auto maptype =
99-
iceberg::MapType(iceberg::SchemaField::MakeRequired(5, "key", iceberg::int32()),
100-
iceberg::SchemaField::MakeRequired(
101-
6, "value", std::make_shared<iceberg::ListType>(listype)));
97+
auto listype = std::make_shared<iceberg::ListType>(*field4_);
10298

103-
field4_ = std::make_unique<iceberg::SchemaField>(
104-
4, "element", std::make_shared<iceberg::StructType>(structtype), false);
10599
field5_ = std::make_unique<iceberg::SchemaField>(5, "key", iceberg::int32(), false);
106-
field6_ = std::make_unique<iceberg::SchemaField>(
107-
6, "value", std::make_shared<iceberg::ListType>(listype), false);
108-
field7_ = std::make_unique<iceberg::SchemaField>(
109-
7, "Value", std::make_shared<iceberg::MapType>(maptype), false);
100+
field6_ = std::make_unique<iceberg::SchemaField>(6, "value", listype, false);
101+
102+
auto maptype = std::make_shared<iceberg::MapType>(*field5_, *field6_);
103+
104+
field7_ = std::make_unique<iceberg::SchemaField>(7, "Value", maptype, false);
110105

111106
schema_ =
112-
std::make_shared<iceberg::Schema>(std::vector<iceberg::SchemaField>{*field7_}, 1);
107+
std::make_unique<iceberg::Schema>(std::vector<iceberg::SchemaField>{*field7_}, 1);
113108
}
114109

115-
std::shared_ptr<iceberg::Schema> schema_;
110+
std::unique_ptr<iceberg::Schema> schema_;
116111
std::unique_ptr<iceberg::SchemaField> field1_;
117112
std::unique_ptr<iceberg::SchemaField> field2_;
118113
std::unique_ptr<iceberg::SchemaField> field3_;
@@ -187,38 +182,32 @@ class ComplexShortNameTest : public ::testing::Test {
187182
field2_ = std::make_unique<iceberg::SchemaField>(2, "Bar", iceberg::string(), true);
188183
field3_ = std::make_unique<iceberg::SchemaField>(3, "Foobar", iceberg::int32(), true);
189184

190-
auto structtype = iceberg::StructType({*field1_, *field2_, *field3_});
191-
192-
field4_ = std::make_unique<iceberg::SchemaField>(
193-
4, "element", std::make_shared<iceberg::StructType>(structtype), false);
194-
195-
auto listype = iceberg::ListType(*field4_);
185+
auto structtype = std::make_shared<iceberg::StructType>(
186+
std::vector<iceberg::SchemaField>{*field1_, *field2_, *field3_});
196187

197-
auto structtype2 = iceberg::StructType(
198-
{iceberg::SchemaField::MakeRequired(5, "First_child", iceberg::int32()),
199-
iceberg::SchemaField::MakeRequired(
200-
6, "Second_child", std::make_shared<iceberg::ListType>(listype))});
188+
field4_ = std::make_unique<iceberg::SchemaField>(4, "element", structtype, false);
201189

202-
auto maptype = iceberg::MapType(
203-
iceberg::SchemaField::MakeRequired(7, "key", iceberg::int32()),
204-
iceberg::SchemaField::MakeRequired(
205-
8, "value", std::make_shared<iceberg::StructType>(structtype2)));
190+
auto listype = std::make_shared<iceberg::ListType>(*field4_);
206191

207192
field5_ =
208193
std::make_unique<iceberg::SchemaField>(5, "First_child", iceberg::int32(), false);
209-
field6_ = std::make_unique<iceberg::SchemaField>(
210-
6, "Second_child", std::make_shared<iceberg::ListType>(listype), false);
194+
field6_ = std::make_unique<iceberg::SchemaField>(6, "Second_child", listype, false);
195+
196+
auto structtype2 = std::make_shared<iceberg::StructType>(
197+
std::vector<iceberg::SchemaField>{*field5_, *field6_});
198+
211199
field7_ = std::make_unique<iceberg::SchemaField>(7, "key", iceberg::int32(), false);
212-
field8_ = std::make_unique<iceberg::SchemaField>(
213-
8, "value", std::make_shared<iceberg::StructType>(structtype2), false);
214-
field9_ = std::make_unique<iceberg::SchemaField>(
215-
9, "Map", std::make_shared<iceberg::MapType>(maptype), false);
200+
field8_ = std::make_unique<iceberg::SchemaField>(8, "value", structtype2, false);
201+
202+
auto maptype = std::make_shared<iceberg::MapType>(*field7_, *field8_);
203+
204+
field9_ = std::make_unique<iceberg::SchemaField>(9, "Map", maptype, false);
216205

217206
schema_ =
218-
std::make_shared<iceberg::Schema>(std::vector<iceberg::SchemaField>{*field9_}, 1);
207+
std::make_unique<iceberg::Schema>(std::vector<iceberg::SchemaField>{*field9_}, 1);
219208
}
220209

221-
std::shared_ptr<iceberg::Schema> schema_;
210+
std::unique_ptr<iceberg::Schema> schema_;
222211
std::unique_ptr<iceberg::SchemaField> field1_;
223212
std::unique_ptr<iceberg::SchemaField> field2_;
224213
std::unique_ptr<iceberg::SchemaField> field3_;
@@ -317,75 +306,48 @@ TEST_F(ComplexShortNameTest, TestFindByShortNameCaseInsensitive) {
317306
class ComplexMapStructShortNameTest : public ::testing::Test {
318307
protected:
319308
void SetUp() override {
320-
// Separate inner struct for key: {inner_key: int, inner_value: int}
321-
inner_struct_type_key_ =
322-
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{
323-
iceberg::SchemaField(10, "inner_key", iceberg::int32(), false),
324-
iceberg::SchemaField(11, "inner_value", iceberg::int32(), false)});
325-
326309
exp_inner_key_key_ =
327310
std::make_unique<iceberg::SchemaField>(10, "inner_key", iceberg::int32(), false);
328311
exp_inner_key_value_ = std::make_unique<iceberg::SchemaField>(
329312
11, "inner_value", iceberg::int32(), false);
330-
331-
// Separate inner struct for value: {inner_k: int, inner_v: int}
332-
inner_struct_type_value_ =
333-
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{
334-
iceberg::SchemaField(12, "inner_k", iceberg::int32(), false),
335-
iceberg::SchemaField(13, "inner_v", iceberg::int32(), false)});
313+
auto inner_struct_type_key_ = std::make_shared<iceberg::StructType>(
314+
std::vector<iceberg::SchemaField>{*exp_inner_key_key_, *exp_inner_key_value_});
336315

337316
exp_inner_value_k_ =
338317
std::make_unique<iceberg::SchemaField>(12, "inner_k", iceberg::int32(), false);
339318
exp_inner_value_v_ =
340319
std::make_unique<iceberg::SchemaField>(13, "inner_v", iceberg::int32(), false);
341-
342-
// Key struct: {key: int, value: inner_struct_key_}
343-
key_struct_type_ =
344-
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{
345-
iceberg::SchemaField(14, "key", iceberg::int32(), false),
346-
iceberg::SchemaField(15, "value", inner_struct_type_key_, false)});
320+
auto inner_struct_type_value_ = std::make_shared<iceberg::StructType>(
321+
std::vector<iceberg::SchemaField>{*exp_inner_value_k_, *exp_inner_value_v_});
347322

348323
exp_key_struct_key_ =
349324
std::make_unique<iceberg::SchemaField>(14, "key", iceberg::int32(), false);
350325
exp_key_struct_value_ = std::make_unique<iceberg::SchemaField>(
351326
15, "value", inner_struct_type_key_, false);
352-
353-
// Value struct: {key: int, value: inner_struct_value_}
354-
value_struct_type_ =
355-
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{
356-
iceberg::SchemaField(16, "key", iceberg::int32(), false),
357-
iceberg::SchemaField(17, "value", inner_struct_type_value_, false)});
327+
auto key_struct_type_ = std::make_shared<iceberg::StructType>(
328+
std::vector<iceberg::SchemaField>{*exp_key_struct_key_, *exp_key_struct_value_});
358329

359330
exp_value_struct_key_ =
360331
std::make_unique<iceberg::SchemaField>(16, "key", iceberg::int32(), false);
361332
exp_value_struct_value_ = std::make_unique<iceberg::SchemaField>(
362333
17, "value", inner_struct_type_value_, false);
363-
364-
// Map type: map<key_struct, value_struct>
365-
map_type_ = std::make_shared<iceberg::MapType>(
366-
iceberg::SchemaField(18, "key", key_struct_type_, false),
367-
iceberg::SchemaField(19, "value", value_struct_type_, false));
334+
auto value_struct_type_ =
335+
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{
336+
*exp_value_struct_key_, *exp_value_struct_value_});
368337

369338
exp_map_key_ =
370339
std::make_unique<iceberg::SchemaField>(18, "key", key_struct_type_, false);
371340
exp_map_value_ =
372341
std::make_unique<iceberg::SchemaField>(19, "value", value_struct_type_, false);
342+
auto map_type_ = std::make_shared<iceberg::MapType>(*exp_map_key_, *exp_map_value_);
373343

374-
// Top-level field: a: map<...>
375344
exp_field_a_ = std::make_unique<iceberg::SchemaField>(20, "a", map_type_, false);
376345

377-
// Create schema
378-
schema_ = std::make_shared<iceberg::Schema>(
346+
schema_ = std::make_unique<iceberg::Schema>(
379347
std::vector<iceberg::SchemaField>{*exp_field_a_}, 1);
380348
}
381349

382-
std::shared_ptr<iceberg::Schema> schema_;
383-
std::shared_ptr<iceberg::StructType> inner_struct_type_key_;
384-
std::shared_ptr<iceberg::StructType> inner_struct_type_value_;
385-
std::shared_ptr<iceberg::StructType> key_struct_type_;
386-
std::shared_ptr<iceberg::StructType> value_struct_type_;
387-
std::shared_ptr<iceberg::MapType> map_type_;
388-
350+
std::unique_ptr<iceberg::Schema> schema_;
389351
std::unique_ptr<iceberg::SchemaField> exp_inner_key_key_;
390352
std::unique_ptr<iceberg::SchemaField> exp_inner_key_value_;
391353
std::unique_ptr<iceberg::SchemaField> exp_inner_value_k_;
@@ -470,29 +432,33 @@ TEST_F(ComplexMapStructShortNameTest, TestInvalidPaths) {
470432
}
471433

472434
TEST(SchemaTest, DuplicatePathErrorCaseSensitive) {
473-
iceberg::SchemaField nested_b(2, "b", iceberg::int32(), false);
474-
iceberg::StructType nested_struct({nested_b});
475-
iceberg::SchemaField a(1, "a", std::make_shared<iceberg::StructType>(nested_struct),
476-
false);
477-
iceberg::SchemaField duplicate_ab(3, "a.b", iceberg::int32(), false);
478-
iceberg::Schema schema({a, duplicate_ab}, 1);
479-
480-
auto result = schema.FindFieldByName("a.b", /*case_sensitive=*/true);
435+
auto nested_b = std::make_unique<iceberg::SchemaField>(2, "b", iceberg::int32(), false);
436+
auto nested_struct =
437+
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{*nested_b});
438+
auto a = std::make_unique<iceberg::SchemaField>(1, "a", nested_struct, false);
439+
auto duplicate_ab =
440+
std::make_unique<iceberg::SchemaField>(3, "a.b", iceberg::int32(), false);
441+
auto schema = std::make_unique<iceberg::Schema>(
442+
std::vector<iceberg::SchemaField>{*a, *duplicate_ab}, 1);
443+
444+
auto result = schema->FindFieldByName("a.b", /*case_sensitive=*/true);
481445
ASSERT_FALSE(result.has_value());
482446
EXPECT_EQ(result.error().kind, iceberg::ErrorKind::kInvalidSchema);
483447
EXPECT_THAT(result.error().message,
484448
::testing::HasSubstr("Duplicate path found: a.b, prev id: 2, curr id: 3"));
485449
}
486450

487451
TEST(SchemaTest, DuplicatePathErrorCaseInsensitive) {
488-
iceberg::SchemaField nested_b(2, "B", iceberg::int32(), false);
489-
iceberg::StructType nested_struct({nested_b});
490-
iceberg::SchemaField a(1, "A", std::make_shared<iceberg::StructType>(nested_struct),
491-
false);
492-
iceberg::SchemaField duplicate_ab(3, "a.b", iceberg::int32(), false);
493-
iceberg::Schema schema({a, duplicate_ab}, 1);
494-
495-
auto result = schema.FindFieldByName("A.B", /*case_sensitive=*/false);
452+
auto nested_b = std::make_unique<iceberg::SchemaField>(2, "B", iceberg::int32(), false);
453+
auto nested_struct =
454+
std::make_shared<iceberg::StructType>(std::vector<iceberg::SchemaField>{*nested_b});
455+
auto a = std::make_unique<iceberg::SchemaField>(1, "A", nested_struct, false);
456+
auto duplicate_ab =
457+
std::make_unique<iceberg::SchemaField>(3, "a.b", iceberg::int32(), false);
458+
auto schema = std::make_unique<iceberg::Schema>(
459+
std::vector<iceberg::SchemaField>{*a, *duplicate_ab}, 1);
460+
461+
auto result = schema->FindFieldByName("A.B", /*case_sensitive=*/false);
496462
ASSERT_FALSE(result.has_value());
497463
EXPECT_EQ(result.error().kind, iceberg::ErrorKind::kInvalidSchema);
498464
EXPECT_THAT(result.error().message,
@@ -501,21 +467,25 @@ TEST(SchemaTest, DuplicatePathErrorCaseInsensitive) {
501467

502468
TEST(SchemaTest, NestedDuplicateFieldIdError) {
503469
// Outer struct with field ID 1
504-
iceberg::SchemaField outer_field(1, "outer", iceberg::int32(), true);
470+
auto outer_field =
471+
std::make_unique<iceberg::SchemaField>(1, "outer", iceberg::int32(), true);
505472

506473
// Inner struct with duplicate field ID 1
507-
iceberg::SchemaField inner_field(1, "inner", iceberg::string(), true);
508-
auto inner_struct = iceberg::StructType({inner_field});
474+
auto inner_field =
475+
std::make_unique<iceberg::SchemaField>(1, "inner", iceberg::string(), true);
476+
auto inner_struct = std::make_shared<iceberg::StructType>(
477+
std::vector<iceberg::SchemaField>{*inner_field});
509478

510479
// Nested field with inner struct
511-
iceberg::SchemaField nested_field(
512-
2, "nested", std::make_shared<iceberg::StructType>(inner_struct), true);
480+
auto nested_field =
481+
std::make_unique<iceberg::SchemaField>(2, "nested", inner_struct, true);
513482

514483
// Schema with outer and nested fields
515-
iceberg::Schema schema({outer_field, nested_field}, 1);
484+
auto schema = std::make_unique<iceberg::Schema>(
485+
std::vector<iceberg::SchemaField>{*outer_field, *nested_field}, 1);
516486

517487
// Attempt to find a field, which should trigger duplicate ID detection
518-
auto result = schema.FindFieldById(1);
488+
auto result = schema->FindFieldById(1);
519489
ASSERT_FALSE(result.has_value());
520490
EXPECT_EQ(result.error().kind, iceberg::ErrorKind::kInvalidSchema);
521491
EXPECT_THAT(result.error().message,

0 commit comments

Comments
 (0)