From bc704b5bf4a76d4b3f1f7cdb371fccf52a6e2930 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 18 Nov 2025 10:50:58 +0800 Subject: [PATCH 01/15] feat: add Map suffix for cpp index & ordered index --- .../index/index.go | 18 ++++++------- .../orderedindex/ordered_index.go | 16 ++++++------ .../src/protoconf/item_conf.pc.cc | 24 +++++++++--------- .../src/protoconf/item_conf.pc.h | 25 +++++++++---------- .../src/protoconf/test_conf.pc.cc | 18 ++++++------- .../src/protoconf/test_conf.pc.h | 20 +++++++-------- 6 files changed, 56 insertions(+), 65 deletions(-) diff --git a/cmd/protoc-gen-cpp-tableau-loader/index/index.go b/cmd/protoc-gen-cpp-tableau-loader/index/index.go index 14f4562a..15863b93 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/index/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/index/index.go @@ -3,6 +3,7 @@ package index import ( "fmt" "strings" + "sync" "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" @@ -88,10 +89,11 @@ func (x *Generator) GenHppIndexFinders() { if !x.NeedGenerate() { return } - x.g.P() - x.g.P(helper.Indent(1), "// Index accessers.") + var once sync.Once for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { + x.g.P() + once.Do(func() { x.g.P(helper.Indent(1), "// Index accessers.") }) x.g.P(helper.Indent(1), "// Index: ", index.Index) x.g.P(" public:") mapType := x.mapType(index) @@ -113,12 +115,7 @@ func (x *Generator) GenHppIndexFinders() { x.g.P(helper.Indent(2), "bool operator==(const ", keyType, "& other) const = default;") x.g.P("#else") x.g.P(helper.Indent(2), "bool operator==(const ", keyType, "& other) const {") - if len(keys) == 1 { - x.g.P(helper.Indent(3), "return ", keys[0].Name, " == other.", keys[0].Name, ";") - } else { - x.g.P(helper.Indent(3), "return std::tie(", keys.GenGetArguments(), ") == std::tie(", keys.GenOtherArguments("other"), ");") - } - // x.g.P(helper.Indent(3), "return ", strings.Join(equalities, " && "), ";") + x.g.P(helper.Indent(3), "return std::tie(", keys.GenGetArguments(), ") == std::tie(", keys.GenOtherArguments("other"), ");") x.g.P(helper.Indent(2), "}") x.g.P("#endif") x.g.P(helper.Indent(1), "};") @@ -134,7 +131,7 @@ func (x *Generator) GenHppIndexFinders() { x.g.P(helper.Indent(1), "using ", mapType, " = std::unordered_map<", keyType, ", ", vectorType, hasher, ">;") x.g.P(helper.Indent(1), "// Finds the index (", index.Index, ") to value (", vectorType, ") hash map.") x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") - x.g.P(helper.Indent(1), "const ", mapType, "& Find", index.Name(), "() const;") + x.g.P(helper.Indent(1), "const ", mapType, "& Find", index.Name(), "Map() const;") x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s).") x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") @@ -142,7 +139,6 @@ func (x *Generator) GenHppIndexFinders() { x.g.P() x.g.P(" private:") x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index), ";") - x.g.P() } } } @@ -277,7 +273,7 @@ func (x *Generator) GenCppIndexFinders() { messagerName := x.messagerName() x.g.P("// Index: ", index.Index) - x.g.P("const ", messagerName, "::", mapType, "& ", messagerName, "::Find", index.Name(), "() const { return ", indexContainerName, " ;}") + x.g.P("const ", messagerName, "::", mapType, "& ", messagerName, "::Find", index.Name(), "Map() const { return ", indexContainerName, " ;}") x.g.P() keys := x.indexKeys(index) diff --git a/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go index 7650a389..5600e7e2 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go @@ -3,6 +3,7 @@ package orderedindex import ( "fmt" "strings" + "sync" "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" @@ -95,9 +96,11 @@ func (x *Generator) GenHppOrderedIndexFinders() { if !x.NeedGenerate() { return } - x.g.P(helper.Indent(1), "// OrderedIndex accessers.") + var once sync.Once for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { + x.g.P() + once.Do(func() { x.g.P(helper.Indent(1), "// OrderedIndex accessers.") }) x.g.P(helper.Indent(1), "// OrderedIndex: ", index.Index) x.g.P(" public:") mapType := x.mapType(index) @@ -116,11 +119,7 @@ func (x *Generator) GenHppOrderedIndexFinders() { x.g.P(helper.Indent(2), "auto operator<=>(const ", keyType, "& other) const = default;") x.g.P("#else") x.g.P(helper.Indent(2), "bool operator<(const ", keyType, "& other) const {") - if len(keys) == 1 { - x.g.P(helper.Indent(3), "return ", keys[0].Name, " < other.", keys[0].Name, ";") - } else { - x.g.P(helper.Indent(3), "return std::tie(", keys.GenGetArguments(), ") < std::tie(", keys.GenOtherArguments("other"), ");") - } + x.g.P(helper.Indent(3), "return std::tie(", keys.GenGetArguments(), ") < std::tie(", keys.GenOtherArguments("other"), ");") x.g.P(helper.Indent(2), "}") x.g.P("#endif") x.g.P(helper.Indent(1), "};") @@ -129,7 +128,7 @@ func (x *Generator) GenHppOrderedIndexFinders() { x.g.P(helper.Indent(1), "using ", mapType, " = std::map<", keyType, ", ", vectorType, ">;") x.g.P(helper.Indent(1), "// Finds the ordered index (", index.Index, ") to value (", vectorType, ") map.") x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") - x.g.P(helper.Indent(1), "const ", mapType, "& Find", index.Name(), "() const;") + x.g.P(helper.Indent(1), "const ", mapType, "& Find", index.Name(), "Map() const;") x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s).") x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") @@ -138,7 +137,6 @@ func (x *Generator) GenHppOrderedIndexFinders() { x.g.P(" private:") x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index), ";") - x.g.P() } } } @@ -274,7 +272,7 @@ func (x *Generator) GenCppOrderedIndexFinders() { messagerName := x.messagerName() x.g.P("// OrderedIndex: ", index.Index) - x.g.P("const ", messagerName, "::", mapType, "& ", messagerName, "::Find", index.Name(), "() const { return ", indexContainerName, " ;}") + x.g.P("const ", messagerName, "::", mapType, "& ", messagerName, "::Find", index.Name(), "Map() const { return ", indexContainerName, " ;}") x.g.P() keys := x.indexKeys(index) diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index 2e3ceff6..15fee8e3 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -151,7 +151,7 @@ const ItemConf::OrderedMap_ItemMap* ItemConf::GetOrderedMap() const { } // Index: Type -const ItemConf::Index_ItemMap& ItemConf::FindItem() const { return index_item_map_ ;} +const ItemConf::Index_ItemMap& ItemConf::FindItemMap() const { return index_item_map_ ;} const ItemConf::Index_ItemVector* ItemConf::FindItem(protoconf::FruitType type) const { auto iter = index_item_map_.find(type); @@ -170,7 +170,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItem(protoconf::FruitType ty } // Index: Param@ItemInfo -const ItemConf::Index_ItemInfoMap& ItemConf::FindItemInfo() const { return index_item_info_map_ ;} +const ItemConf::Index_ItemInfoMap& ItemConf::FindItemInfoMap() const { return index_item_info_map_ ;} const ItemConf::Index_ItemInfoVector* ItemConf::FindItemInfo(int32_t param) const { auto iter = index_item_info_map_.find(param); @@ -189,7 +189,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItemInfo(int32_t param) cons } // Index: Default@ItemDefaultInfo -const ItemConf::Index_ItemDefaultInfoMap& ItemConf::FindItemDefaultInfo() const { return index_item_default_info_map_ ;} +const ItemConf::Index_ItemDefaultInfoMap& ItemConf::FindItemDefaultInfoMap() const { return index_item_default_info_map_ ;} const ItemConf::Index_ItemDefaultInfoVector* ItemConf::FindItemDefaultInfo(const std::string& default_) const { auto iter = index_item_default_info_map_.find(default_); @@ -208,7 +208,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItemDefaultInfo(const std::s } // Index: ExtType@ItemExtInfo -const ItemConf::Index_ItemExtInfoMap& ItemConf::FindItemExtInfo() const { return index_item_ext_info_map_ ;} +const ItemConf::Index_ItemExtInfoMap& ItemConf::FindItemExtInfoMap() const { return index_item_ext_info_map_ ;} const ItemConf::Index_ItemExtInfoVector* ItemConf::FindItemExtInfo(protoconf::FruitType ext_type) const { auto iter = index_item_ext_info_map_.find(ext_type); @@ -227,7 +227,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItemExtInfo(protoconf::Fruit } // Index: (ID,Name)@AwardItem -const ItemConf::Index_AwardItemMap& ItemConf::FindAwardItem() const { return index_award_item_map_ ;} +const ItemConf::Index_AwardItemMap& ItemConf::FindAwardItemMap() const { return index_award_item_map_ ;} const ItemConf::Index_AwardItemVector* ItemConf::FindAwardItem(uint32_t id, const std::string& name) const { auto iter = index_award_item_map_.find({id, name}); @@ -246,7 +246,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstAwardItem(uint32_t id, const } // Index: (ID,Type,Param,ExtType)@SpecialItem -const ItemConf::Index_SpecialItemMap& ItemConf::FindSpecialItem() const { return index_special_item_map_ ;} +const ItemConf::Index_SpecialItemMap& ItemConf::FindSpecialItemMap() const { return index_special_item_map_ ;} const ItemConf::Index_SpecialItemVector* ItemConf::FindSpecialItem(uint32_t id, protoconf::FruitType type, int32_t param, protoconf::FruitType ext_type) const { auto iter = index_special_item_map_.find({id, type, param, ext_type}); @@ -265,7 +265,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstSpecialItem(uint32_t id, pro } // Index: PathDir@ItemPathDir -const ItemConf::Index_ItemPathDirMap& ItemConf::FindItemPathDir() const { return index_item_path_dir_map_ ;} +const ItemConf::Index_ItemPathDirMap& ItemConf::FindItemPathDirMap() const { return index_item_path_dir_map_ ;} const ItemConf::Index_ItemPathDirVector* ItemConf::FindItemPathDir(const std::string& dir) const { auto iter = index_item_path_dir_map_.find(dir); @@ -284,7 +284,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItemPathDir(const std::strin } // Index: PathName@ItemPathName -const ItemConf::Index_ItemPathNameMap& ItemConf::FindItemPathName() const { return index_item_path_name_map_ ;} +const ItemConf::Index_ItemPathNameMap& ItemConf::FindItemPathNameMap() const { return index_item_path_name_map_ ;} const ItemConf::Index_ItemPathNameVector* ItemConf::FindItemPathName(const std::string& name) const { auto iter = index_item_path_name_map_.find(name); @@ -303,7 +303,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItemPathName(const std::stri } // Index: PathFriendID@ItemPathFriendID -const ItemConf::Index_ItemPathFriendIDMap& ItemConf::FindItemPathFriendID() const { return index_item_path_friend_id_map_ ;} +const ItemConf::Index_ItemPathFriendIDMap& ItemConf::FindItemPathFriendIDMap() const { return index_item_path_friend_id_map_ ;} const ItemConf::Index_ItemPathFriendIDVector* ItemConf::FindItemPathFriendID(uint32_t id) const { auto iter = index_item_path_friend_id_map_.find(id); @@ -322,7 +322,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstItemPathFriendID(uint32_t id } // Index: UseEffectType@UseEffectType -const ItemConf::Index_UseEffectTypeMap& ItemConf::FindUseEffectType() const { return index_use_effect_type_map_ ;} +const ItemConf::Index_UseEffectTypeMap& ItemConf::FindUseEffectTypeMap() const { return index_use_effect_type_map_ ;} const ItemConf::Index_UseEffectTypeVector* ItemConf::FindUseEffectType(protoconf::UseEffect::Type type) const { auto iter = index_use_effect_type_map_.find(type); @@ -341,7 +341,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstUseEffectType(protoconf::Use } // OrderedIndex: ExtType@ExtType -const ItemConf::OrderedIndex_ExtTypeMap& ItemConf::FindExtType() const { return ordered_index_ext_type_map_ ;} +const ItemConf::OrderedIndex_ExtTypeMap& ItemConf::FindExtTypeMap() const { return ordered_index_ext_type_map_ ;} const ItemConf::OrderedIndex_ExtTypeVector* ItemConf::FindExtType(protoconf::FruitType ext_type) const { auto iter = ordered_index_ext_type_map_.find(ext_type); @@ -360,7 +360,7 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstExtType(protoconf::FruitType } // OrderedIndex: (Param,ExtType)@ParamExtType -const ItemConf::OrderedIndex_ParamExtTypeMap& ItemConf::FindParamExtType() const { return ordered_index_param_ext_type_map_ ;} +const ItemConf::OrderedIndex_ParamExtTypeMap& ItemConf::FindParamExtTypeMap() const { return ordered_index_param_ext_type_map_ ;} const ItemConf::OrderedIndex_ParamExtTypeVector* ItemConf::FindParamExtType(int32_t param, protoconf::FruitType ext_type) const { auto iter = ordered_index_param_ext_type_map_.find({param, ext_type}); diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index 56d1bff8..a7353b6d 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -45,7 +45,7 @@ class ItemConf : public Messager { using Index_ItemMap = std::unordered_map; // Finds the index (Type) to value (Index_ItemVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemMap& FindItem() const; + const Index_ItemMap& FindItemMap() const; // Finds a vector of all values of the given key(s). const Index_ItemVector* FindItem(protoconf::FruitType type) const; // Finds the first value of the given key(s). @@ -60,7 +60,7 @@ class ItemConf : public Messager { using Index_ItemInfoMap = std::unordered_map; // Finds the index (Param@ItemInfo) to value (Index_ItemInfoVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemInfoMap& FindItemInfo() const; + const Index_ItemInfoMap& FindItemInfoMap() const; // Finds a vector of all values of the given key(s). const Index_ItemInfoVector* FindItemInfo(int32_t param) const; // Finds the first value of the given key(s). @@ -75,7 +75,7 @@ class ItemConf : public Messager { using Index_ItemDefaultInfoMap = std::unordered_map; // Finds the index (Default@ItemDefaultInfo) to value (Index_ItemDefaultInfoVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemDefaultInfoMap& FindItemDefaultInfo() const; + const Index_ItemDefaultInfoMap& FindItemDefaultInfoMap() const; // Finds a vector of all values of the given key(s). const Index_ItemDefaultInfoVector* FindItemDefaultInfo(const std::string& default_) const; // Finds the first value of the given key(s). @@ -90,7 +90,7 @@ class ItemConf : public Messager { using Index_ItemExtInfoMap = std::unordered_map; // Finds the index (ExtType@ItemExtInfo) to value (Index_ItemExtInfoVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemExtInfoMap& FindItemExtInfo() const; + const Index_ItemExtInfoMap& FindItemExtInfoMap() const; // Finds a vector of all values of the given key(s). const Index_ItemExtInfoVector* FindItemExtInfo(protoconf::FruitType ext_type) const; // Finds the first value of the given key(s). @@ -121,7 +121,7 @@ class ItemConf : public Messager { using Index_AwardItemMap = std::unordered_map; // Finds the index ((ID,Name)@AwardItem) to value (Index_AwardItemVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_AwardItemMap& FindAwardItem() const; + const Index_AwardItemMap& FindAwardItemMap() const; // Finds a vector of all values of the given key(s). const Index_AwardItemVector* FindAwardItem(uint32_t id, const std::string& name) const; // Finds the first value of the given key(s). @@ -154,7 +154,7 @@ class ItemConf : public Messager { using Index_SpecialItemMap = std::unordered_map; // Finds the index ((ID,Type,Param,ExtType)@SpecialItem) to value (Index_SpecialItemVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_SpecialItemMap& FindSpecialItem() const; + const Index_SpecialItemMap& FindSpecialItemMap() const; // Finds a vector of all values of the given key(s). const Index_SpecialItemVector* FindSpecialItem(uint32_t id, protoconf::FruitType type, int32_t param, protoconf::FruitType ext_type) const; // Finds the first value of the given key(s). @@ -169,7 +169,7 @@ class ItemConf : public Messager { using Index_ItemPathDirMap = std::unordered_map; // Finds the index (PathDir@ItemPathDir) to value (Index_ItemPathDirVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemPathDirMap& FindItemPathDir() const; + const Index_ItemPathDirMap& FindItemPathDirMap() const; // Finds a vector of all values of the given key(s). const Index_ItemPathDirVector* FindItemPathDir(const std::string& dir) const; // Finds the first value of the given key(s). @@ -184,7 +184,7 @@ class ItemConf : public Messager { using Index_ItemPathNameMap = std::unordered_map; // Finds the index (PathName@ItemPathName) to value (Index_ItemPathNameVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemPathNameMap& FindItemPathName() const; + const Index_ItemPathNameMap& FindItemPathNameMap() const; // Finds a vector of all values of the given key(s). const Index_ItemPathNameVector* FindItemPathName(const std::string& name) const; // Finds the first value of the given key(s). @@ -199,7 +199,7 @@ class ItemConf : public Messager { using Index_ItemPathFriendIDMap = std::unordered_map; // Finds the index (PathFriendID@ItemPathFriendID) to value (Index_ItemPathFriendIDVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ItemPathFriendIDMap& FindItemPathFriendID() const; + const Index_ItemPathFriendIDMap& FindItemPathFriendIDMap() const; // Finds a vector of all values of the given key(s). const Index_ItemPathFriendIDVector* FindItemPathFriendID(uint32_t id) const; // Finds the first value of the given key(s). @@ -214,7 +214,7 @@ class ItemConf : public Messager { using Index_UseEffectTypeMap = std::unordered_map; // Finds the index (UseEffectType@UseEffectType) to value (Index_UseEffectTypeVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_UseEffectTypeMap& FindUseEffectType() const; + const Index_UseEffectTypeMap& FindUseEffectTypeMap() const; // Finds a vector of all values of the given key(s). const Index_UseEffectTypeVector* FindUseEffectType(protoconf::UseEffect::Type type) const; // Finds the first value of the given key(s). @@ -230,7 +230,7 @@ class ItemConf : public Messager { using OrderedIndex_ExtTypeMap = std::map; // Finds the ordered index (ExtType@ExtType) to value (OrderedIndex_ExtTypeVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ExtTypeMap& FindExtType() const; + const OrderedIndex_ExtTypeMap& FindExtTypeMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ExtTypeVector* FindExtType(protoconf::FruitType ext_type) const; // Finds the first value of the given key(s). @@ -256,7 +256,7 @@ class ItemConf : public Messager { using OrderedIndex_ParamExtTypeMap = std::map; // Finds the ordered index ((Param,ExtType)@ParamExtType) to value (OrderedIndex_ParamExtTypeVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ParamExtTypeMap& FindParamExtType() const; + const OrderedIndex_ParamExtTypeMap& FindParamExtTypeMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ParamExtTypeVector* FindParamExtType(int32_t param, protoconf::FruitType ext_type) const; // Finds the first value of the given key(s). @@ -264,7 +264,6 @@ class ItemConf : public Messager { private: OrderedIndex_ParamExtTypeMap ordered_index_param_ext_type_map_; - }; } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc index 1018fd65..2bf19eee 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc @@ -162,7 +162,7 @@ const ActivityConf::OrderedMap_int32Map* ActivityConf::GetOrderedMap(uint64_t ac } // Index: ActivityName -const ActivityConf::Index_ActivityMap& ActivityConf::FindActivity() const { return index_activity_map_ ;} +const ActivityConf::Index_ActivityMap& ActivityConf::FindActivityMap() const { return index_activity_map_ ;} const ActivityConf::Index_ActivityVector* ActivityConf::FindActivity(const std::string& activity_name) const { auto iter = index_activity_map_.find(activity_name); @@ -181,7 +181,7 @@ const protoconf::ActivityConf::Activity* ActivityConf::FindFirstActivity(const s } // Index: ChapterID -const ActivityConf::Index_ChapterMap& ActivityConf::FindChapter() const { return index_chapter_map_ ;} +const ActivityConf::Index_ChapterMap& ActivityConf::FindChapterMap() const { return index_chapter_map_ ;} const ActivityConf::Index_ChapterVector* ActivityConf::FindChapter(uint32_t chapter_id) const { auto iter = index_chapter_map_.find(chapter_id); @@ -200,7 +200,7 @@ const protoconf::ActivityConf::Activity::Chapter* ActivityConf::FindFirstChapter } // Index: ChapterName@NamedChapter -const ActivityConf::Index_NamedChapterMap& ActivityConf::FindNamedChapter() const { return index_named_chapter_map_ ;} +const ActivityConf::Index_NamedChapterMap& ActivityConf::FindNamedChapterMap() const { return index_named_chapter_map_ ;} const ActivityConf::Index_NamedChapterVector* ActivityConf::FindNamedChapter(const std::string& chapter_name) const { auto iter = index_named_chapter_map_.find(chapter_name); @@ -219,7 +219,7 @@ const protoconf::ActivityConf::Activity::Chapter* ActivityConf::FindFirstNamedCh } // Index: SectionItemID@Award -const ActivityConf::Index_AwardMap& ActivityConf::FindAward() const { return index_award_map_ ;} +const ActivityConf::Index_AwardMap& ActivityConf::FindAwardMap() const { return index_award_map_ ;} const ActivityConf::Index_AwardVector* ActivityConf::FindAward(uint32_t id) const { auto iter = index_award_map_.find(id); @@ -367,7 +367,7 @@ const protoconf::TaskConf::Task* TaskConf::Get(int64_t id) const { } // Index: ActivityID -const TaskConf::Index_TaskMap& TaskConf::FindTask() const { return index_task_map_ ;} +const TaskConf::Index_TaskMap& TaskConf::FindTaskMap() const { return index_task_map_ ;} const TaskConf::Index_TaskVector* TaskConf::FindTask(int64_t activity_id) const { auto iter = index_task_map_.find(activity_id); @@ -386,7 +386,7 @@ const protoconf::TaskConf::Task* TaskConf::FindFirstTask(int64_t activity_id) co } // OrderedIndex: Goal@OrderedTask -const TaskConf::OrderedIndex_OrderedTaskMap& TaskConf::FindOrderedTask() const { return ordered_index_ordered_task_map_ ;} +const TaskConf::OrderedIndex_OrderedTaskMap& TaskConf::FindOrderedTaskMap() const { return ordered_index_ordered_task_map_ ;} const TaskConf::OrderedIndex_OrderedTaskVector* TaskConf::FindOrderedTask(int64_t goal) const { auto iter = ordered_index_ordered_task_map_.find(goal); @@ -405,7 +405,7 @@ const protoconf::TaskConf::Task* TaskConf::FindFirstOrderedTask(int64_t goal) co } // OrderedIndex: Expiry@TaskExpiry -const TaskConf::OrderedIndex_TaskExpiryMap& TaskConf::FindTaskExpiry() const { return ordered_index_task_expiry_map_ ;} +const TaskConf::OrderedIndex_TaskExpiryMap& TaskConf::FindTaskExpiryMap() const { return ordered_index_task_expiry_map_ ;} const TaskConf::OrderedIndex_TaskExpiryVector* TaskConf::FindTaskExpiry(int64_t expiry) const { auto iter = ordered_index_task_expiry_map_.find(expiry); @@ -424,7 +424,7 @@ const protoconf::TaskConf::Task* TaskConf::FindFirstTaskExpiry(int64_t expiry) c } // OrderedIndex: Expiry@SortedTaskExpiry -const TaskConf::OrderedIndex_SortedTaskExpiryMap& TaskConf::FindSortedTaskExpiry() const { return ordered_index_sorted_task_expiry_map_ ;} +const TaskConf::OrderedIndex_SortedTaskExpiryMap& TaskConf::FindSortedTaskExpiryMap() const { return ordered_index_sorted_task_expiry_map_ ;} const TaskConf::OrderedIndex_SortedTaskExpiryVector* TaskConf::FindSortedTaskExpiry(int64_t expiry) const { auto iter = ordered_index_sorted_task_expiry_map_.find(expiry); @@ -443,7 +443,7 @@ const protoconf::TaskConf::Task* TaskConf::FindFirstSortedTaskExpiry(int64_t exp } // OrderedIndex: (Expiry,ActivityID)@ActivityExpiry -const TaskConf::OrderedIndex_ActivityExpiryMap& TaskConf::FindActivityExpiry() const { return ordered_index_activity_expiry_map_ ;} +const TaskConf::OrderedIndex_ActivityExpiryMap& TaskConf::FindActivityExpiryMap() const { return ordered_index_activity_expiry_map_ ;} const TaskConf::OrderedIndex_ActivityExpiryVector* TaskConf::FindActivityExpiry(int64_t expiry, int64_t activity_id) const { auto iter = ordered_index_activity_expiry_map_.find({expiry, activity_id}); diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 7a9f2273..8ace4c27 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -60,7 +60,7 @@ class ActivityConf : public Messager { using Index_ActivityMap = std::unordered_map; // Finds the index (ActivityName) to value (Index_ActivityVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ActivityMap& FindActivity() const; + const Index_ActivityMap& FindActivityMap() const; // Finds a vector of all values of the given key(s). const Index_ActivityVector* FindActivity(const std::string& activity_name) const; // Finds the first value of the given key(s). @@ -75,7 +75,7 @@ class ActivityConf : public Messager { using Index_ChapterMap = std::unordered_map; // Finds the index (ChapterID) to value (Index_ChapterVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_ChapterMap& FindChapter() const; + const Index_ChapterMap& FindChapterMap() const; // Finds a vector of all values of the given key(s). const Index_ChapterVector* FindChapter(uint32_t chapter_id) const; // Finds the first value of the given key(s). @@ -90,7 +90,7 @@ class ActivityConf : public Messager { using Index_NamedChapterMap = std::unordered_map; // Finds the index (ChapterName@NamedChapter) to value (Index_NamedChapterVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_NamedChapterMap& FindNamedChapter() const; + const Index_NamedChapterMap& FindNamedChapterMap() const; // Finds a vector of all values of the given key(s). const Index_NamedChapterVector* FindNamedChapter(const std::string& chapter_name) const; // Finds the first value of the given key(s). @@ -105,7 +105,7 @@ class ActivityConf : public Messager { using Index_AwardMap = std::unordered_map; // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_AwardMap& FindAward() const; + const Index_AwardMap& FindAwardMap() const; // Finds a vector of all values of the given key(s). const Index_AwardVector* FindAward(uint32_t id) const; // Finds the first value of the given key(s). @@ -113,7 +113,6 @@ class ActivityConf : public Messager { private: Index_AwardMap index_award_map_; - }; class ChapterConf : public Messager { @@ -171,7 +170,7 @@ class TaskConf : public Messager { using Index_TaskMap = std::unordered_map; // Finds the index (ActivityID) to value (Index_TaskVector) hash map. // One key may correspond to multiple values, which are contained by a vector. - const Index_TaskMap& FindTask() const; + const Index_TaskMap& FindTaskMap() const; // Finds a vector of all values of the given key(s). const Index_TaskVector* FindTask(int64_t activity_id) const; // Finds the first value of the given key(s). @@ -187,7 +186,7 @@ class TaskConf : public Messager { using OrderedIndex_OrderedTaskMap = std::map; // Finds the ordered index (Goal@OrderedTask) to value (OrderedIndex_OrderedTaskVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_OrderedTaskMap& FindOrderedTask() const; + const OrderedIndex_OrderedTaskMap& FindOrderedTaskMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_OrderedTaskVector* FindOrderedTask(int64_t goal) const; // Finds the first value of the given key(s). @@ -202,7 +201,7 @@ class TaskConf : public Messager { using OrderedIndex_TaskExpiryMap = std::map; // Finds the ordered index (Expiry@TaskExpiry) to value (OrderedIndex_TaskExpiryVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_TaskExpiryMap& FindTaskExpiry() const; + const OrderedIndex_TaskExpiryMap& FindTaskExpiryMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_TaskExpiryVector* FindTaskExpiry(int64_t expiry) const; // Finds the first value of the given key(s). @@ -217,7 +216,7 @@ class TaskConf : public Messager { using OrderedIndex_SortedTaskExpiryMap = std::map; // Finds the ordered index (Expiry@SortedTaskExpiry) to value (OrderedIndex_SortedTaskExpiryVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_SortedTaskExpiryMap& FindSortedTaskExpiry() const; + const OrderedIndex_SortedTaskExpiryMap& FindSortedTaskExpiryMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_SortedTaskExpiryVector* FindSortedTaskExpiry(int64_t expiry) const; // Finds the first value of the given key(s). @@ -243,7 +242,7 @@ class TaskConf : public Messager { using OrderedIndex_ActivityExpiryMap = std::map; // Finds the ordered index ((Expiry,ActivityID)@ActivityExpiry) to value (OrderedIndex_ActivityExpiryVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ActivityExpiryMap& FindActivityExpiry() const; + const OrderedIndex_ActivityExpiryMap& FindActivityExpiryMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ActivityExpiryVector* FindActivityExpiry(int64_t expiry, int64_t activity_id) const; // Finds the first value of the given key(s). @@ -251,7 +250,6 @@ class TaskConf : public Messager { private: OrderedIndex_ActivityExpiryMap ordered_index_activity_expiry_map_; - }; } // namespace tableau From df17fe47d7c348e79305b9258ce64ccd5a3d5ef2 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 18 Nov 2025 19:16:57 +0800 Subject: [PATCH 02/15] feat: add leveled-index generator --- .../helper/helper.go | 12 ++ .../index/index.go | 172 ++++++++++++--- .../leveledindex/leveled_index.go | 87 ++++++++ cmd/protoc-gen-cpp-tableau-loader/messager.go | 12 +- .../orderedindex/ordered_index.go | 171 ++++++++++++--- .../orderedmap/ordered_map.go | 13 +- internal/index/descriptor.go | 17 +- .../cpp-tableau-loader/src/protoconf/hub.pc.h | 5 + .../src/protoconf/hub_shard0.pc.cc | 7 + .../src/protoconf/item_conf.pc.cc | 139 ++++++++++-- .../src/protoconf/item_conf.pc.h | 45 ++++ .../src/protoconf/test_conf.pc.cc | 203 ++++++++++++++++-- .../src/protoconf/test_conf.pc.h | 81 +++++++ test/proto/item_conf.proto | 17 ++ test/testdata/conf/FruitConf.json | 1 + 15 files changed, 864 insertions(+), 118 deletions(-) create mode 100644 cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go create mode 100644 test/testdata/conf/FruitConf.json diff --git a/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go b/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go index e136cc36..9fc2e84c 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go +++ b/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go @@ -165,6 +165,14 @@ func ParseCppClassType(md protoreflect.MessageDescriptor) string { return strings.ReplaceAll(protoFullName, ".", "::") } +func ParseLeveledMapPrefix(md protoreflect.MessageDescriptor, mapFd protoreflect.FieldDescriptor) string { + if mapFd.MapValue().Kind() == protoreflect.MessageKind { + localMsgProtoName := strings.TrimPrefix(string(mapFd.MapValue().Message().FullName()), string(md.FullName())+".") + return strings.ReplaceAll(localMsgProtoName, ".", "_") + } + return mapFd.MapValue().Kind().String() +} + type MapKey struct { Type string Name string @@ -218,6 +226,10 @@ func Indent(depth int) string { return strings.Repeat(" ", depth) } +func Whitespace(count int) string { + return strings.Repeat(" ", count) +} + func ParseMapValueType(fd protoreflect.FieldDescriptor) string { valueType := ParseCppType(fd.MapValue()) if fd.MapValue().Kind() == protoreflect.MessageKind { diff --git a/cmd/protoc-gen-cpp-tableau-loader/index/index.go b/cmd/protoc-gen-cpp-tableau-loader/index/index.go index 15863b93..64dc0bec 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/index/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/index/index.go @@ -7,6 +7,7 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" + "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" @@ -17,13 +18,15 @@ type Generator struct { g *protogen.GeneratedFile descriptor *index.IndexDescriptor message *protogen.Message + level *leveledindex.Generator } -func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { +func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { return &Generator{ g: g, descriptor: descriptor, message: message, + level: level, } } @@ -62,6 +65,10 @@ func (x *Generator) indexContainerName(index *index.LevelIndex) string { return fmt.Sprintf("index_%s_map_", strcase.ToSnake(index.Name())) } +func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { + return fmt.Sprintf("index_%s_map%d_", strcase.ToSnake(index.Name()), i) +} + func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { var keys helper.MapKeys for _, field := range index.ColFields { @@ -136,9 +143,35 @@ func (x *Generator) GenHppIndexFinders() { x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", keys.GenGetParams(), ") const;") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + partKeys := x.level.Keys[:i] + x.g.P(helper.Indent(1), "// Finds the index (", index.Index, ") to value (", vectorType, ") hash map") + x.g.P(helper.Indent(1), "// specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") + x.g.P(helper.Indent(1), "const ", mapType, "* Find", index.Name(), "Map(", partKeys.GenGetParams(), ") const;") + x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") + x.g.P(helper.Indent(1), "// Finds the first value of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") + } x.g.P() + x.g.P(" private:") x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index), ";") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P(helper.Indent(1), "std::unordered_map<", x.level.Keys[0].Type, ", ", mapType, "> ", x.indexContainerNameI(index, i), ";") + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.indexContainerNameI(index, i), ";") + } + } } } } @@ -147,36 +180,38 @@ func (x *Generator) GenCppIndexLoader() { if !x.NeedGenerate() { return } + defer x.genIndexSorter() x.g.P(helper.Indent(1), "// Index init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { x.g.P(helper.Indent(1), x.indexContainerName(index), ".clear();") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + x.g.P(helper.Indent(1), x.indexContainerNameI(index, i), ".clear();") + } } } parentDataName := "data_" - depth := 1 for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.genOneCppIndexLoader(depth, index, parentDataName) + x.genOneCppIndexLoader(levelMessage.Depth, index, parentDataName) } - itemName := fmt.Sprintf("item%d", depth) + itemName := fmt.Sprintf("item%d", levelMessage.Depth) if levelMessage.FD == nil { break } if !levelMessage.NextLevel.NeedGen() { break } - x.g.P(helper.Indent(depth), "for (auto&& ", itemName, " : ", parentDataName, x.fieldGetter(levelMessage.FD), ") {") + x.g.P(helper.Indent(levelMessage.Depth), "for (auto&& ", itemName, " : ", parentDataName, x.fieldGetter(levelMessage.FD), ") {") parentDataName = itemName if levelMessage.FD.IsMap() { parentDataName = itemName + ".second" } - depth++ - } - for i := depth - 1; i > 0; i-- { - x.g.P(helper.Indent(i), "}") + defer x.g.P(helper.Indent(levelMessage.Depth), "}") } - x.genIndexSorter() } func (x *Generator) genOneCppIndexLoader(depth int, index *index.LevelIndex, parentDataName string) { @@ -186,7 +221,6 @@ func (x *Generator) genOneCppIndexLoader(depth int, index *index.LevelIndex, par // single-column index field := index.ColFields[0] // just take the first field fieldName := x.parseKeyFieldName(field) - indexContainerName := x.indexContainerName(index) if field.FD.IsList() { itemName := fmt.Sprintf("item%d", depth) x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") @@ -194,44 +228,61 @@ func (x *Generator) genOneCppIndexLoader(depth int, index *index.LevelIndex, par if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } - x.g.P(helper.Indent(depth+2), indexContainerName, "[", key, "].push_back(&", parentDataName, ");") + x.genLoader(depth, depth+2, index, key, parentDataName) x.g.P(helper.Indent(depth+1), "}") } else { key := parentDataName + fieldName - x.g.P(helper.Indent(depth+1), indexContainerName, "[", key, "].push_back(&", parentDataName, ");") + x.genLoader(depth, depth+1, index, key, parentDataName) } } else { // multi-column index - x.generateOneCppMulticolumnIndex(depth, index, parentDataName, nil) + x.generateOneCppMulticolumnIndex(depth, depth, index, parentDataName, nil) } x.g.P(helper.Indent(depth), "}") } -func (x *Generator) generateOneCppMulticolumnIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { +func (x *Generator) generateOneCppMulticolumnIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.mapKeyType(index) - indexContainerName := x.indexContainerName(index) - x.g.P(helper.Indent(depth+1), keyType, " key{", keys.GenGetArguments(), "};") - x.g.P(helper.Indent(depth+1), indexContainerName, "[key].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident+1), keyType, " key{", keys.GenGetArguments(), "};") + x.genLoader(depth, ident+1, index, "key", parentDataName) return } field := index.ColFields[cursor] fieldName := x.parseKeyFieldName(field) if field.FD.IsList() { itemName := fmt.Sprintf("index_item%d", cursor) - x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") + x.g.P(helper.Indent(ident+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") key := itemName if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } keys = keys.AddMapKey(helper.MapKey{Name: key}) - x.generateOneCppMulticolumnIndex(depth+1, index, parentDataName, keys) - x.g.P(helper.Indent(depth+1), "}") + x.generateOneCppMulticolumnIndex(depth, ident+1, index, parentDataName, keys) + x.g.P(helper.Indent(ident+1), "}") } else { key := parentDataName + fieldName keys = keys.AddMapKey(helper.MapKey{Name: key}) - x.generateOneCppMulticolumnIndex(depth, index, parentDataName, keys) + x.generateOneCppMulticolumnIndex(depth, ident, index, parentDataName, keys) + } +} + +func (x *Generator) genLoader(depth, ident int, index *index.LevelIndex, key, parentDataName string) { + x.g.P(helper.Indent(ident), x.indexContainerName(index), "[", key, "].push_back(&", parentDataName, ");") + for i := 1; i <= depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") + } else { + var fields []string + for j := 1; j <= i; j++ { + fields = append(fields, fmt.Sprintf("item%d.first", j)) + } + x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") + } } } @@ -241,21 +292,34 @@ func (x *Generator) genIndexSorter() { if len(index.SortedColFields) != 0 { valueType := x.mapValueType(index) x.g.P(helper.Indent(1), "// Index(sort): ", index.Index) - x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerName(index), ") {") - x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(),") - x.g.P(helper.Indent(7), "[](const ", valueType, "* a, const ", valueType, "* b) {") + indexContainerName := x.indexContainerName(index) + sorterDef := "auto " + indexContainerName + "sorter = [](" + x.g.P(helper.Indent(1), sorterDef, "const ", valueType, "* a,") + x.g.P(helper.Indent(1), helper.Whitespace(len(sorterDef)), "const ", valueType, "* b) {") for i, field := range index.SortedColFields { fieldName := strings.Replace(x.parseKeyFieldName(field), ".", "->", 1) if i == len(index.SortedColFields)-1 { - x.g.P(helper.Indent(8), "return a", fieldName, " < b", fieldName, ";") + x.g.P(helper.Indent(2), "return a", fieldName, " < b", fieldName, ";") } else { - x.g.P(helper.Indent(8), "if (a", fieldName, " != b", fieldName, ") {") - x.g.P(helper.Indent(9), "return a", fieldName, " < b", fieldName, ";") - x.g.P(helper.Indent(8), "}") + x.g.P(helper.Indent(2), "if (a", fieldName, " != b", fieldName, ") {") + x.g.P(helper.Indent(3), "return a", fieldName, " < b", fieldName, ";") + x.g.P(helper.Indent(2), "}") } } - x.g.P(helper.Indent(7), "});") + x.g.P(helper.Indent(1), "};") + x.g.P(helper.Indent(1), "for (auto&& item : ", indexContainerName, ") {") + x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(1), "}") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerNameI(index, i), ") {") + x.g.P(helper.Indent(2), "for (auto&& item1 : item.second) {") + x.g.P(helper.Indent(3), "std::sort(item1.second.begin(), item1.second.end(), ", indexContainerName, "sorter);") + x.g.P(helper.Indent(2), "}") + x.g.P(helper.Indent(1), "}") + } } } } @@ -300,6 +364,54 @@ func (x *Generator) GenCppIndexFinders() { x.g.P(helper.Indent(1), "return conf->front();") x.g.P("}") x.g.P() + + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + indexContainerNameI := x.indexContainerNameI(index, i) + partKeys := x.level.Keys[:i] + partParams := partKeys.GenGetParams() + partArgs := partKeys.GenGetArguments() + x.g.P("const ", messagerName, "::", mapType, "* ", messagerName, "::Find", index.Name(), "Map(", partParams, ") const {") + if len(partKeys) == 1 { + x.g.P(helper.Indent(1), "auto iter = ", indexContainerNameI, ".find(", partArgs, ");") + } else { + x.g.P(helper.Indent(1), "auto iter = ", indexContainerNameI, ".find({", partArgs, "});") + } + x.g.P(helper.Indent(1), "if (iter == ", indexContainerNameI, ".end()) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + x.g.P(helper.Indent(1), "return &iter->second;") + x.g.P("}") + x.g.P() + + x.g.P("const ", messagerName, "::", vectorType, "* ", messagerName, "::Find", index.Name(), "(", partParams, ", ", params, ") const {") + x.g.P(helper.Indent(1), "auto map = Find", index.Name(), "Map(", partArgs, ");") + x.g.P(helper.Indent(1), "if (map == nullptr) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + if len(index.ColFields) == 1 { + x.g.P(helper.Indent(1), "auto iter = map->find(", args, ");") + } else { + x.g.P(helper.Indent(1), "auto iter = map->find({", args, "});") + } + x.g.P(helper.Indent(1), "if (iter == map->end()) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + x.g.P(helper.Indent(1), "return &iter->second;") + x.g.P("}") + x.g.P() + + x.g.P("const ", x.mapValueType(index), "* ", messagerName, "::FindFirst", index.Name(), "(", partParams, ", ", params, ") const {") + x.g.P(helper.Indent(1), "auto conf = Find", index.Name(), "(", partArgs, ", ", args, ");") + x.g.P(helper.Indent(1), "if (conf == nullptr || conf->empty()) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + x.g.P(helper.Indent(1), "return conf->front();") + x.g.P("}") + x.g.P() + } } } } diff --git a/cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go b/cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go new file mode 100644 index 00000000..43f0dc8b --- /dev/null +++ b/cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go @@ -0,0 +1,87 @@ +package leveledindex + +import ( + "fmt" + + "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" + "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/options" + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/reflect/protoreflect" +) + +type Generator struct { + g *protogen.GeneratedFile + descriptor *index.IndexDescriptor + message *protogen.Message + + maxDepth int + Keys helper.MapKeys + MapFds []protoreflect.FieldDescriptor +} + +func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { + gen := &Generator{ + g: g, + descriptor: descriptor, + message: message, + } + gen.init() + return gen +} + +func (x *Generator) init() { + for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { + if fd := levelMessage.FD; fd != nil && fd.IsMap() { + x.Keys = x.Keys.AddMapKey(helper.MapKey{ + Type: helper.ParseMapKeyType(fd.MapKey()), + Name: helper.ParseMapFieldName(fd), + }) + x.MapFds = append(x.MapFds, fd) + } + if len(levelMessage.Indexes) != 0 || len(levelMessage.OrderedIndexes) != 0 { + x.maxDepth = levelMessage.Depth + } + } +} + +func (x *Generator) NeedGenerate() bool { + return options.NeedGenIndex(x.message.Desc, options.LangCPP) || options.NeedGenOrderedIndex(x.message.Desc, options.LangCPP) +} + +func (x *Generator) KeyType(mapFd protoreflect.FieldDescriptor) string { + return fmt.Sprintf("LeveledIndex_%sKey", helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) +} + +func (x *Generator) GenHppLeveledIndexKeys() { + if !x.NeedGenerate() { + return + } + for i := 1; i <= x.maxDepth-3 && i <= len(x.MapFds)-1; i++ { + if i == 1 { + x.g.P() + x.g.P(helper.Indent(1), "// LeveledIndex keys.") + x.g.P(" public:") + } + fd := x.MapFds[i] + keyType := x.KeyType(fd) + x.g.P(helper.Indent(1), "struct ", keyType, " {") + keys := x.Keys[:i+1] + for _, key := range keys { + x.g.P(helper.Indent(2), key.Type, " ", key.Name, ";") + } + x.g.P("#if __cplusplus >= 202002L") + x.g.P(helper.Indent(2), "bool operator==(const ", keyType, "& other) const = default;") + x.g.P("#else") + x.g.P(helper.Indent(2), "bool operator==(const ", keyType, "& other) const {") + x.g.P(helper.Indent(3), "return std::tie(", keys.GenGetArguments(), ") == std::tie(", keys.GenOtherArguments("other"), ");") + x.g.P(helper.Indent(2), "}") + x.g.P("#endif") + x.g.P(helper.Indent(1), "};") + x.g.P(helper.Indent(1), "struct ", keyType, "Hasher {") + x.g.P(helper.Indent(2), "std::size_t operator()(const ", keyType, "& key) const {") + x.g.P(helper.Indent(3), "return util::SugaredHashCombine(", keys.GenOtherArguments("key"), ");") + x.g.P(helper.Indent(2), "}") + x.g.P(helper.Indent(1), "};") + } +} diff --git a/cmd/protoc-gen-cpp-tableau-loader/messager.go b/cmd/protoc-gen-cpp-tableau-loader/messager.go index a9f6f0a3..15ac213f 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/messager.go +++ b/cmd/protoc-gen-cpp-tableau-loader/messager.go @@ -5,6 +5,7 @@ import ( "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" idx "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/index" + "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/leveledindex" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/orderedindex" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/orderedmap" "github.com/tableauio/loader/internal/extensions" @@ -85,8 +86,9 @@ func genHppMessage(g *protogen.GeneratedFile, message *protogen.Message) { indexDescriptor := index.ParseIndexDescriptor(message.Desc) orderedMapGenerator := orderedmap.NewGenerator(g, message) - indexGenerator := idx.NewGenerator(g, indexDescriptor, message) - orderedIndexGenerator := orderedindex.NewGenerator(g, indexDescriptor, message) + leveledIndexGenerator := leveledindex.NewGenerator(g, indexDescriptor, message) + indexGenerator := idx.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) + orderedIndexGenerator := orderedindex.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) g.P("class ", message.Desc.Name(), " : public Messager {") g.P(" public:") @@ -109,6 +111,7 @@ func genHppMessage(g *protogen.GeneratedFile, message *protogen.Message) { g.P(helper.Indent(1), "static const std::string kProtoName;") g.P(helper.Indent(1), cppFullName, " data_;") orderedMapGenerator.GenHppOrderedMapGetters() + leveledIndexGenerator.GenHppLeveledIndexKeys() indexGenerator.GenHppIndexFinders() orderedIndexGenerator.GenHppOrderedIndexFinders() g.P("};") @@ -161,8 +164,9 @@ func genCppMessage(g *protogen.GeneratedFile, message *protogen.Message) { indexDescriptor := index.ParseIndexDescriptor(message.Desc) orderedMapGenerator := orderedmap.NewGenerator(g, message) - indexGenerator := idx.NewGenerator(g, indexDescriptor, message) - orderedIndexGenerator := orderedindex.NewGenerator(g, indexDescriptor, message) + leveledIndexGenerator := leveledindex.NewGenerator(g, indexDescriptor, message) + indexGenerator := idx.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) + orderedIndexGenerator := orderedindex.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) g.P("const std::string ", messagerName, "::kProtoName = ", cppFullName, `::GetDescriptor()->name();`) g.P() diff --git a/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go index 5600e7e2..b7799b32 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go @@ -7,6 +7,7 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" + "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" @@ -17,13 +18,15 @@ type Generator struct { g *protogen.GeneratedFile descriptor *index.IndexDescriptor message *protogen.Message + level *leveledindex.Generator } -func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { +func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { return &Generator{ g: g, descriptor: descriptor, message: message, + level: level, } } @@ -62,6 +65,10 @@ func (x *Generator) indexContainerName(index *index.LevelIndex) string { return fmt.Sprintf("ordered_index_%s_map_", strcase.ToSnake(index.Name())) } +func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { + return fmt.Sprintf("ordered_index_%s_map%d_", strcase.ToSnake(index.Name()), i) +} + func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { var keys helper.MapKeys for _, field := range index.ColFields { @@ -133,10 +140,35 @@ func (x *Generator) GenHppOrderedIndexFinders() { x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") x.g.P(helper.Indent(1), "const ", helper.ParseCppClassType(index.MD), "* FindFirst", index.Name(), "(", keys.GenGetParams(), ") const;") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + partKeys := x.level.Keys[:i] + x.g.P(helper.Indent(1), "// Finds the ordered index (", index.Index, ") to value (", vectorType, ") map") + x.g.P(helper.Indent(1), "// specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") + x.g.P(helper.Indent(1), "const ", mapType, "* Find", index.Name(), "Map(", partKeys.GenGetParams(), ") const;") + x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") + x.g.P(helper.Indent(1), "// Finds the first value of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") + } x.g.P() x.g.P(" private:") x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index), ";") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P(helper.Indent(1), "std::unordered_map<", x.level.Keys[0].Type, ", ", mapType, "> ", x.indexContainerNameI(index, i), ";") + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.indexContainerNameI(index, i), ";") + } + } } } } @@ -145,36 +177,38 @@ func (x *Generator) GenCppOrderedIndexLoader() { if !x.NeedGenerate() { return } + defer x.genOrderedIndexSorter() x.g.P(helper.Indent(1), "// OrderedIndex init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { x.g.P(helper.Indent(1), x.indexContainerName(index), ".clear();") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + x.g.P(helper.Indent(1), x.indexContainerNameI(index, i), ".clear();") + } } } parentDataName := "data_" - depth := 1 for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.genOneCppOrderedIndexLoader(depth, index, parentDataName) + x.genOneCppOrderedIndexLoader(levelMessage.Depth, index, parentDataName) } - itemName := fmt.Sprintf("item%d", depth) + itemName := fmt.Sprintf("item%d", levelMessage.Depth) if levelMessage.FD == nil { break } if !levelMessage.NextLevel.NeedGen() { break } - x.g.P(helper.Indent(depth), "for (auto&& ", itemName, " : ", parentDataName, x.fieldGetter(levelMessage.FD), ") {") + x.g.P(helper.Indent(levelMessage.Depth), "for (auto&& ", itemName, " : ", parentDataName, x.fieldGetter(levelMessage.FD), ") {") parentDataName = itemName if levelMessage.FD.IsMap() { parentDataName = itemName + ".second" } - depth++ - } - for i := depth - 1; i > 0; i-- { - x.g.P(helper.Indent(i), "}") + defer x.g.P(helper.Indent(levelMessage.Depth), "}") } - x.genOrderedIndexSorter() } func (x *Generator) genOneCppOrderedIndexLoader(depth int, index *index.LevelIndex, parentDataName string) { @@ -184,7 +218,6 @@ func (x *Generator) genOneCppOrderedIndexLoader(depth int, index *index.LevelInd // single-column index field := index.ColFields[0] // just take the first field fieldName, suffix := x.parseKeyFieldNameAndSuffix(field) - indexContainerName := x.indexContainerName(index) if field.FD.IsList() { itemName := fmt.Sprintf("item%d", depth) x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") @@ -192,44 +225,61 @@ func (x *Generator) genOneCppOrderedIndexLoader(depth int, index *index.LevelInd if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } - x.g.P(helper.Indent(depth+2), indexContainerName, "[", key, "].push_back(&", parentDataName, ");") + x.genLoader(depth, depth+2, index, key, parentDataName) x.g.P(helper.Indent(depth+1), "}") } else { key := parentDataName + fieldName + suffix - x.g.P(helper.Indent(depth+1), indexContainerName, "[", key, "].push_back(&", parentDataName, ");") + x.genLoader(depth, depth+1, index, key, parentDataName) } } else { // multi-column index - x.generateOneCppMulticolumnOrderedIndex(depth, index, parentDataName, nil) + x.generateOneCppMulticolumnOrderedIndex(depth, depth, index, parentDataName, nil) } x.g.P(helper.Indent(depth), "}") } -func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { +func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.mapKeyType(index) - indexContainerName := x.indexContainerName(index) - x.g.P(helper.Indent(depth+1), keyType, " key{", keys.GenGetArguments(), "};") - x.g.P(helper.Indent(depth+1), indexContainerName, "[key].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident+1), keyType, " key{", keys.GenGetArguments(), "};") + x.genLoader(depth, ident+1, index, "key", parentDataName) return } field := index.ColFields[cursor] fieldName, suffix := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { itemName := fmt.Sprintf("index_item%d", cursor) - x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") + x.g.P(helper.Indent(ident+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") key := itemName + suffix if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } keys = keys.AddMapKey(helper.MapKey{Name: key}) - x.generateOneCppMulticolumnOrderedIndex(depth+1, index, parentDataName, keys) - x.g.P(helper.Indent(depth+1), "}") + x.generateOneCppMulticolumnOrderedIndex(depth, ident+1, index, parentDataName, keys) + x.g.P(helper.Indent(ident+1), "}") } else { key := parentDataName + fieldName + suffix keys = keys.AddMapKey(helper.MapKey{Name: key}) - x.generateOneCppMulticolumnOrderedIndex(depth, index, parentDataName, keys) + x.generateOneCppMulticolumnOrderedIndex(depth, ident, index, parentDataName, keys) + } +} + +func (x *Generator) genLoader(depth, ident int, index *index.LevelIndex, key, parentDataName string) { + x.g.P(helper.Indent(ident), x.indexContainerName(index), "[", key, "].push_back(&", parentDataName, ");") + for i := 1; i <= depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") + } else { + var fields []string + for j := 1; j <= i; j++ { + fields = append(fields, fmt.Sprintf("item%d.first", j)) + } + x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") + } } } @@ -239,22 +289,35 @@ func (x *Generator) genOrderedIndexSorter() { if len(index.SortedColFields) != 0 { valueType := x.mapValueType(index) x.g.P(helper.Indent(1), "// OrderedIndex(sort): ", index.Index) - x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerName(index), ") {") - x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(),") - x.g.P(helper.Indent(7), "[](const ", valueType, "* a, const ", valueType, "* b) {") + indexContainerName := x.indexContainerName(index) + sorterDef := "auto " + indexContainerName + "sorter = [](" + x.g.P(helper.Indent(1), sorterDef, "const ", valueType, "* a,") + x.g.P(helper.Indent(1), helper.Whitespace(len(sorterDef)), "const ", valueType, "* b) {") for i, field := range index.SortedColFields { fieldName, _ := x.parseKeyFieldNameAndSuffix(field) fieldName = strings.Replace(fieldName, ".", "->", 1) if i == len(index.SortedColFields)-1 { - x.g.P(helper.Indent(8), "return a", fieldName, " < b", fieldName, ";") + x.g.P(helper.Indent(2), "return a", fieldName, " < b", fieldName, ";") } else { - x.g.P(helper.Indent(8), "if (a", fieldName, " != b", fieldName, ") {") - x.g.P(helper.Indent(9), "return a", fieldName, " < b", fieldName, ";") - x.g.P(helper.Indent(8), "}") + x.g.P(helper.Indent(2), "if (a", fieldName, " != b", fieldName, ") {") + x.g.P(helper.Indent(3), "return a", fieldName, " < b", fieldName, ";") + x.g.P(helper.Indent(2), "}") } } - x.g.P(helper.Indent(7), "});") + x.g.P(helper.Indent(1), "};") + x.g.P(helper.Indent(1), "for (auto&& item : ", indexContainerName, ") {") + x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(1), "}") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerNameI(index, i), ") {") + x.g.P(helper.Indent(2), "for (auto&& item1 : item.second) {") + x.g.P(helper.Indent(3), "std::sort(item1.second.begin(), item1.second.end(), ", indexContainerName, "sorter);") + x.g.P(helper.Indent(2), "}") + x.g.P(helper.Indent(1), "}") + } } } } @@ -299,6 +362,54 @@ func (x *Generator) GenCppOrderedIndexFinders() { x.g.P(helper.Indent(1), "return conf->front();") x.g.P("}") x.g.P() + + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + indexContainerNameI := x.indexContainerNameI(index, i) + partKeys := x.level.Keys[:i] + partParams := partKeys.GenGetParams() + partArgs := partKeys.GenGetArguments() + x.g.P("const ", messagerName, "::", mapType, "* ", messagerName, "::Find", index.Name(), "Map(", partParams, ") const {") + if len(partKeys) == 1 { + x.g.P(helper.Indent(1), "auto iter = ", indexContainerNameI, ".find(", partArgs, ");") + } else { + x.g.P(helper.Indent(1), "auto iter = ", indexContainerNameI, ".find({", partArgs, "});") + } + x.g.P(helper.Indent(1), "if (iter == ", indexContainerNameI, ".end()) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + x.g.P(helper.Indent(1), "return &iter->second;") + x.g.P("}") + x.g.P() + + x.g.P("const ", messagerName, "::", vectorType, "* ", messagerName, "::Find", index.Name(), "(", partParams, ", ", params, ") const {") + x.g.P(helper.Indent(1), "auto map = Find", index.Name(), "Map(", partArgs, ");") + x.g.P(helper.Indent(1), "if (map == nullptr) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + if len(index.ColFields) == 1 { + x.g.P(helper.Indent(1), "auto iter = map->find(", args, ");") + } else { + x.g.P(helper.Indent(1), "auto iter = map->find({", args, "});") + } + x.g.P(helper.Indent(1), "if (iter == map->end()) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + x.g.P(helper.Indent(1), "return &iter->second;") + x.g.P("}") + x.g.P() + + x.g.P("const ", x.mapValueType(index), "* ", messagerName, "::FindFirst", index.Name(), "(", partParams, ", ", params, ") const {") + x.g.P(helper.Indent(1), "auto conf = Find", index.Name(), "(", partArgs, ", ", args, ");") + x.g.P(helper.Indent(1), "if (conf == nullptr || conf->empty()) {") + x.g.P(helper.Indent(2), "return nullptr;") + x.g.P(helper.Indent(1), "}") + x.g.P(helper.Indent(1), "return conf->front();") + x.g.P("}") + x.g.P() + } } } } diff --git a/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go b/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go index ad51515e..47ece8b6 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go +++ b/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go @@ -2,7 +2,6 @@ package orderedmap import ( "fmt" - "strings" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" "github.com/tableauio/loader/internal/options" @@ -30,20 +29,12 @@ func (x *Generator) messagerName() string { return string(x.message.Desc.Name()) } -func (x *Generator) orderedMapPrefix(mapFd protoreflect.FieldDescriptor) string { - if mapFd.MapValue().Kind() == protoreflect.MessageKind { - localMsgProtoName := strings.TrimPrefix(string(mapFd.MapValue().Message().FullName()), string(x.message.Desc.FullName())+".") - return strings.ReplaceAll(localMsgProtoName, ".", "_") - } - return mapFd.MapValue().Kind().String() -} - func (x *Generator) mapType(mapFd protoreflect.FieldDescriptor) string { - return fmt.Sprintf("OrderedMap_%sMap", x.orderedMapPrefix(mapFd)) + return fmt.Sprintf("OrderedMap_%sMap", helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } func (x *Generator) mapValueType(mapFd protoreflect.FieldDescriptor) string { - return fmt.Sprintf("OrderedMap_%sValue", x.orderedMapPrefix(mapFd)) + return fmt.Sprintf("OrderedMap_%sValue", helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } func (x *Generator) mapValueFieldType(fd protoreflect.FieldDescriptor) string { diff --git a/internal/index/descriptor.go b/internal/index/descriptor.go index d5e808d6..13dea3c4 100644 --- a/internal/index/descriptor.go +++ b/internal/index/descriptor.go @@ -52,6 +52,9 @@ type LevelMessage struct { // Current level message's all index fields Indexes, OrderedIndexes []*LevelIndex + + // depth of message hierarchy + Depth int } func (l *LevelMessage) NeedGen() bool { @@ -77,21 +80,23 @@ func (l *LevelIndex) Name() string { return name } -func parseLevelMessage(md protoreflect.MessageDescriptor) *LevelMessage { - levelInfo := &LevelMessage{} +func parseLevelMessage(md protoreflect.MessageDescriptor, depth int) *LevelMessage { + levelInfo := &LevelMessage{ + Depth: depth, + } for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() && fd.MapValue().Kind() == protoreflect.MessageKind { - levelInfo.NextLevel = parseLevelMessage(fd.MapValue().Message()) + levelInfo.NextLevel = parseLevelMessage(fd.MapValue().Message(), depth+1) levelInfo.FD = fd return levelInfo } else if fd.IsList() && fd.Kind() == protoreflect.MessageKind { - levelInfo.NextLevel = parseLevelMessage(fd.Message()) + levelInfo.NextLevel = parseLevelMessage(fd.Message(), depth+1) levelInfo.FD = fd return levelInfo } } - return &LevelMessage{} + return levelInfo } // parseRecursively parses multi-column index related info. @@ -169,7 +174,7 @@ func parseCols(cols []string, prefix string, md protoreflect.MessageDescriptor, func ParseIndexDescriptor(md protoreflect.MessageDescriptor) *IndexDescriptor { descriptor := &IndexDescriptor{ - LevelMessage: parseLevelMessage(md), + LevelMessage: parseLevelMessage(md, 1), } indexes, orderedIndexes := ParseWSOptionIndex(md) // parse indexes into level message diff --git a/test/cpp-tableau-loader/src/protoconf/hub.pc.h b/test/cpp-tableau-loader/src/protoconf/hub.pc.h index 618c4681..63e9a9f1 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/hub.pc.h @@ -126,6 +126,10 @@ class HeroConf; template <> const std::shared_ptr Hub::Get() const; +class FruitConf; +template <> +const std::shared_ptr Hub::Get() const; + class ItemConf; template <> const std::shared_ptr Hub::Get() const; @@ -174,6 +178,7 @@ class MessagerContainer { std::time_t last_loaded_time_; std::shared_ptr hero_base_conf_; std::shared_ptr hero_conf_; + std::shared_ptr fruit_conf_; std::shared_ptr item_conf_; std::shared_ptr patch_merge_conf_; std::shared_ptr patch_replace_conf_; diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc index a5d39608..c05d426f 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc @@ -19,6 +19,11 @@ const std::shared_ptr Hub::Get() const { return GetMessagerContainerWithProvider()->hero_conf_; } +template <> +const std::shared_ptr Hub::Get() const { + return GetMessagerContainerWithProvider()->fruit_conf_; +} + template <> const std::shared_ptr Hub::Get() const { return GetMessagerContainerWithProvider()->item_conf_; @@ -27,12 +32,14 @@ const std::shared_ptr Hub::Get() const { void MessagerContainer::InitShard0() { hero_base_conf_ = std::dynamic_pointer_cast(GetMessager(HeroBaseConf::Name())); hero_conf_ = std::dynamic_pointer_cast(GetMessager(HeroConf::Name())); + fruit_conf_ = std::dynamic_pointer_cast(GetMessager(FruitConf::Name())); item_conf_ = std::dynamic_pointer_cast(GetMessager(ItemConf::Name())); } void Registry::InitShard0() { Register(); Register(); + Register(); Register(); } } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index 15fee8e3..69cb1dd1 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -92,21 +92,23 @@ bool ItemConf::ProcessAfterLoad() { } } // Index(sort): Param@ItemInfo + auto index_item_info_map_sorter = [](const protoconf::ItemConf::Item* a, + const protoconf::ItemConf::Item* b) { + return a->id() < b->id(); + }; for (auto&& item : index_item_info_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::ItemConf::Item* a, const protoconf::ItemConf::Item* b) { - return a->id() < b->id(); - }); + std::sort(item.second.begin(), item.second.end(), index_item_info_map_sorter); } // Index(sort): (ID,Name)@AwardItem + auto index_award_item_map_sorter = [](const protoconf::ItemConf::Item* a, + const protoconf::ItemConf::Item* b) { + if (a->type() != b->type()) { + return a->type() < b->type(); + } + return a->use_effect().type() < b->use_effect().type(); + }; for (auto&& item : index_award_item_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::ItemConf::Item* a, const protoconf::ItemConf::Item* b) { - if (a->type() != b->type()) { - return a->type() < b->type(); - } - return a->use_effect().type() < b->use_effect().type(); - }); + std::sort(item.second.begin(), item.second.end(), index_award_item_map_sorter); } // OrderedIndex init. ordered_index_ext_type_map_.clear(); @@ -129,11 +131,12 @@ bool ItemConf::ProcessAfterLoad() { } } // OrderedIndex(sort): (Param,ExtType)@ParamExtType + auto ordered_index_param_ext_type_map_sorter = [](const protoconf::ItemConf::Item* a, + const protoconf::ItemConf::Item* b) { + return a->id() < b->id(); + }; for (auto&& item : ordered_index_param_ext_type_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::ItemConf::Item* a, const protoconf::ItemConf::Item* b) { - return a->id() < b->id(); - }); + std::sort(item.second.begin(), item.second.end(), ordered_index_param_ext_type_map_sorter); } return true; } @@ -378,4 +381,110 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstParamExtType(int32_t param, return conf->front(); } +const std::string FruitConf::kProtoName = protoconf::FruitConf::GetDescriptor()->name(); + +bool FruitConf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessagerInDir(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool FruitConf::ProcessAfterLoad() { + // OrderedIndex init. + ordered_index_fruit_map_.clear(); + ordered_index_fruit_map1_.clear(); + for (auto&& item1 : data_.fruits_map()) { + for (auto&& item2 : item1.second.fruit_map()) { + { + // OrderedIndex: Price + ordered_index_fruit_map_[item2.second.price()].push_back(&item2.second); + ordered_index_fruit_map1_[item1.first][item2.second.price()].push_back(&item2.second); + } + } + } + // OrderedIndex(sort): Price + auto ordered_index_fruit_map_sorter = [](const protoconf::FruitConf::Fruits::Fruit* a, + const protoconf::FruitConf::Fruits::Fruit* b) { + return a->fruit_id() < b->fruit_id(); + }; + for (auto&& item : ordered_index_fruit_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_fruit_map_sorter); + } + for (auto&& item : ordered_index_fruit_map1_) { + for (auto&& item1 : item.second) { + std::sort(item1.second.begin(), item1.second.end(), ordered_index_fruit_map_sorter); + } + } + return true; +} + +const protoconf::FruitConf::Fruits* FruitConf::Get(int32_t fruit_type) const { + auto iter = data_.fruits_map().find(fruit_type); + if (iter == data_.fruits_map().end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::FruitConf::Fruits::Fruit* FruitConf::Get(int32_t fruit_type, int32_t fruit_id) const { + const auto* conf = Get(fruit_type); + if (conf == nullptr) { + return nullptr; + } + auto iter = conf->fruit_map().find(fruit_id); + if (iter == conf->fruit_map().end()) { + return nullptr; + } + return &iter->second; +} + +// OrderedIndex: Price +const FruitConf::OrderedIndex_FruitMap& FruitConf::FindFruitMap() const { return ordered_index_fruit_map_ ;} + +const FruitConf::OrderedIndex_FruitVector* FruitConf::FindFruit(int32_t price) const { + auto iter = ordered_index_fruit_map_.find(price); + if (iter == ordered_index_fruit_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::FruitConf::Fruits::Fruit* FruitConf::FindFirstFruit(int32_t price) const { + auto conf = FindFruit(price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const FruitConf::OrderedIndex_FruitMap* FruitConf::FindFruitMap(int32_t fruit_type) const { + auto iter = ordered_index_fruit_map1_.find(fruit_type); + if (iter == ordered_index_fruit_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const FruitConf::OrderedIndex_FruitVector* FruitConf::FindFruit(int32_t fruit_type, int32_t price) const { + auto map = FindFruitMap(fruit_type); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(price); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::FruitConf::Fruits::Fruit* FruitConf::FindFirstFruit(int32_t fruit_type, int32_t price) const { + auto conf = FindFruit(fruit_type, price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index a7353b6d..3e9dacac 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -266,9 +266,54 @@ class ItemConf : public Messager { OrderedIndex_ParamExtTypeMap ordered_index_param_ext_type_map_; }; +class FruitConf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; + const protoconf::FruitConf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + public: + const protoconf::FruitConf::Fruits* Get(int32_t fruit_type) const; + const protoconf::FruitConf::Fruits::Fruit* Get(int32_t fruit_type, int32_t fruit_id) const; + + private: + static const std::string kProtoName; + protoconf::FruitConf data_; + + // OrderedIndex accessers. + // OrderedIndex: Price + public: + using OrderedIndex_FruitVector = std::vector; + using OrderedIndex_FruitMap = std::map; + // Finds the ordered index (Price) to value (OrderedIndex_FruitVector) map. + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_FruitMap& FindFruitMap() const; + // Finds a vector of all values of the given key(s). + const OrderedIndex_FruitVector* FindFruit(int32_t price) const; + // Finds the first value of the given key(s). + const protoconf::FruitConf::Fruits::Fruit* FindFirstFruit(int32_t price) const; + // Finds the ordered index (Price) to value (OrderedIndex_FruitVector) map + // specified by (fruit_type). + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_FruitMap* FindFruitMap(int32_t fruit_type) const; + // Finds a vector of all values of the given key(s) specified by (fruit_type). + const OrderedIndex_FruitVector* FindFruit(int32_t fruit_type, int32_t price) const; + // Finds the first value of the given key(s) specified by (fruit_type). + const protoconf::FruitConf::Fruits::Fruit* FindFirstFruit(int32_t fruit_type, int32_t price) const; + + private: + OrderedIndex_FruitMap ordered_index_fruit_map_; + std::unordered_map ordered_index_fruit_map1_; +}; + } // namespace tableau namespace protoconf { // Here are some type aliases for easy use. using ItemConfMgr = tableau::ItemConf; +using FruitConfMgr = tableau::FruitConf; } // namespace protoconf diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc index 2bf19eee..dca5989f 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc @@ -41,8 +41,13 @@ bool ActivityConf::ProcessAfterLoad() { // Index init. index_activity_map_.clear(); index_chapter_map_.clear(); + index_chapter_map1_.clear(); index_named_chapter_map_.clear(); + index_named_chapter_map1_.clear(); index_award_map_.clear(); + index_award_map1_.clear(); + index_award_map2_.clear(); + index_award_map3_.clear(); for (auto&& item1 : data_.activity_map()) { { // Index: ActivityName @@ -52,27 +57,38 @@ bool ActivityConf::ProcessAfterLoad() { { // Index: ChapterID index_chapter_map_[item2.second.chapter_id()].push_back(&item2.second); + index_chapter_map1_[item1.first][item2.second.chapter_id()].push_back(&item2.second); } { // Index: ChapterName@NamedChapter index_named_chapter_map_[item2.second.chapter_name()].push_back(&item2.second); + index_named_chapter_map1_[item1.first][item2.second.chapter_name()].push_back(&item2.second); } for (auto&& item3 : item2.second.section_map()) { for (auto&& item4 : item3.second.section_item_list()) { { // Index: SectionItemID@Award index_award_map_[item4.id()].push_back(&item4); + index_award_map1_[item1.first][item4.id()].push_back(&item4); + index_award_map2_[{item1.first, item2.first}][item4.id()].push_back(&item4); + index_award_map3_[{item1.first, item2.first, item3.first}][item4.id()].push_back(&item4); } } } } } // Index(sort): ChapterName@NamedChapter + auto index_named_chapter_map_sorter = [](const protoconf::ActivityConf::Activity::Chapter* a, + const protoconf::ActivityConf::Activity::Chapter* b) { + return a->award_id() < b->award_id(); + }; for (auto&& item : index_named_chapter_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::ActivityConf::Activity::Chapter* a, const protoconf::ActivityConf::Activity::Chapter* b) { - return a->award_id() < b->award_id(); - }); + std::sort(item.second.begin(), item.second.end(), index_named_chapter_map_sorter); + } + for (auto&& item : index_named_chapter_map1_) { + for (auto&& item1 : item.second) { + std::sort(item1.second.begin(), item1.second.end(), index_named_chapter_map_sorter); + } } return true; } @@ -199,6 +215,34 @@ const protoconf::ActivityConf::Activity::Chapter* ActivityConf::FindFirstChapter return conf->front(); } +const ActivityConf::Index_ChapterMap* ActivityConf::FindChapterMap(uint64_t activity_id) const { + auto iter = index_chapter_map1_.find(activity_id); + if (iter == index_chapter_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const ActivityConf::Index_ChapterVector* ActivityConf::FindChapter(uint64_t activity_id, uint32_t chapter_id) const { + auto map = FindChapterMap(activity_id); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(chapter_id); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::ActivityConf::Activity::Chapter* ActivityConf::FindFirstChapter(uint64_t activity_id, uint32_t chapter_id) const { + auto conf = FindChapter(activity_id, chapter_id); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + // Index: ChapterName@NamedChapter const ActivityConf::Index_NamedChapterMap& ActivityConf::FindNamedChapterMap() const { return index_named_chapter_map_ ;} @@ -218,6 +262,34 @@ const protoconf::ActivityConf::Activity::Chapter* ActivityConf::FindFirstNamedCh return conf->front(); } +const ActivityConf::Index_NamedChapterMap* ActivityConf::FindNamedChapterMap(uint64_t activity_id) const { + auto iter = index_named_chapter_map1_.find(activity_id); + if (iter == index_named_chapter_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const ActivityConf::Index_NamedChapterVector* ActivityConf::FindNamedChapter(uint64_t activity_id, const std::string& chapter_name) const { + auto map = FindNamedChapterMap(activity_id); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(chapter_name); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::ActivityConf::Activity::Chapter* ActivityConf::FindFirstNamedChapter(uint64_t activity_id, const std::string& chapter_name) const { + auto conf = FindNamedChapter(activity_id, chapter_name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + // Index: SectionItemID@Award const ActivityConf::Index_AwardMap& ActivityConf::FindAwardMap() const { return index_award_map_ ;} @@ -237,6 +309,90 @@ const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint32_t id) return conf->front(); } +const ActivityConf::Index_AwardMap* ActivityConf::FindAwardMap(uint64_t activity_id) const { + auto iter = index_award_map1_.find(activity_id); + if (iter == index_award_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const ActivityConf::Index_AwardVector* ActivityConf::FindAward(uint64_t activity_id, uint32_t id) const { + auto map = FindAwardMap(activity_id); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(id); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint64_t activity_id, uint32_t id) const { + auto conf = FindAward(activity_id, id); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const ActivityConf::Index_AwardMap* ActivityConf::FindAwardMap(uint64_t activity_id, uint32_t chapter_id) const { + auto iter = index_award_map2_.find({activity_id, chapter_id}); + if (iter == index_award_map2_.end()) { + return nullptr; + } + return &iter->second; +} + +const ActivityConf::Index_AwardVector* ActivityConf::FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const { + auto map = FindAwardMap(activity_id, chapter_id); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(id); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const { + auto conf = FindAward(activity_id, chapter_id, id); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const ActivityConf::Index_AwardMap* ActivityConf::FindAwardMap(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id) const { + auto iter = index_award_map3_.find({activity_id, chapter_id, section_id}); + if (iter == index_award_map3_.end()) { + return nullptr; + } + return &iter->second; +} + +const ActivityConf::Index_AwardVector* ActivityConf::FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const { + auto map = FindAwardMap(activity_id, chapter_id, section_id); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(id); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const { + auto conf = FindAward(activity_id, chapter_id, section_id, id); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + const std::string ChapterConf::kProtoName = protoconf::ChapterConf::GetDescriptor()->name(); bool ChapterConf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { @@ -305,14 +461,15 @@ bool TaskConf::ProcessAfterLoad() { } } // Index(sort): ActivityID + auto index_task_map_sorter = [](const protoconf::TaskConf::Task* a, + const protoconf::TaskConf::Task* b) { + if (a->goal() != b->goal()) { + return a->goal() < b->goal(); + } + return a->id() < b->id(); + }; for (auto&& item : index_task_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::TaskConf::Task* a, const protoconf::TaskConf::Task* b) { - if (a->goal() != b->goal()) { - return a->goal() < b->goal(); - } - return a->id() < b->id(); - }); + std::sort(item.second.begin(), item.second.end(), index_task_map_sorter); } // OrderedIndex init. ordered_index_ordered_task_map_.clear(); @@ -339,21 +496,23 @@ bool TaskConf::ProcessAfterLoad() { } } // OrderedIndex(sort): Goal@OrderedTask + auto ordered_index_ordered_task_map_sorter = [](const protoconf::TaskConf::Task* a, + const protoconf::TaskConf::Task* b) { + return a->id() < b->id(); + }; for (auto&& item : ordered_index_ordered_task_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::TaskConf::Task* a, const protoconf::TaskConf::Task* b) { - return a->id() < b->id(); - }); + std::sort(item.second.begin(), item.second.end(), ordered_index_ordered_task_map_sorter); } // OrderedIndex(sort): Expiry@SortedTaskExpiry + auto ordered_index_sorted_task_expiry_map_sorter = [](const protoconf::TaskConf::Task* a, + const protoconf::TaskConf::Task* b) { + if (a->goal() != b->goal()) { + return a->goal() < b->goal(); + } + return a->id() < b->id(); + }; for (auto&& item : ordered_index_sorted_task_expiry_map_) { - std::sort(item.second.begin(), item.second.end(), - [](const protoconf::TaskConf::Task* a, const protoconf::TaskConf::Task* b) { - if (a->goal() != b->goal()) { - return a->goal() < b->goal(); - } - return a->id() < b->id(); - }); + std::sort(item.second.begin(), item.second.end(), ordered_index_sorted_task_expiry_map_sorter); } return true; } diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 8ace4c27..8f21a5a0 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -53,6 +53,42 @@ class ActivityConf : public Messager { private: OrderedMap_ActivityMap ordered_map_; + // LeveledIndex keys. + public: + struct LeveledIndex_Activity_ChapterKey { + uint64_t activity_id; + uint32_t chapter_id; +#if __cplusplus >= 202002L + bool operator==(const LeveledIndex_Activity_ChapterKey& other) const = default; +#else + bool operator==(const LeveledIndex_Activity_ChapterKey& other) const { + return std::tie(activity_id, chapter_id) == std::tie(other.activity_id, other.chapter_id); + } +#endif + }; + struct LeveledIndex_Activity_ChapterKeyHasher { + std::size_t operator()(const LeveledIndex_Activity_ChapterKey& key) const { + return util::SugaredHashCombine(key.activity_id, key.chapter_id); + } + }; + struct LeveledIndex_protoconf_SectionKey { + uint64_t activity_id; + uint32_t chapter_id; + uint32_t section_id; +#if __cplusplus >= 202002L + bool operator==(const LeveledIndex_protoconf_SectionKey& other) const = default; +#else + bool operator==(const LeveledIndex_protoconf_SectionKey& other) const { + return std::tie(activity_id, chapter_id, section_id) == std::tie(other.activity_id, other.chapter_id, other.section_id); + } +#endif + }; + struct LeveledIndex_protoconf_SectionKeyHasher { + std::size_t operator()(const LeveledIndex_protoconf_SectionKey& key) const { + return util::SugaredHashCombine(key.activity_id, key.chapter_id, key.section_id); + } + }; + // Index accessers. // Index: ActivityName public: @@ -80,9 +116,18 @@ class ActivityConf : public Messager { const Index_ChapterVector* FindChapter(uint32_t chapter_id) const; // Finds the first value of the given key(s). const protoconf::ActivityConf::Activity::Chapter* FindFirstChapter(uint32_t chapter_id) const; + // Finds the index (ChapterID) to value (Index_ChapterVector) hash map + // specified by (activity_id). + // One key may correspond to multiple values, which are contained by a vector. + const Index_ChapterMap* FindChapterMap(uint64_t activity_id) const; + // Finds a vector of all values of the given key(s) specified by (activity_id). + const Index_ChapterVector* FindChapter(uint64_t activity_id, uint32_t chapter_id) const; + // Finds the first value of the given key(s) specified by (activity_id). + const protoconf::ActivityConf::Activity::Chapter* FindFirstChapter(uint64_t activity_id, uint32_t chapter_id) const; private: Index_ChapterMap index_chapter_map_; + std::unordered_map index_chapter_map1_; // Index: ChapterName@NamedChapter public: @@ -95,9 +140,18 @@ class ActivityConf : public Messager { const Index_NamedChapterVector* FindNamedChapter(const std::string& chapter_name) const; // Finds the first value of the given key(s). const protoconf::ActivityConf::Activity::Chapter* FindFirstNamedChapter(const std::string& chapter_name) const; + // Finds the index (ChapterName@NamedChapter) to value (Index_NamedChapterVector) hash map + // specified by (activity_id). + // One key may correspond to multiple values, which are contained by a vector. + const Index_NamedChapterMap* FindNamedChapterMap(uint64_t activity_id) const; + // Finds a vector of all values of the given key(s) specified by (activity_id). + const Index_NamedChapterVector* FindNamedChapter(uint64_t activity_id, const std::string& chapter_name) const; + // Finds the first value of the given key(s) specified by (activity_id). + const protoconf::ActivityConf::Activity::Chapter* FindFirstNamedChapter(uint64_t activity_id, const std::string& chapter_name) const; private: Index_NamedChapterMap index_named_chapter_map_; + std::unordered_map index_named_chapter_map1_; // Index: SectionItemID@Award public: @@ -110,9 +164,36 @@ class ActivityConf : public Messager { const Index_AwardVector* FindAward(uint32_t id) const; // Finds the first value of the given key(s). const protoconf::Section::SectionItem* FindFirstAward(uint32_t id) const; + // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map + // specified by (activity_id). + // One key may correspond to multiple values, which are contained by a vector. + const Index_AwardMap* FindAwardMap(uint64_t activity_id) const; + // Finds a vector of all values of the given key(s) specified by (activity_id). + const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t id) const; + // Finds the first value of the given key(s) specified by (activity_id). + const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t id) const; + // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map + // specified by (activity_id, chapter_id). + // One key may correspond to multiple values, which are contained by a vector. + const Index_AwardMap* FindAwardMap(uint64_t activity_id, uint32_t chapter_id) const; + // Finds a vector of all values of the given key(s) specified by (activity_id, chapter_id). + const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const; + // Finds the first value of the given key(s) specified by (activity_id, chapter_id). + const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const; + // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map + // specified by (activity_id, chapter_id, section_id). + // One key may correspond to multiple values, which are contained by a vector. + const Index_AwardMap* FindAwardMap(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id) const; + // Finds a vector of all values of the given key(s) specified by (activity_id, chapter_id, section_id). + const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const; + // Finds the first value of the given key(s) specified by (activity_id, chapter_id, section_id). + const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const; private: Index_AwardMap index_award_map_; + std::unordered_map index_award_map1_; + std::unordered_map index_award_map2_; + std::unordered_map index_award_map3_; }; class ChapterConf : public Messager { diff --git a/test/proto/item_conf.proto b/test/proto/item_conf.proto index 7c143864..6cc03808 100644 --- a/test/proto/item_conf.proto +++ b/test/proto/item_conf.proto @@ -77,4 +77,21 @@ message UseEffect { uint32 item_id = 1 [(tableau.field) = { name: "ItemId" }]; } message AccountLevel {} +} + +message FruitConf { + option (tableau.worksheet) = { + name: "FruitConf" + ordered_index: "Price" + }; + + map fruits_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; + message Fruits { + protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; + map fruit_map = 2 [(tableau.field) = { key: "FruitID" layout: LAYOUT_VERTICAL }]; + message Fruit { + int32 fruit_id = 1 [(tableau.field) = { name: "FruitID" }]; + int32 price = 2 [(tableau.field) = { name: "Price" }]; + } + } } \ No newline at end of file diff --git a/test/testdata/conf/FruitConf.json b/test/testdata/conf/FruitConf.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/test/testdata/conf/FruitConf.json @@ -0,0 +1 @@ +{} \ No newline at end of file From d61a243ab701d9fdb8a020208ffc9b46647363ed Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 18 Nov 2025 21:03:18 +0800 Subject: [PATCH 03/15] feat: go level-index generator --- .../helper/helper.go | 22 +- .../index/index.go | 161 ++++++++-- .../leveledindex/leveled_index.go | 81 +++++ cmd/protoc-gen-go-tableau-loader/messager.go | 9 +- .../orderedindex/ordered_index.go | 170 +++++++++-- .../orderedmap/ordered_map.go | 19 +- .../protoconf/loader/hero_conf.pc.go | 38 ++- .../protoconf/loader/hub.pc.go | 4 + .../protoconf/loader/item_conf.pc.go | 288 +++++++++++++++--- .../protoconf/loader/messager_container.pc.go | 6 + .../protoconf/loader/test_conf.pc.go | 260 +++++++++++++--- 11 files changed, 901 insertions(+), 157 deletions(-) create mode 100644 cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go diff --git a/cmd/protoc-gen-go-tableau-loader/helper/helper.go b/cmd/protoc-gen-go-tableau-loader/helper/helper.go index 669cca52..2b2818d7 100644 --- a/cmd/protoc-gen-go-tableau-loader/helper/helper.go +++ b/cmd/protoc-gen-go-tableau-loader/helper/helper.go @@ -37,7 +37,7 @@ func ParseIndexFieldNameAsFuncParam(gen *protogen.Plugin, fd protoreflect.FieldD if fieldName == "" { return fieldName } - return escapeIdentifier(strings.ToLower(fieldName[:1]) + fieldName[1:]) + return escapeIdentifier(fieldName) } // ParseGoType converts a FieldDescriptor to its Go type. @@ -130,7 +130,7 @@ func ParseOrderedIndexKeyType(gen *protogen.Plugin, g *protogen.GeneratedFile, f } } -func ParseMapFieldName(fd protoreflect.FieldDescriptor) string { +func ParseMapFieldNameAsKeyStructFieldName(fd protoreflect.FieldDescriptor) string { opts := fd.Options().(*descriptorpb.FieldOptions) fdOpts := proto.GetExtension(opts, tableaupb.E_Field).(*tableaupb.FieldOptions) name := fdOpts.GetKey() @@ -138,7 +138,15 @@ func ParseMapFieldName(fd protoreflect.FieldDescriptor) string { valueFd := fd.MapValue().Message().Fields().Get(0) name = string(valueFd.Name()) } - return escapeIdentifier(name) + return strcase.ToCamel(name) +} + +func ParseMapFieldNameAsFuncParam(fd protoreflect.FieldDescriptor) string { + fieldName := ParseMapFieldNameAsKeyStructFieldName(fd) + if fieldName == "" { + return fieldName + } + return escapeIdentifier(fieldName) } func ParseMapValueType(gen *protogen.Plugin, g *protogen.GeneratedFile, fd protoreflect.FieldDescriptor) string { @@ -242,6 +250,14 @@ func GetTypeEmptyValue(fd protoreflect.FieldDescriptor) string { } } +func ParseLeveledMapPrefix(md protoreflect.MessageDescriptor, mapFd protoreflect.FieldDescriptor) string { + if mapFd.MapValue().Kind() == protoreflect.MessageKind { + localMsgProtoName := strings.TrimPrefix(string(mapFd.MapValue().Message().FullName()), string(md.FullName())+".") + return strings.ReplaceAll(localMsgProtoName, ".", "_") + } + return mapFd.MapValue().Kind().String() +} + type MapKey struct { Type string Name string diff --git a/cmd/protoc-gen-go-tableau-loader/index/index.go b/cmd/protoc-gen-go-tableau-loader/index/index.go index 03278700..a792d3de 100644 --- a/cmd/protoc-gen-go-tableau-loader/index/index.go +++ b/cmd/protoc-gen-go-tableau-loader/index/index.go @@ -2,9 +2,11 @@ package index import ( "fmt" + "strings" "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" + "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" @@ -16,14 +18,16 @@ type Generator struct { g *protogen.GeneratedFile descriptor *index.IndexDescriptor message *protogen.Message + level *leveledindex.Generator } -func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { +func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { return &Generator{ gen: gen, g: g, descriptor: descriptor, message: message, + level: level, } } @@ -58,6 +62,10 @@ func (x *Generator) indexContainerName(index *index.LevelIndex) string { return fmt.Sprintf("index%sMap", strcase.ToCamel(index.Name())) } +func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { + return fmt.Sprintf("index%sMap%d", strcase.ToCamel(index.Name()), i) +} + func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { var keys helper.MapKeys for _, field := range index.ColFields { @@ -116,6 +124,17 @@ func (x *Generator) GenIndexField() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { x.g.P(x.indexContainerName(index), " ", x.mapType(index)) + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P(x.indexContainerNameI(index, i), " map[", x.level.Keys[0].Type, "]", x.mapType(index)) + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P(x.indexContainerNameI(index, i), " map[", leveledIndexKeyType, "]", x.mapType(index)) + } + } } } } @@ -124,33 +143,42 @@ func (x *Generator) GenIndexLoader() { if !x.needGenerate() { return } + defer x.genIndexSorter() x.g.P("// Index init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { x.g.P("x.", x.indexContainerName(index), " = make(", x.mapType(index), ")") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", x.level.Keys[0].Type, "]", x.mapType(index), ")") + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", leveledIndexKeyType, "]", x.mapType(index), ")") + } + } } } parentDataName := "x.data" - depth := 1 for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.genOneIndexLoader(index, depth, parentDataName) + x.genOneIndexLoader(index, levelMessage.Depth, parentDataName) } - itemName := fmt.Sprintf("item%d", depth) + keyName := fmt.Sprintf("k%d", levelMessage.Depth) + valueName := fmt.Sprintf("v%d", levelMessage.Depth) if levelMessage.FD == nil { break } if !levelMessage.NextLevel.NeedGen() { break } - x.g.P("for _, ", itemName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") - parentDataName = itemName - depth++ - } - for i := depth - 1; i > 0; i-- { - x.g.P("}") + x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") + x.g.P("_ = ", keyName) + parentDataName = valueName + defer x.g.P("}") } - x.genIndexSorter() } func (x *Generator) genOneIndexLoader(index *index.LevelIndex, depth int, parentDataName string) { @@ -160,16 +188,17 @@ func (x *Generator) genOneIndexLoader(index *index.LevelIndex, depth int, parent // single-column index field := index.ColFields[0] // just take the first field fieldName := x.parseKeyFieldName(field) - indexContainerName := x.indexContainerName(index) if field.FD.IsList() { - itemName := fmt.Sprintf("item%d", depth) - x.g.P("for _, ", itemName, " := range ", parentDataName, fieldName, " {") - x.g.P("key := ", itemName) - x.g.P("x.", indexContainerName, "[key] = append(x.", indexContainerName, "[key], ", parentDataName, ")") + keyName := fmt.Sprintf("k%d", depth) + valueName := fmt.Sprintf("v%d", depth) + x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, fieldName, " {") + x.g.P("_ = ", keyName) + x.g.P("key := ", valueName) + x.genLoader(depth, index, parentDataName) x.g.P("}") } else { x.g.P("key := ", parentDataName, fieldName) - x.g.P("x.", indexContainerName, "[key] = append(x.", indexContainerName, "[key], ", parentDataName, ")") + x.genLoader(depth, index, parentDataName) } } else { // multi-column index @@ -182,9 +211,8 @@ func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelInd cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.mapKeyType(index) - indexContainerName := x.indexContainerName(index) x.g.P("key := ", keyType, " {", keys.GenGetArguments(), "}") - x.g.P("x.", indexContainerName, "[key] = append(x.", indexContainerName, "[key], ", parentDataName, ")") + x.genLoader(depth, index, parentDataName) return } field := index.ColFields[cursor] @@ -193,7 +221,7 @@ func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelInd itemName := fmt.Sprintf("indexItem%d", cursor) x.g.P("for _, ", itemName, " := range ", parentDataName, fieldName, " {") keys = keys.AddMapKey(helper.MapKey{Name: itemName}) - x.generateOneMulticolumnIndex(depth+1, index, parentDataName, keys) + x.generateOneMulticolumnIndex(depth, index, parentDataName, keys) x.g.P("}") } else { key := parentDataName + fieldName @@ -202,13 +230,43 @@ func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelInd } } +func (x *Generator) genLoader(depth int, index *index.LevelIndex, parentDataName string) { + indexContainerName := x.indexContainerName(index) + x.g.P("x.", indexContainerName, "[key] = append(x.", indexContainerName, "[key], ", parentDataName, ")") + for i := 1; i <= depth-2; i++ { + if i > len(x.level.Keys) { + break + } + indexContainerNameI := x.indexContainerNameI(index, i) + if i == 1 { + x.g.P("if x.", indexContainerNameI, "[k1] == nil {") + x.g.P("x.", indexContainerNameI, "[k1] = make(", x.mapType(index), ")") + x.g.P("}") + x.g.P("x.", indexContainerNameI, "[k1][key] = append(x.", indexContainerNameI, "[k1][key], ", parentDataName, ")") + } else { + var fields []string + for j := 1; j <= i; j++ { + fields = append(fields, fmt.Sprintf("k%d", j)) + } + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + keyName := indexContainerNameI + "Keys" + x.g.P(keyName, " := ", leveledIndexKeyType, "{", strings.Join(fields, ", "), "}") + x.g.P("if x.", indexContainerNameI, "[", keyName, "] == nil {") + x.g.P("x.", indexContainerNameI, "[", keyName, "] = make(", x.mapType(index), ")") + x.g.P("}") + x.g.P("x.", indexContainerNameI, "[", keyName, "][key] = append(x.", indexContainerNameI, "[", keyName, "][key], ", parentDataName, ")") + } + } +} + func (x *Generator) genIndexSorter() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { if len(index.SortedColFields) != 0 { x.g.P("// Index(sort): ", index.Index) - x.g.P("for _, item := range x.", x.indexContainerName(index), " {") - x.g.P(helper.SortPackage.Ident("Slice"), "(item, func(i, j int) bool {") + indexContainerName := x.indexContainerName(index) + x.g.P(indexContainerName, "Sorter := func(item []*", x.mapValueType(index), ") func(i, j int) bool {") + x.g.P("return func(i, j int) bool {") for i, field := range index.SortedColFields { fieldName := x.parseKeyFieldName(field) if i == len(index.SortedColFields)-1 { @@ -219,8 +277,21 @@ func (x *Generator) genIndexSorter() { x.g.P("}") } } - x.g.P("})") x.g.P("}") + x.g.P("}") + x.g.P("for _, item := range x.", x.indexContainerName(index), " {") + x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") + x.g.P("}") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + x.g.P("for _, item := range x.", x.indexContainerNameI(index, i), " {") + x.g.P("for _, item1 := range item {") + x.g.P(helper.SortPackage.Ident("Slice"), "(item1, ", indexContainerName, "Sorter(item1))") + x.g.P("}") + x.g.P("}") + } } } } @@ -267,6 +338,50 @@ func (x *Generator) GenIndexFinders() { x.g.P("return nil") x.g.P("}") x.g.P() + + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + indexContainerNameI := x.indexContainerNameI(index, i) + partKeys := x.level.Keys[:i] + partParams := partKeys.GenGetParams() + partArgs := partKeys.GenGetArguments() + + x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") map") + x.g.P("// specified by (", partArgs, ").") + x.g.P("// One key may correspond to multiple values, which are contained by a slice.") + x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") ", x.mapType(index), " {") + if len(partKeys) == 1 { + x.g.P("return x.", indexContainerNameI, "[", partArgs, "]") + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P("return x.", indexContainerNameI, "[", leveledIndexKeyType, "{", partArgs, "}]") + } + x.g.P("}") + x.g.P() + + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key specified by (", partArgs, ").") + x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") + if len(index.ColFields) == 1 { + x.g.P("return x.Find", index.Name(), "Map", i, "(", partArgs, ")[", args, "]") + } else { + x.g.P("return x.Find", index.Name(), "Map", i, "(", partArgs, ")[", x.mapKeyType(index), "{", args, "}]") + } + x.g.P("}") + x.g.P() + + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key specified by (", partArgs, "),") + x.g.P("// or nil if no value found.") + x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") + x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") + x.g.P("if len(val) > 0 {") + x.g.P("return val[0]") + x.g.P("}") + x.g.P("return nil") + x.g.P("}") + x.g.P() + } } } } diff --git a/cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go b/cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go new file mode 100644 index 00000000..e13799e0 --- /dev/null +++ b/cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go @@ -0,0 +1,81 @@ +package leveledindex + +import ( + "fmt" + + "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" + "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/options" + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/reflect/protoreflect" +) + +type Generator struct { + gen *protogen.Plugin + g *protogen.GeneratedFile + descriptor *index.IndexDescriptor + message *protogen.Message + + maxDepth int + Keys helper.MapKeys + MapFds []protoreflect.FieldDescriptor +} + +func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { + generator := &Generator{ + gen: gen, + g: g, + descriptor: descriptor, + message: message, + } + generator.init() + return generator +} + +func (x *Generator) init() { + for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { + if fd := levelMessage.FD; fd != nil && fd.IsMap() { + x.Keys = x.Keys.AddMapKey(helper.MapKey{ + Type: helper.ParseMapKeyType(fd.MapKey()), + Name: helper.ParseMapFieldNameAsFuncParam(fd), + FieldName: helper.ParseMapFieldNameAsKeyStructFieldName(fd), + }) + x.MapFds = append(x.MapFds, fd) + } + if len(levelMessage.Indexes) != 0 || len(levelMessage.OrderedIndexes) != 0 { + x.maxDepth = levelMessage.Depth + } + } +} + +func (x *Generator) NeedGenerate() bool { + return options.NeedGenIndex(x.message.Desc, options.LangCPP) || options.NeedGenOrderedIndex(x.message.Desc, options.LangCPP) +} + +func (x *Generator) messagerName() string { + return string(x.message.Desc.Name()) +} + +func (x *Generator) KeyType(mapFd protoreflect.FieldDescriptor) string { + return fmt.Sprintf("%s_LeveledIndex_%sKey", x.messagerName(), helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) +} + +func (x *Generator) GenLeveledIndexTypeDef() { + if !x.NeedGenerate() { + return + } + for i := 1; i <= x.maxDepth-3 && i <= len(x.MapFds)-1; i++ { + if i == 1 { + x.g.P() + x.g.P("// LeveledIndex keys.") + } + fd := x.MapFds[i] + keyType := x.KeyType(fd) + keys := x.Keys[:i+1] + x.g.P("type ", keyType, " struct {") + for _, key := range keys { + x.g.P(key.FieldName, " ", key.Type) + } + x.g.P("}") + } +} diff --git a/cmd/protoc-gen-go-tableau-loader/messager.go b/cmd/protoc-gen-go-tableau-loader/messager.go index a4f32cbf..4bee71dd 100644 --- a/cmd/protoc-gen-go-tableau-loader/messager.go +++ b/cmd/protoc-gen-go-tableau-loader/messager.go @@ -5,6 +5,7 @@ import ( "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" idx "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/index" + "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/leveledindex" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/orderedindex" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/orderedmap" "github.com/tableauio/loader/internal/extensions" @@ -66,11 +67,13 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog indexDescriptor := index.ParseIndexDescriptor(message.Desc) orderedMapGenerator := orderedmap.NewGenerator(gen, g, message) - indexGenerator := idx.NewGenerator(gen, g, indexDescriptor, message) - orderedIndexGenerator := orderedindex.NewGenerator(gen, g, indexDescriptor, message) + leveledIndexGenerator := leveledindex.NewGenerator(gen, g, indexDescriptor, message) + indexGenerator := idx.NewGenerator(gen, g, indexDescriptor, message, leveledIndexGenerator) + orderedIndexGenerator := orderedindex.NewGenerator(gen, g, indexDescriptor, message, leveledIndexGenerator) // type definitions orderedMapGenerator.GenOrderedMapTypeDef() + leveledIndexGenerator.GenLeveledIndexTypeDef() indexGenerator.GenIndexTypeDef() orderedIndexGenerator.GenOrderedIndexTypeDef() @@ -177,7 +180,7 @@ func genMapGetters(gen *protogen.Plugin, g *protogen.GeneratedFile, message *pro if fd.IsMap() { keys = keys.AddMapKey(helper.MapKey{ Type: helper.ParseMapKeyType(fd.MapKey()), - Name: helper.ParseMapFieldName(fd), + Name: helper.ParseMapFieldNameAsFuncParam(fd), }) getter := fmt.Sprintf("Get%v", depth) g.P("// ", getter, " finds value in the ", depth, "-level map. It will return") diff --git a/cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go b/cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go index 96f619e0..6959bbb0 100644 --- a/cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go +++ b/cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go @@ -2,9 +2,11 @@ package orderedindex import ( "fmt" + "strings" "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" + "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" @@ -16,14 +18,16 @@ type Generator struct { g *protogen.GeneratedFile descriptor *index.IndexDescriptor message *protogen.Message + level *leveledindex.Generator } -func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { +func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { return &Generator{ gen: gen, g: g, descriptor: descriptor, message: message, + level: level, } } @@ -58,6 +62,10 @@ func (x *Generator) indexContainerName(index *index.LevelIndex) string { return fmt.Sprintf("orderedIndex%sMap", strcase.ToCamel(index.Name())) } +func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { + return fmt.Sprintf("orderedIndex%sMap%d", strcase.ToCamel(index.Name()), i) +} + func (x *Generator) mapCtor(index *index.LevelIndex) string { if len(index.ColFields) == 1 { // single-column index @@ -147,6 +155,17 @@ func (x *Generator) GenOrderedIndexField() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { x.g.P(x.indexContainerName(index), " *", x.mapType(index)) + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P(x.indexContainerNameI(index, i), " map[", x.level.Keys[0].Type, "]*", x.mapType(index)) + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P(x.indexContainerNameI(index, i), " map[", leveledIndexKeyType, "]*", x.mapType(index)) + } + } } } } @@ -155,33 +174,42 @@ func (x *Generator) GenOrderedIndexLoader() { if !x.needGenerate() { return } + defer x.genOrderedIndexSorter() x.g.P("// OrderedIndex init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { x.g.P("x.", x.indexContainerName(index), " = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]()") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + if i == 1 { + x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", x.level.Keys[0].Type, "]*", x.mapType(index), ")") + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", leveledIndexKeyType, "]*", x.mapType(index), ")") + } + } } } parentDataName := "x.data" - depth := 1 for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.genOneOrderedIndexLoader(index, depth, parentDataName) + x.genOneOrderedIndexLoader(index, levelMessage.Depth, parentDataName) } - itemName := fmt.Sprintf("item%d", depth) + keyName := fmt.Sprintf("k%d", levelMessage.Depth) + valueName := fmt.Sprintf("v%d", levelMessage.Depth) if levelMessage.FD == nil { break } if !levelMessage.NextLevel.NeedGen() { break } - x.g.P("for _, ", itemName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") - parentDataName = itemName - depth++ + x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") + x.g.P("_ = ", keyName) + parentDataName = valueName + defer x.g.P("}") } - for i := depth - 1; i > 0; i-- { - x.g.P("}") - } - x.genOrderedIndexSorter() } func (x *Generator) genOneOrderedIndexLoader(index *index.LevelIndex, depth int, parentDataName string) { @@ -191,18 +219,17 @@ func (x *Generator) genOneOrderedIndexLoader(index *index.LevelIndex, depth int, // single-column index field := index.ColFields[0] // just take the first field fieldName, suffix := x.parseKeyFieldNameAndSuffix(field) - indexContainerName := x.indexContainerName(index) if field.FD.IsList() { - itemName := fmt.Sprintf("item%d", depth) - x.g.P("for _, ", itemName, " := range ", parentDataName, fieldName, " {") - x.g.P("key := ", itemName, suffix) - x.g.P("value, _ := x.", indexContainerName, ".Get(key)") - x.g.P("x.", indexContainerName, ".Put(key, append(value, ", parentDataName, "))") + keyName := fmt.Sprintf("k%d", depth) + valueName := fmt.Sprintf("v%d", depth) + x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, fieldName, " {") + x.g.P("_ = ", keyName) + x.g.P("key := ", valueName, suffix) + x.genLoader(depth, index, parentDataName) x.g.P("}") } else { x.g.P("key := ", parentDataName, fieldName, suffix) - x.g.P("value, _ := x.", indexContainerName, ".Get(key)") - x.g.P("x.", indexContainerName, ".Put(key, append(value, ", parentDataName, "))") + x.genLoader(depth, index, parentDataName) } } else { // multi-column index @@ -215,10 +242,8 @@ func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.L cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.mapKeyType(index) - indexContainerName := x.indexContainerName(index) x.g.P("key := ", keyType, " {", keys.GenGetArguments(), "}") - x.g.P("value, _ := x.", indexContainerName, ".Get(key)") - x.g.P("x.", indexContainerName, ".Put(key, append(value, ", parentDataName, "))") + x.genLoader(depth, index, parentDataName) return } field := index.ColFields[cursor] @@ -228,7 +253,7 @@ func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.L x.g.P("for _, ", itemName, " := range ", parentDataName, fieldName, " {") key := itemName + suffix keys = keys.AddMapKey(helper.MapKey{Name: key}) - x.generateOneMulticolumnOrderedIndex(depth+1, index, parentDataName, keys) + x.generateOneMulticolumnOrderedIndex(depth, index, parentDataName, keys) x.g.P("}") } else { key := parentDataName + fieldName + suffix @@ -237,13 +262,47 @@ func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.L } } +func (x *Generator) genLoader(depth int, index *index.LevelIndex, parentDataName string) { + indexContainerName := x.indexContainerName(index) + x.g.P("value, _ := x.", indexContainerName, ".Get(key)") + x.g.P("x.", indexContainerName, ".Put(key, append(value, ", parentDataName, "))") + for i := 1; i <= depth-2; i++ { + if i > len(x.level.Keys) { + break + } + indexContainerNameI := x.indexContainerNameI(index, i) + valueName := indexContainerNameI + "Value" + if i == 1 { + x.g.P("if x.", indexContainerNameI, "[k1] == nil {") + x.g.P("x.", indexContainerNameI, "[k1] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]()") + x.g.P("}") + x.g.P(valueName, ", _ := x.", indexContainerNameI, "[k1].Get(key)") + x.g.P("x.", indexContainerNameI, "[k1].Put(key, append(", valueName, ", ", parentDataName, "))") + } else { + var fields []string + for j := 1; j <= i; j++ { + fields = append(fields, fmt.Sprintf("k%d", j)) + } + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + keyName := indexContainerNameI + "Keys" + x.g.P(keyName, " := ", leveledIndexKeyType, "{", strings.Join(fields, ", "), "}") + x.g.P("if x.", indexContainerNameI, "[", keyName, "] == nil {") + x.g.P("x.", indexContainerNameI, "[", keyName, "] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]()") + x.g.P("}") + x.g.P(valueName, ", _ := x.", indexContainerNameI, "[", keyName, "].Get(key)") + x.g.P("x.", indexContainerNameI, "[", keyName, "].Put(key, append(", valueName, ", ", parentDataName, "))") + } + } +} + func (x *Generator) genOrderedIndexSorter() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { if len(index.SortedColFields) != 0 { x.g.P("// OrderedIndex(sort): ", index.Index) - x.g.P("x.", x.indexContainerName(index), ".Range(func(key ", x.mapKeyType(index), ", item []*", x.mapValueType(index), ") bool {") - x.g.P(helper.SortPackage.Ident("Slice"), "(item, func(i, j int) bool {") + indexContainerName := x.indexContainerName(index) + x.g.P(indexContainerName, "Sorter := func(item []*", x.mapValueType(index), ") func(i, j int) bool {") + x.g.P("return func(i, j int) bool {") for i, field := range index.SortedColFields { fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if i == len(index.SortedColFields)-1 { @@ -254,9 +313,23 @@ func (x *Generator) genOrderedIndexSorter() { x.g.P("}") } } - x.g.P("})") + x.g.P("}") + x.g.P("}") + x.g.P("x.", x.indexContainerName(index), ".Range(func(key ", x.mapKeyType(index), ", item []*", x.mapValueType(index), ") bool {") + x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") x.g.P("return true") x.g.P("})") + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + x.g.P("for _, item := range x.", x.indexContainerNameI(index, i), " {") + x.g.P("item.Range(func(key ", x.mapKeyType(index), ", item1 []*", x.mapValueType(index), ") bool {") + x.g.P(helper.SortPackage.Ident("Slice"), "(item1, ", indexContainerName, "Sorter(item1))") + x.g.P("return true") + x.g.P("})") + x.g.P("}") + } } } } @@ -304,6 +377,51 @@ func (x *Generator) GenOrderedIndexFinders() { x.g.P("return nil") x.g.P("}") x.g.P() + + for i := 1; i <= levelMessage.Depth-2; i++ { + if i > len(x.level.Keys) { + break + } + indexContainerNameI := x.indexContainerNameI(index, i) + partKeys := x.level.Keys[:i] + partParams := partKeys.GenGetParams() + partArgs := partKeys.GenGetArguments() + + x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") treemap") + x.g.P("// specified by (", partArgs, ").") + x.g.P("// One key may correspond to multiple values, which are contained by a slice.") + x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") *", x.mapType(index), " {") + if len(partKeys) == 1 { + x.g.P("return x.", indexContainerNameI, "[", partArgs, "]") + } else { + leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) + x.g.P("return x.", indexContainerNameI, "[", leveledIndexKeyType, "{", partArgs, "}]") + } + x.g.P("}") + x.g.P() + + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key specified by (", partArgs, ").") + x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") + if len(index.ColFields) == 1 { + x.g.P("val, _ := x.Find", index.Name(), "Map", i, "(", partArgs, ").Get(", args, ")") + } else { + x.g.P("val, _ := x.Find", index.Name(), "Map", i, "(", partArgs, ").Get(", x.mapKeyType(index), "{", args, "})") + } + x.g.P("return val") + x.g.P("}") + x.g.P() + + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key specified by (", partArgs, "),") + x.g.P("// or nil if no value found.") + x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") + x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") + x.g.P("if len(val) > 0 {") + x.g.P("return val[0]") + x.g.P("}") + x.g.P("return nil") + x.g.P("}") + x.g.P() + } } } } diff --git a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go index f671ce70..6990de39 100644 --- a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go +++ b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go @@ -2,7 +2,6 @@ package orderedmap import ( "fmt" - "strings" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" "github.com/tableauio/loader/internal/options" @@ -32,20 +31,12 @@ func (x *Generator) messagerName() string { return string(x.message.Desc.Name()) } -func (x *Generator) orderedMapPrefix(mapFd protoreflect.FieldDescriptor) string { - if mapFd.MapValue().Kind() == protoreflect.MessageKind { - localMsgProtoName := strings.TrimPrefix(string(mapFd.MapValue().Message().FullName()), string(x.message.Desc.FullName())+".") - return strings.ReplaceAll(localMsgProtoName, ".", "_") - } - return mapFd.MapValue().Kind().String() -} - func (x *Generator) mapType(mapFd protoreflect.FieldDescriptor) string { - return fmt.Sprintf("%s_OrderedMap_%sMap", x.messagerName(), x.orderedMapPrefix(mapFd)) + return fmt.Sprintf("%s_OrderedMap_%sMap", x.messagerName(), helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } func (x *Generator) mapValueType(mapFd protoreflect.FieldDescriptor) string { - return fmt.Sprintf("%s_OrderedMap_%sValue", x.messagerName(), x.orderedMapPrefix(mapFd)) + return fmt.Sprintf("%s_OrderedMap_%sValue", x.messagerName(), helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } func (x *Generator) mapValueFieldType(fd protoreflect.FieldDescriptor) string { @@ -70,7 +61,7 @@ func (x *Generator) genOrderedMapTypeDef(md protoreflect.MessageDescriptor, dept if fd.IsMap() { nextKeys := keys.AddMapKey(helper.MapKey{ Type: helper.ParseMapKeyType(fd.MapKey()), - Name: helper.ParseMapFieldName(fd), + Name: helper.ParseMapFieldNameAsFuncParam(fd), }) keyType := nextKeys[len(nextKeys)-1].Type if keyType == "bool" { @@ -124,7 +115,7 @@ func (x *Generator) genOrderedMapLoader(md protoreflect.MessageDescriptor, depth needConvertBool := len(keys) > 0 && keys[len(keys)-1].Type == "int" nextKeys := keys.AddMapKey(helper.MapKey{ Type: helper.ParseMapKeyType(fd.MapKey()), - Name: helper.ParseMapFieldName(fd), + Name: helper.ParseMapFieldNameAsFuncParam(fd), }) keyType := nextKeys[len(nextKeys)-1].Type needConvertBoolNext := keyType == "bool" @@ -226,7 +217,7 @@ func (x *Generator) genOrderedMapGetters(md protoreflect.MessageDescriptor, dept nextKeys := keys.AddMapKey(helper.MapKey{ Type: helper.ParseMapKeyType(fd.MapKey()), - Name: helper.ParseMapFieldName(fd), + Name: helper.ParseMapFieldNameAsFuncParam(fd), }) if fd.MapValue().Kind() == protoreflect.MessageKind { x.genOrderedMapGetters(fd.MapValue().Message(), depth+1, nextKeys) diff --git a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go index a27aa011..4d764c1e 100644 --- a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go @@ -34,6 +34,7 @@ type HeroConf struct { UnimplementedMessager data, originalData *protoconf.HeroConf indexAttrMap HeroConf_Index_AttrMap + indexAttrMap1 map[string]HeroConf_Index_AttrMap } // Name returns the HeroConf's message name. @@ -94,12 +95,19 @@ func (x *HeroConf) originalMessage() proto.Message { func (x *HeroConf) processAfterLoad() error { // Index init. x.indexAttrMap = make(HeroConf_Index_AttrMap) - for _, item1 := range x.data.GetHeroMap() { - for _, item2 := range item1.GetAttrMap() { + x.indexAttrMap1 = make(map[string]HeroConf_Index_AttrMap) + for k1, v1 := range x.data.GetHeroMap() { + _ = k1 + for k2, v2 := range v1.GetAttrMap() { + _ = k2 { // Index: Title - key := item2.GetTitle() - x.indexAttrMap[key] = append(x.indexAttrMap[key], item2) + key := v2.GetTitle() + x.indexAttrMap[key] = append(x.indexAttrMap[key], v2) + if x.indexAttrMap1[k1] == nil { + x.indexAttrMap1[k1] = make(HeroConf_Index_AttrMap) + } + x.indexAttrMap1[k1][key] = append(x.indexAttrMap1[k1][key], v2) } } } @@ -155,6 +163,28 @@ func (x *HeroConf) FindFirstAttr(title string) *protoconf.HeroConf_Hero_Attr { return nil } +// FindAttrMap1 finds the index (Title) to value (protoconf.HeroConf_Hero_Attr) map +// specified by (name). +// One key may correspond to multiple values, which are contained by a slice. +func (x *HeroConf) FindAttrMap1(name string) HeroConf_Index_AttrMap { + return x.indexAttrMap1[name] +} + +// FindAttr1 finds a slice of all values of the given key specified by (name). +func (x *HeroConf) FindAttr1(name string, title string) []*protoconf.HeroConf_Hero_Attr { + return x.FindAttrMap1(name)[title] +} + +// FindFirstAttr1 finds the first value of the given key specified by (name), +// or nil if no value found. +func (x *HeroConf) FindFirstAttr1(name string, title string) *protoconf.HeroConf_Hero_Attr { + val := x.FindAttr1(name, title) + if len(val) > 0 { + return val[0] + } + return nil +} + // OrderedMap types. type HeroBaseConf_OrderedMap_base_ItemMap = treemap.TreeMap[string, *base.Item] diff --git a/test/go-tableau-loader/protoconf/loader/hub.pc.go b/test/go-tableau-loader/protoconf/loader/hub.pc.go index ab33e062..1d737393 100644 --- a/test/go-tableau-loader/protoconf/loader/hub.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hub.pc.go @@ -224,6 +224,10 @@ func (h *Hub) GetItemConf() *ItemConf { return h.mc.Load().GetItemConf() } +func (h *Hub) GetFruitConf() *FruitConf { + return h.mc.Load().GetFruitConf() +} + func (h *Hub) GetPatchReplaceConf() *PatchReplaceConf { return h.mc.Load().GetPatchReplaceConf() } diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index e658b08e..fc972bbf 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -179,111 +179,126 @@ func (x *ItemConf) processAfterLoad() error { x.indexItemPathNameMap = make(ItemConf_Index_ItemPathNameMap) x.indexItemPathFriendIdMap = make(ItemConf_Index_ItemPathFriendIDMap) x.indexUseEffectTypeMap = make(ItemConf_Index_UseEffectTypeMap) - for _, item1 := range x.data.GetItemMap() { + for k1, v1 := range x.data.GetItemMap() { + _ = k1 { // Index: Type - key := item1.GetType() - x.indexItemMap[key] = append(x.indexItemMap[key], item1) + key := v1.GetType() + x.indexItemMap[key] = append(x.indexItemMap[key], v1) } { // Index: Param@ItemInfo - for _, item2 := range item1.GetParamList() { - key := item2 - x.indexItemInfoMap[key] = append(x.indexItemInfoMap[key], item1) + for k2, v2 := range v1.GetParamList() { + _ = k2 + key := v2 + x.indexItemInfoMap[key] = append(x.indexItemInfoMap[key], v1) } } { // Index: Default@ItemDefaultInfo - key := item1.GetDefault() - x.indexItemDefaultInfoMap[key] = append(x.indexItemDefaultInfoMap[key], item1) + key := v1.GetDefault() + x.indexItemDefaultInfoMap[key] = append(x.indexItemDefaultInfoMap[key], v1) } { // Index: ExtType@ItemExtInfo - for _, item2 := range item1.GetExtTypeList() { - key := item2 - x.indexItemExtInfoMap[key] = append(x.indexItemExtInfoMap[key], item1) + for k2, v2 := range v1.GetExtTypeList() { + _ = k2 + key := v2 + x.indexItemExtInfoMap[key] = append(x.indexItemExtInfoMap[key], v1) } } { // Index: (ID,Name)@AwardItem - key := ItemConf_Index_AwardItemKey{item1.GetId(), item1.GetName()} - x.indexAwardItemMap[key] = append(x.indexAwardItemMap[key], item1) + key := ItemConf_Index_AwardItemKey{v1.GetId(), v1.GetName()} + x.indexAwardItemMap[key] = append(x.indexAwardItemMap[key], v1) } { // Index: (ID,Type,Param,ExtType)@SpecialItem - for _, indexItem2 := range item1.GetParamList() { - for _, indexItem3 := range item1.GetExtTypeList() { - key := ItemConf_Index_SpecialItemKey{item1.GetId(), item1.GetType(), indexItem2, indexItem3} - x.indexSpecialItemMap[key] = append(x.indexSpecialItemMap[key], item1) + for _, indexItem2 := range v1.GetParamList() { + for _, indexItem3 := range v1.GetExtTypeList() { + key := ItemConf_Index_SpecialItemKey{v1.GetId(), v1.GetType(), indexItem2, indexItem3} + x.indexSpecialItemMap[key] = append(x.indexSpecialItemMap[key], v1) } } } { // Index: PathDir@ItemPathDir - key := item1.GetPath().GetDir() - x.indexItemPathDirMap[key] = append(x.indexItemPathDirMap[key], item1) + key := v1.GetPath().GetDir() + x.indexItemPathDirMap[key] = append(x.indexItemPathDirMap[key], v1) } { // Index: PathName@ItemPathName - for _, item2 := range item1.GetPath().GetNameList() { - key := item2 - x.indexItemPathNameMap[key] = append(x.indexItemPathNameMap[key], item1) + for k2, v2 := range v1.GetPath().GetNameList() { + _ = k2 + key := v2 + x.indexItemPathNameMap[key] = append(x.indexItemPathNameMap[key], v1) } } { // Index: PathFriendID@ItemPathFriendID - key := item1.GetPath().GetFriend().GetId() - x.indexItemPathFriendIdMap[key] = append(x.indexItemPathFriendIdMap[key], item1) + key := v1.GetPath().GetFriend().GetId() + x.indexItemPathFriendIdMap[key] = append(x.indexItemPathFriendIdMap[key], v1) } { // Index: UseEffectType@UseEffectType - key := item1.GetUseEffect().GetType() - x.indexUseEffectTypeMap[key] = append(x.indexUseEffectTypeMap[key], item1) + key := v1.GetUseEffect().GetType() + x.indexUseEffectTypeMap[key] = append(x.indexUseEffectTypeMap[key], v1) } } // Index(sort): Param@ItemInfo - for _, item := range x.indexItemInfoMap { - sort.Slice(item, func(i, j int) bool { + indexItemInfoMapSorter := func(item []*protoconf.ItemConf_Item) func(i, j int) bool { + return func(i, j int) bool { return item[i].GetId() < item[j].GetId() - }) + } + } + for _, item := range x.indexItemInfoMap { + sort.Slice(item, indexItemInfoMapSorter(item)) } // Index(sort): (ID,Name)@AwardItem - for _, item := range x.indexAwardItemMap { - sort.Slice(item, func(i, j int) bool { + indexAwardItemMapSorter := func(item []*protoconf.ItemConf_Item) func(i, j int) bool { + return func(i, j int) bool { if item[i].GetType() != item[j].GetType() { return item[i].GetType() < item[j].GetType() } return item[i].GetUseEffect().GetType() < item[j].GetUseEffect().GetType() - }) + } + } + for _, item := range x.indexAwardItemMap { + sort.Slice(item, indexAwardItemMapSorter(item)) } // OrderedIndex init. x.orderedIndexExtTypeMap = treemap.New[protoconf.FruitType, []*protoconf.ItemConf_Item]() x.orderedIndexParamExtTypeMap = treemap.New2[ItemConf_OrderedIndex_ParamExtTypeKey, []*protoconf.ItemConf_Item]() - for _, item1 := range x.data.GetItemMap() { + for k1, v1 := range x.data.GetItemMap() { + _ = k1 { // OrderedIndex: ExtType@ExtType - for _, item2 := range item1.GetExtTypeList() { - key := item2 + for k2, v2 := range v1.GetExtTypeList() { + _ = k2 + key := v2 value, _ := x.orderedIndexExtTypeMap.Get(key) - x.orderedIndexExtTypeMap.Put(key, append(value, item1)) + x.orderedIndexExtTypeMap.Put(key, append(value, v1)) } } { // OrderedIndex: (Param,ExtType)@ParamExtType - for _, indexItem0 := range item1.GetParamList() { - for _, indexItem1 := range item1.GetExtTypeList() { + for _, indexItem0 := range v1.GetParamList() { + for _, indexItem1 := range v1.GetExtTypeList() { key := ItemConf_OrderedIndex_ParamExtTypeKey{indexItem0, indexItem1} value, _ := x.orderedIndexParamExtTypeMap.Get(key) - x.orderedIndexParamExtTypeMap.Put(key, append(value, item1)) + x.orderedIndexParamExtTypeMap.Put(key, append(value, v1)) } } } } // OrderedIndex(sort): (Param,ExtType)@ParamExtType - x.orderedIndexParamExtTypeMap.Range(func(key ItemConf_OrderedIndex_ParamExtTypeKey, item []*protoconf.ItemConf_Item) bool { - sort.Slice(item, func(i, j int) bool { + orderedIndexParamExtTypeMapSorter := func(item []*protoconf.ItemConf_Item) func(i, j int) bool { + return func(i, j int) bool { return item[i].GetId() < item[j].GetId() - }) + } + } + x.orderedIndexParamExtTypeMap.Range(func(key ItemConf_OrderedIndex_ParamExtTypeKey, item []*protoconf.ItemConf_Item) bool { + sort.Slice(item, orderedIndexParamExtTypeMapSorter(item)) return true }) return nil @@ -583,8 +598,197 @@ func (x *ItemConf) FindFirstParamExtType(param int32, extType protoconf.FruitTyp return nil } +// OrderedIndex types. +// OrderedIndex: Price +type FruitConf_OrderedIndex_FruitMap = treemap.TreeMap[int32, []*protoconf.FruitConf_Fruits_Fruit] + +// FruitConf is a wrapper around protobuf message: protoconf.FruitConf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... +type FruitConf struct { + UnimplementedMessager + data, originalData *protoconf.FruitConf + orderedIndexFruitMap *FruitConf_OrderedIndex_FruitMap + orderedIndexFruitMap1 map[int32]*FruitConf_OrderedIndex_FruitMap +} + +// Name returns the FruitConf's message name. +func (x *FruitConf) Name() string { + return string((*protoconf.FruitConf)(nil).ProtoReflect().Descriptor().Name()) +} + +// Data returns the FruitConf's inner message data. +func (x *FruitConf) Data() *protoconf.FruitConf { + if x != nil { + return x.data + } + return nil +} + +// Load fills FruitConf's inner message from file in the specified directory and format. +func (x *FruitConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.FruitConf{} + err := load.LoadMessagerInDir(x.data, dir, format, opts) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.FruitConf) + } + return x.processAfterLoad() +} + +// Store writes FruitConf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *FruitConf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the FruitConf's inner message data. +func (x *FruitConf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *FruitConf) Messager() Messager { + return x +} + +// originalMessage returns the FruitConf's original inner message. +func (x *FruitConf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *FruitConf) processAfterLoad() error { + // OrderedIndex init. + x.orderedIndexFruitMap = treemap.New[int32, []*protoconf.FruitConf_Fruits_Fruit]() + x.orderedIndexFruitMap1 = make(map[int32]*FruitConf_OrderedIndex_FruitMap) + for k1, v1 := range x.data.GetFruitsMap() { + _ = k1 + for k2, v2 := range v1.GetFruitMap() { + _ = k2 + { + // OrderedIndex: Price + key := v2.GetPrice() + value, _ := x.orderedIndexFruitMap.Get(key) + x.orderedIndexFruitMap.Put(key, append(value, v2)) + if x.orderedIndexFruitMap1[k1] == nil { + x.orderedIndexFruitMap1[k1] = treemap.New[int32, []*protoconf.FruitConf_Fruits_Fruit]() + } + orderedIndexFruitMap1Value, _ := x.orderedIndexFruitMap1[k1].Get(key) + x.orderedIndexFruitMap1[k1].Put(key, append(orderedIndexFruitMap1Value, v2)) + } + } + } + // OrderedIndex(sort): Price + orderedIndexFruitMapSorter := func(item []*protoconf.FruitConf_Fruits_Fruit) func(i, j int) bool { + return func(i, j int) bool { + return item[i].GetFruitId() < item[j].GetFruitId() + } + } + x.orderedIndexFruitMap.Range(func(key int32, item []*protoconf.FruitConf_Fruits_Fruit) bool { + sort.Slice(item, orderedIndexFruitMapSorter(item)) + return true + }) + for _, item := range x.orderedIndexFruitMap1 { + item.Range(func(key int32, item1 []*protoconf.FruitConf_Fruits_Fruit) bool { + sort.Slice(item1, orderedIndexFruitMapSorter(item1)) + return true + }) + } + return nil +} + +// Get1 finds value in the 1-level map. It will return +// NotFound error if the key is not found. +func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruits, error) { + d := x.Data().GetFruitsMap() + if val, ok := d[fruitType]; !ok { + return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) + } else { + return val, nil + } +} + +// Get2 finds value in the 2-level map. It will return +// NotFound error if the key is not found. +func (x *FruitConf) Get2(fruitType int32, fruitId int32) (*protoconf.FruitConf_Fruits_Fruit, error) { + conf, err := x.Get1(fruitType) + if err != nil { + return nil, err + } + d := conf.GetFruitMap() + if val, ok := d[fruitId]; !ok { + return nil, fmt.Errorf("fruitId(%v) %w", fruitId, ErrNotFound) + } else { + return val, nil + } +} + +// OrderedIndex: Price + +// FindFruitMap finds the ordered index (Price) to value (protoconf.FruitConf_Fruits_Fruit) treemap. +// One key may correspond to multiple values, which are contained by a slice. +func (x *FruitConf) FindFruitMap() *FruitConf_OrderedIndex_FruitMap { + return x.orderedIndexFruitMap +} + +// FindFruit finds a slice of all values of the given key. +func (x *FruitConf) FindFruit(price int32) []*protoconf.FruitConf_Fruits_Fruit { + val, _ := x.orderedIndexFruitMap.Get(price) + return val +} + +// FindFirstFruit finds the first value of the given key, +// or nil if no value found. +func (x *FruitConf) FindFirstFruit(price int32) *protoconf.FruitConf_Fruits_Fruit { + val := x.FindFruit(price) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindFruitMap1 finds the index (Price) to value (protoconf.FruitConf_Fruits_Fruit) treemap +// specified by (fruitType). +// One key may correspond to multiple values, which are contained by a slice. +func (x *FruitConf) FindFruitMap1(fruitType int32) *FruitConf_OrderedIndex_FruitMap { + return x.orderedIndexFruitMap1[fruitType] +} + +// FindFruit1 finds a slice of all values of the given key specified by (fruitType). +func (x *FruitConf) FindFruit1(fruitType int32, price int32) []*protoconf.FruitConf_Fruits_Fruit { + val, _ := x.FindFruitMap1(fruitType).Get(price) + return val +} + +// FindFirstFruit1 finds the first value of the given key specified by (fruitType), +// or nil if no value found. +func (x *FruitConf) FindFirstFruit1(fruitType int32, price int32) *protoconf.FruitConf_Fruits_Fruit { + val := x.FindFruit1(fruitType, price) + if len(val) > 0 { + return val[0] + } + return nil +} + func init() { Register(func() Messager { return new(ItemConf) }) + Register(func() Messager { + return new(FruitConf) + }) } diff --git a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go index 39cf846b..d9d00acc 100644 --- a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go +++ b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go @@ -16,6 +16,7 @@ type MessagerContainer struct { heroConf *HeroConf heroBaseConf *HeroBaseConf itemConf *ItemConf + fruitConf *FruitConf patchReplaceConf *PatchReplaceConf patchMergeConf *PatchMergeConf recursivePatchConf *RecursivePatchConf @@ -32,6 +33,7 @@ func newMessagerContainer(messagerMap MessagerMap) *MessagerContainer { heroConf: GetMessager[*HeroConf](messagerMap), heroBaseConf: GetMessager[*HeroBaseConf](messagerMap), itemConf: GetMessager[*ItemConf](messagerMap), + fruitConf: GetMessager[*FruitConf](messagerMap), patchReplaceConf: GetMessager[*PatchReplaceConf](messagerMap), patchMergeConf: GetMessager[*PatchMergeConf](messagerMap), recursivePatchConf: GetMessager[*RecursivePatchConf](messagerMap), @@ -68,6 +70,10 @@ func (mc *MessagerContainer) GetItemConf() *ItemConf { return mc.itemConf } +func (mc *MessagerContainer) GetFruitConf() *FruitConf { + return mc.fruitConf +} + func (mc *MessagerContainer) GetPatchReplaceConf() *PatchReplaceConf { return mc.patchReplaceConf } diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index f17d6e07..bfbfb2de 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -31,6 +31,17 @@ type ActivityConf_OrderedMap_Activity_ChapterMap = treemap.TreeMap[uint32, *Acti type ActivityConf_OrderedMap_ActivityValue = pair.Pair[*ActivityConf_OrderedMap_Activity_ChapterMap, *protoconf.ActivityConf_Activity] type ActivityConf_OrderedMap_ActivityMap = treemap.TreeMap[uint64, *ActivityConf_OrderedMap_ActivityValue] +// LeveledIndex keys. +type ActivityConf_LeveledIndex_Activity_ChapterKey struct { + ActivityId uint64 + ChapterId uint32 +} +type ActivityConf_LeveledIndex_protoconf_SectionKey struct { + ActivityId uint64 + ChapterId uint32 + SectionId uint32 +} + // Index types. // Index: ActivityName type ActivityConf_Index_ActivityMap = map[string][]*protoconf.ActivityConf_Activity @@ -53,12 +64,17 @@ type ActivityConf_Index_AwardMap = map[uint32][]*protoconf.Section_SectionItem // 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... type ActivityConf struct { UnimplementedMessager - data, originalData *protoconf.ActivityConf - orderedMap *ActivityConf_OrderedMap_ActivityMap - indexActivityMap ActivityConf_Index_ActivityMap - indexChapterMap ActivityConf_Index_ChapterMap - indexNamedChapterMap ActivityConf_Index_NamedChapterMap - indexAwardMap ActivityConf_Index_AwardMap + data, originalData *protoconf.ActivityConf + orderedMap *ActivityConf_OrderedMap_ActivityMap + indexActivityMap ActivityConf_Index_ActivityMap + indexChapterMap ActivityConf_Index_ChapterMap + indexChapterMap1 map[uint64]ActivityConf_Index_ChapterMap + indexNamedChapterMap ActivityConf_Index_NamedChapterMap + indexNamedChapterMap1 map[uint64]ActivityConf_Index_NamedChapterMap + indexAwardMap ActivityConf_Index_AwardMap + indexAwardMap1 map[uint64]ActivityConf_Index_AwardMap + indexAwardMap2 map[ActivityConf_LeveledIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap + indexAwardMap3 map[ActivityConf_LeveledIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap } // Name returns the ActivityConf's message name. @@ -150,41 +166,80 @@ func (x *ActivityConf) processAfterLoad() error { // Index init. x.indexActivityMap = make(ActivityConf_Index_ActivityMap) x.indexChapterMap = make(ActivityConf_Index_ChapterMap) + x.indexChapterMap1 = make(map[uint64]ActivityConf_Index_ChapterMap) x.indexNamedChapterMap = make(ActivityConf_Index_NamedChapterMap) + x.indexNamedChapterMap1 = make(map[uint64]ActivityConf_Index_NamedChapterMap) x.indexAwardMap = make(ActivityConf_Index_AwardMap) - for _, item1 := range x.data.GetActivityMap() { + x.indexAwardMap1 = make(map[uint64]ActivityConf_Index_AwardMap) + x.indexAwardMap2 = make(map[ActivityConf_LeveledIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap) + x.indexAwardMap3 = make(map[ActivityConf_LeveledIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap) + for k1, v1 := range x.data.GetActivityMap() { + _ = k1 { // Index: ActivityName - key := item1.GetActivityName() - x.indexActivityMap[key] = append(x.indexActivityMap[key], item1) + key := v1.GetActivityName() + x.indexActivityMap[key] = append(x.indexActivityMap[key], v1) } - for _, item2 := range item1.GetChapterMap() { + for k2, v2 := range v1.GetChapterMap() { + _ = k2 { // Index: ChapterID - key := item2.GetChapterId() - x.indexChapterMap[key] = append(x.indexChapterMap[key], item2) + key := v2.GetChapterId() + x.indexChapterMap[key] = append(x.indexChapterMap[key], v2) + if x.indexChapterMap1[k1] == nil { + x.indexChapterMap1[k1] = make(ActivityConf_Index_ChapterMap) + } + x.indexChapterMap1[k1][key] = append(x.indexChapterMap1[k1][key], v2) } { // Index: ChapterName@NamedChapter - key := item2.GetChapterName() - x.indexNamedChapterMap[key] = append(x.indexNamedChapterMap[key], item2) + key := v2.GetChapterName() + x.indexNamedChapterMap[key] = append(x.indexNamedChapterMap[key], v2) + if x.indexNamedChapterMap1[k1] == nil { + x.indexNamedChapterMap1[k1] = make(ActivityConf_Index_NamedChapterMap) + } + x.indexNamedChapterMap1[k1][key] = append(x.indexNamedChapterMap1[k1][key], v2) } - for _, item3 := range item2.GetSectionMap() { - for _, item4 := range item3.GetSectionItemList() { + for k3, v3 := range v2.GetSectionMap() { + _ = k3 + for k4, v4 := range v3.GetSectionItemList() { + _ = k4 { // Index: SectionItemID@Award - key := item4.GetId() - x.indexAwardMap[key] = append(x.indexAwardMap[key], item4) + key := v4.GetId() + x.indexAwardMap[key] = append(x.indexAwardMap[key], v4) + if x.indexAwardMap1[k1] == nil { + x.indexAwardMap1[k1] = make(ActivityConf_Index_AwardMap) + } + x.indexAwardMap1[k1][key] = append(x.indexAwardMap1[k1][key], v4) + indexAwardMap2Keys := ActivityConf_LeveledIndex_Activity_ChapterKey{k1, k2} + if x.indexAwardMap2[indexAwardMap2Keys] == nil { + x.indexAwardMap2[indexAwardMap2Keys] = make(ActivityConf_Index_AwardMap) + } + x.indexAwardMap2[indexAwardMap2Keys][key] = append(x.indexAwardMap2[indexAwardMap2Keys][key], v4) + indexAwardMap3Keys := ActivityConf_LeveledIndex_protoconf_SectionKey{k1, k2, k3} + if x.indexAwardMap3[indexAwardMap3Keys] == nil { + x.indexAwardMap3[indexAwardMap3Keys] = make(ActivityConf_Index_AwardMap) + } + x.indexAwardMap3[indexAwardMap3Keys][key] = append(x.indexAwardMap3[indexAwardMap3Keys][key], v4) } } } } } // Index(sort): ChapterName@NamedChapter - for _, item := range x.indexNamedChapterMap { - sort.Slice(item, func(i, j int) bool { + indexNamedChapterMapSorter := func(item []*protoconf.ActivityConf_Activity_Chapter) func(i, j int) bool { + return func(i, j int) bool { return item[i].GetAwardId() < item[j].GetAwardId() - }) + } + } + for _, item := range x.indexNamedChapterMap { + sort.Slice(item, indexNamedChapterMapSorter(item)) + } + for _, item := range x.indexNamedChapterMap1 { + for _, item1 := range item { + sort.Slice(item1, indexNamedChapterMapSorter(item1)) + } } return nil } @@ -335,6 +390,28 @@ func (x *ActivityConf) FindFirstChapter(chapterId uint32) *protoconf.ActivityCon return nil } +// FindChapterMap1 finds the index (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) map +// specified by (activityId). +// One key may correspond to multiple values, which are contained by a slice. +func (x *ActivityConf) FindChapterMap1(activityId uint64) ActivityConf_Index_ChapterMap { + return x.indexChapterMap1[activityId] +} + +// FindChapter1 finds a slice of all values of the given key specified by (activityId). +func (x *ActivityConf) FindChapter1(activityId uint64, chapterId uint32) []*protoconf.ActivityConf_Activity_Chapter { + return x.FindChapterMap1(activityId)[chapterId] +} + +// FindFirstChapter1 finds the first value of the given key specified by (activityId), +// or nil if no value found. +func (x *ActivityConf) FindFirstChapter1(activityId uint64, chapterId uint32) *protoconf.ActivityConf_Activity_Chapter { + val := x.FindChapter1(activityId, chapterId) + if len(val) > 0 { + return val[0] + } + return nil +} + // Index: ChapterName@NamedChapter // FindNamedChapterMap finds the index (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) map. @@ -358,6 +435,28 @@ func (x *ActivityConf) FindFirstNamedChapter(chapterName string) *protoconf.Acti return nil } +// FindNamedChapterMap1 finds the index (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) map +// specified by (activityId). +// One key may correspond to multiple values, which are contained by a slice. +func (x *ActivityConf) FindNamedChapterMap1(activityId uint64) ActivityConf_Index_NamedChapterMap { + return x.indexNamedChapterMap1[activityId] +} + +// FindNamedChapter1 finds a slice of all values of the given key specified by (activityId). +func (x *ActivityConf) FindNamedChapter1(activityId uint64, chapterName string) []*protoconf.ActivityConf_Activity_Chapter { + return x.FindNamedChapterMap1(activityId)[chapterName] +} + +// FindFirstNamedChapter1 finds the first value of the given key specified by (activityId), +// or nil if no value found. +func (x *ActivityConf) FindFirstNamedChapter1(activityId uint64, chapterName string) *protoconf.ActivityConf_Activity_Chapter { + val := x.FindNamedChapter1(activityId, chapterName) + if len(val) > 0 { + return val[0] + } + return nil +} + // Index: SectionItemID@Award // FindAwardMap finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map. @@ -381,6 +480,72 @@ func (x *ActivityConf) FindFirstAward(id uint32) *protoconf.Section_SectionItem return nil } +// FindAwardMap1 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map +// specified by (activityId). +// One key may correspond to multiple values, which are contained by a slice. +func (x *ActivityConf) FindAwardMap1(activityId uint64) ActivityConf_Index_AwardMap { + return x.indexAwardMap1[activityId] +} + +// FindAward1 finds a slice of all values of the given key specified by (activityId). +func (x *ActivityConf) FindAward1(activityId uint64, id uint32) []*protoconf.Section_SectionItem { + return x.FindAwardMap1(activityId)[id] +} + +// FindFirstAward1 finds the first value of the given key specified by (activityId), +// or nil if no value found. +func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf.Section_SectionItem { + val := x.FindAward1(activityId, id) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindAwardMap2 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map +// specified by (activityId, chapterId). +// One key may correspond to multiple values, which are contained by a slice. +func (x *ActivityConf) FindAwardMap2(activityId uint64, chapterId uint32) ActivityConf_Index_AwardMap { + return x.indexAwardMap2[ActivityConf_LeveledIndex_Activity_ChapterKey{activityId, chapterId}] +} + +// FindAward2 finds a slice of all values of the given key specified by (activityId, chapterId). +func (x *ActivityConf) FindAward2(activityId uint64, chapterId uint32, id uint32) []*protoconf.Section_SectionItem { + return x.FindAwardMap2(activityId, chapterId)[id] +} + +// FindFirstAward2 finds the first value of the given key specified by (activityId, chapterId), +// or nil if no value found. +func (x *ActivityConf) FindFirstAward2(activityId uint64, chapterId uint32, id uint32) *protoconf.Section_SectionItem { + val := x.FindAward2(activityId, chapterId, id) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindAwardMap3 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map +// specified by (activityId, chapterId, sectionId). +// One key may correspond to multiple values, which are contained by a slice. +func (x *ActivityConf) FindAwardMap3(activityId uint64, chapterId uint32, sectionId uint32) ActivityConf_Index_AwardMap { + return x.indexAwardMap3[ActivityConf_LeveledIndex_protoconf_SectionKey{activityId, chapterId, sectionId}] +} + +// FindAward3 finds a slice of all values of the given key specified by (activityId, chapterId, sectionId). +func (x *ActivityConf) FindAward3(activityId uint64, chapterId uint32, sectionId uint32, id uint32) []*protoconf.Section_SectionItem { + return x.FindAwardMap3(activityId, chapterId, sectionId)[id] +} + +// FindFirstAward3 finds the first value of the given key specified by (activityId, chapterId, sectionId), +// or nil if no value found. +func (x *ActivityConf) FindFirstAward3(activityId uint64, chapterId uint32, sectionId uint32, id uint32) *protoconf.Section_SectionItem { + val := x.FindAward3(activityId, chapterId, sectionId, id) + if len(val) > 0 { + return val[0] + } + return nil +} + // ChapterConf is a wrapper around protobuf message: protoconf.ChapterConf. // // It is designed for three goals: @@ -654,68 +819,79 @@ func (x *TaskConf) originalMessage() proto.Message { func (x *TaskConf) processAfterLoad() error { // Index init. x.indexTaskMap = make(TaskConf_Index_TaskMap) - for _, item1 := range x.data.GetTaskMap() { + for k1, v1 := range x.data.GetTaskMap() { + _ = k1 { // Index: ActivityID - key := item1.GetActivityId() - x.indexTaskMap[key] = append(x.indexTaskMap[key], item1) + key := v1.GetActivityId() + x.indexTaskMap[key] = append(x.indexTaskMap[key], v1) } } // Index(sort): ActivityID - for _, item := range x.indexTaskMap { - sort.Slice(item, func(i, j int) bool { + indexTaskMapSorter := func(item []*protoconf.TaskConf_Task) func(i, j int) bool { + return func(i, j int) bool { if item[i].GetGoal() != item[j].GetGoal() { return item[i].GetGoal() < item[j].GetGoal() } return item[i].GetId() < item[j].GetId() - }) + } + } + for _, item := range x.indexTaskMap { + sort.Slice(item, indexTaskMapSorter(item)) } // OrderedIndex init. x.orderedIndexOrderedTaskMap = treemap.New[int64, []*protoconf.TaskConf_Task]() x.orderedIndexTaskExpiryMap = treemap.New[int64, []*protoconf.TaskConf_Task]() x.orderedIndexSortedTaskExpiryMap = treemap.New[int64, []*protoconf.TaskConf_Task]() x.orderedIndexActivityExpiryMap = treemap.New2[TaskConf_OrderedIndex_ActivityExpiryKey, []*protoconf.TaskConf_Task]() - for _, item1 := range x.data.GetTaskMap() { + for k1, v1 := range x.data.GetTaskMap() { + _ = k1 { // OrderedIndex: Goal@OrderedTask - key := item1.GetGoal() + key := v1.GetGoal() value, _ := x.orderedIndexOrderedTaskMap.Get(key) - x.orderedIndexOrderedTaskMap.Put(key, append(value, item1)) + x.orderedIndexOrderedTaskMap.Put(key, append(value, v1)) } { // OrderedIndex: Expiry@TaskExpiry - key := item1.GetExpiry().GetSeconds() + key := v1.GetExpiry().GetSeconds() value, _ := x.orderedIndexTaskExpiryMap.Get(key) - x.orderedIndexTaskExpiryMap.Put(key, append(value, item1)) + x.orderedIndexTaskExpiryMap.Put(key, append(value, v1)) } { // OrderedIndex: Expiry@SortedTaskExpiry - key := item1.GetExpiry().GetSeconds() + key := v1.GetExpiry().GetSeconds() value, _ := x.orderedIndexSortedTaskExpiryMap.Get(key) - x.orderedIndexSortedTaskExpiryMap.Put(key, append(value, item1)) + x.orderedIndexSortedTaskExpiryMap.Put(key, append(value, v1)) } { // OrderedIndex: (Expiry,ActivityID)@ActivityExpiry - key := TaskConf_OrderedIndex_ActivityExpiryKey{item1.GetExpiry().GetSeconds(), item1.GetActivityId()} + key := TaskConf_OrderedIndex_ActivityExpiryKey{v1.GetExpiry().GetSeconds(), v1.GetActivityId()} value, _ := x.orderedIndexActivityExpiryMap.Get(key) - x.orderedIndexActivityExpiryMap.Put(key, append(value, item1)) + x.orderedIndexActivityExpiryMap.Put(key, append(value, v1)) } } // OrderedIndex(sort): Goal@OrderedTask - x.orderedIndexOrderedTaskMap.Range(func(key int64, item []*protoconf.TaskConf_Task) bool { - sort.Slice(item, func(i, j int) bool { + orderedIndexOrderedTaskMapSorter := func(item []*protoconf.TaskConf_Task) func(i, j int) bool { + return func(i, j int) bool { return item[i].GetId() < item[j].GetId() - }) + } + } + x.orderedIndexOrderedTaskMap.Range(func(key int64, item []*protoconf.TaskConf_Task) bool { + sort.Slice(item, orderedIndexOrderedTaskMapSorter(item)) return true }) // OrderedIndex(sort): Expiry@SortedTaskExpiry - x.orderedIndexSortedTaskExpiryMap.Range(func(key int64, item []*protoconf.TaskConf_Task) bool { - sort.Slice(item, func(i, j int) bool { + orderedIndexSortedTaskExpiryMapSorter := func(item []*protoconf.TaskConf_Task) func(i, j int) bool { + return func(i, j int) bool { if item[i].GetGoal() != item[j].GetGoal() { return item[i].GetGoal() < item[j].GetGoal() } return item[i].GetId() < item[j].GetId() - }) + } + } + x.orderedIndexSortedTaskExpiryMap.Range(func(key int64, item []*protoconf.TaskConf_Task) bool { + sort.Slice(item, orderedIndexSortedTaskExpiryMapSorter(item)) return true }) return nil From 3cb1fccdb412dc57306f87fa0dd91537488f49be Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Fri, 21 Nov 2025 11:44:02 +0800 Subject: [PATCH 04/15] feat(go): unify index logic --- .../leveled_index.go => indexes/generator.go} | 70 +++++-- .../{index => indexes}/index.go | 166 ++++++---------- .../orderedindex.go} | 181 +++++++----------- cmd/protoc-gen-go-tableau-loader/messager.go | 16 +- .../orderedmap/ordered_map.go | 10 +- 5 files changed, 191 insertions(+), 252 deletions(-) rename cmd/protoc-gen-go-tableau-loader/{leveledindex/leveled_index.go => indexes/generator.go} (50%) rename cmd/protoc-gen-go-tableau-loader/{index => indexes}/index.go (65%) rename cmd/protoc-gen-go-tableau-loader/{orderedindex/ordered_index.go => indexes/orderedindex.go} (63%) diff --git a/cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go similarity index 50% rename from cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go rename to cmd/protoc-gen-go-tableau-loader/indexes/generator.go index e13799e0..ea4d5cdb 100644 --- a/cmd/protoc-gen-go-tableau-loader/leveledindex/leveled_index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go @@ -1,11 +1,10 @@ -package leveledindex +package indexes import ( "fmt" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" "github.com/tableauio/loader/internal/index" - "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -16,9 +15,10 @@ type Generator struct { descriptor *index.IndexDescriptor message *protogen.Message + // level message maxDepth int - Keys helper.MapKeys - MapFds []protoreflect.FieldDescriptor + keys helper.MapKeys + mapFds []protoreflect.FieldDescriptor } func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { @@ -28,19 +28,19 @@ func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *i descriptor: descriptor, message: message, } - generator.init() + generator.initLevelMessage() return generator } -func (x *Generator) init() { +func (x *Generator) initLevelMessage() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { if fd := levelMessage.FD; fd != nil && fd.IsMap() { - x.Keys = x.Keys.AddMapKey(helper.MapKey{ + x.keys = x.keys.AddMapKey(helper.MapKey{ Type: helper.ParseMapKeyType(fd.MapKey()), Name: helper.ParseMapFieldNameAsFuncParam(fd), FieldName: helper.ParseMapFieldNameAsKeyStructFieldName(fd), }) - x.MapFds = append(x.MapFds, fd) + x.mapFds = append(x.mapFds, fd) } if len(levelMessage.Indexes) != 0 || len(levelMessage.OrderedIndexes) != 0 { x.maxDepth = levelMessage.Depth @@ -49,33 +49,73 @@ func (x *Generator) init() { } func (x *Generator) NeedGenerate() bool { - return options.NeedGenIndex(x.message.Desc, options.LangCPP) || options.NeedGenOrderedIndex(x.message.Desc, options.LangCPP) + return x.needGenerateIndex() || x.needGenerateOrderedIndex() } func (x *Generator) messagerName() string { return string(x.message.Desc.Name()) } -func (x *Generator) KeyType(mapFd protoreflect.FieldDescriptor) string { +func (x *Generator) levelKeyType(mapFd protoreflect.FieldDescriptor) string { return fmt.Sprintf("%s_LeveledIndex_%sKey", x.messagerName(), helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } -func (x *Generator) GenLeveledIndexTypeDef() { +func (x *Generator) mapValueType(index *index.LevelIndex) protogen.GoIdent { + return helper.FindMessageGoIdent(x.gen, index.MD) +} + +func (x *Generator) fieldGetter(fd protoreflect.FieldDescriptor) string { + return fmt.Sprintf(".Get%s()", helper.ParseIndexFieldName(x.gen, fd)) +} + +func (x *Generator) parseKeyFieldNameAndSuffix(field *index.LevelField) (string, string) { + var fieldName, suffix string + for i, leveledFd := range field.LeveledFDList { + fieldName += x.fieldGetter(leveledFd) + if i == len(field.LeveledFDList)-1 && leveledFd.Message() != nil { + switch leveledFd.Message().FullName() { + case "google.protobuf.Timestamp", "google.protobuf.Duration": + suffix = ".GetSeconds()" + default: + } + } + } + return fieldName, suffix +} + +func (x *Generator) GenIndexTypeDef() { if !x.NeedGenerate() { return } - for i := 1; i <= x.maxDepth-3 && i <= len(x.MapFds)-1; i++ { + for i := 1; i <= x.maxDepth-3 && i <= len(x.mapFds)-1; i++ { if i == 1 { x.g.P() x.g.P("// LeveledIndex keys.") } - fd := x.MapFds[i] - keyType := x.KeyType(fd) - keys := x.Keys[:i+1] + fd := x.mapFds[i] + keyType := x.levelKeyType(fd) + keys := x.keys[:i+1] x.g.P("type ", keyType, " struct {") for _, key := range keys { x.g.P(key.FieldName, " ", key.Type) } x.g.P("}") } + x.genIndexTypeDef() + x.genOrderedIndexTypeDef() +} + +func (x *Generator) GenIndexField() { + x.genIndexField() + x.genOrderedIndexField() +} + +func (x *Generator) GenIndexLoader() { + x.genIndexLoader() + x.genOrderedIndexLoader() +} + +func (x *Generator) GenIndexFinders() { + x.genIndexFinders() + x.genOrderedIndexFinders() } diff --git a/cmd/protoc-gen-go-tableau-loader/index/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go similarity index 65% rename from cmd/protoc-gen-go-tableau-loader/index/index.go rename to cmd/protoc-gen-go-tableau-loader/indexes/index.go index a792d3de..015ab2fd 100644 --- a/cmd/protoc-gen-go-tableau-loader/index/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -1,4 +1,4 @@ -package index +package indexes import ( "fmt" @@ -6,44 +6,19 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" - "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/reflect/protoreflect" ) -type Generator struct { - gen *protogen.Plugin - g *protogen.GeneratedFile - descriptor *index.IndexDescriptor - message *protogen.Message - level *leveledindex.Generator -} - -func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { - return &Generator{ - gen: gen, - g: g, - descriptor: descriptor, - message: message, - level: level, - } -} - -func (x *Generator) needGenerate() bool { +func (x *Generator) needGenerateIndex() bool { return options.NeedGenIndex(x.message.Desc, options.LangGO) } -func (x *Generator) messagerName() string { - return string(x.message.Desc.Name()) -} - -func (x *Generator) mapType(index *index.LevelIndex) string { +func (x *Generator) indexMapType(index *index.LevelIndex) string { return fmt.Sprintf("%s_Index_%sMap", x.messagerName(), index.Name()) } -func (x *Generator) mapKeyType(index *index.LevelIndex) string { +func (x *Generator) indexMapKeyType(index *index.LevelIndex) string { if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take first field @@ -54,15 +29,10 @@ func (x *Generator) mapKeyType(index *index.LevelIndex) string { } } -func (x *Generator) mapValueType(index *index.LevelIndex) protogen.GoIdent { - return helper.FindMessageGoIdent(x.gen, index.MD) -} - -func (x *Generator) indexContainerName(index *index.LevelIndex) string { - return fmt.Sprintf("index%sMap", strcase.ToCamel(index.Name())) -} - -func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { +func (x *Generator) indexContainerName(index *index.LevelIndex, i int) string { + if i == 0 { + return fmt.Sprintf("index%sMap", strcase.ToCamel(index.Name())) + } return fmt.Sprintf("index%sMap%d", strcase.ToCamel(index.Name()), i) } @@ -78,20 +48,8 @@ func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { return keys } -func (x *Generator) fieldGetter(fd protoreflect.FieldDescriptor) string { - return fmt.Sprintf(".Get%s()", helper.ParseIndexFieldName(x.gen, fd)) -} - -func (x *Generator) parseKeyFieldName(field *index.LevelField) string { - var fieldName string - for _, leveledFd := range field.LeveledFDList { - fieldName += x.fieldGetter(leveledFd) - } - return fieldName -} - -func (x *Generator) GenIndexTypeDef() { - if !x.needGenerate() { +func (x *Generator) genIndexTypeDef() { + if !x.needGenerateIndex() { return } x.g.P("// Index types.") @@ -100,7 +58,7 @@ func (x *Generator) GenIndexTypeDef() { x.g.P("// Index: ", index.Index) if len(index.ColFields) != 1 { // multi-column index - keyType := x.mapKeyType(index) + keyType := x.indexMapKeyType(index) keys := x.indexKeys(index) // generate key struct @@ -111,52 +69,52 @@ func (x *Generator) GenIndexTypeDef() { } x.g.P("}") } - x.g.P("type ", x.mapType(index), " = map[", x.mapKeyType(index), "][]*", x.mapValueType(index)) + x.g.P("type ", x.indexMapType(index), " = map[", x.indexMapKeyType(index), "][]*", x.mapValueType(index)) x.g.P() } } } -func (x *Generator) GenIndexField() { - if !x.needGenerate() { +func (x *Generator) genIndexField() { + if !x.needGenerateIndex() { return } for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.g.P(x.indexContainerName(index), " ", x.mapType(index)) + x.g.P(x.indexContainerName(index, 0), " ", x.indexMapType(index)) for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P(x.indexContainerNameI(index, i), " map[", x.level.Keys[0].Type, "]", x.mapType(index)) + x.g.P(x.indexContainerName(index, i), " map[", x.keys[0].Type, "]", x.indexMapType(index)) } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P(x.indexContainerNameI(index, i), " map[", leveledIndexKeyType, "]", x.mapType(index)) + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(x.indexContainerName(index, i), " map[", leveledIndexKeyType, "]", x.indexMapType(index)) } } } } } -func (x *Generator) GenIndexLoader() { - if !x.needGenerate() { +func (x *Generator) genIndexLoader() { + if !x.needGenerateIndex() { return } defer x.genIndexSorter() x.g.P("// Index init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.g.P("x.", x.indexContainerName(index), " = make(", x.mapType(index), ")") + x.g.P("x.", x.indexContainerName(index, 0), " = make(", x.indexMapType(index), ")") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", x.level.Keys[0].Type, "]", x.mapType(index), ")") + x.g.P("x.", x.indexContainerName(index, i), " = make(map[", x.keys[0].Type, "]", x.indexMapType(index), ")") } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", leveledIndexKeyType, "]", x.mapType(index), ")") + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("x.", x.indexContainerName(index, i), " = make(map[", leveledIndexKeyType, "]", x.indexMapType(index), ")") } } } @@ -187,18 +145,18 @@ func (x *Generator) genOneIndexLoader(index *index.LevelIndex, depth int, parent if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take the first field - fieldName := x.parseKeyFieldName(field) + fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { keyName := fmt.Sprintf("k%d", depth) valueName := fmt.Sprintf("v%d", depth) x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, fieldName, " {") x.g.P("_ = ", keyName) x.g.P("key := ", valueName) - x.genLoader(depth, index, parentDataName) + x.genIndexLoaderCommon(depth, index, parentDataName) x.g.P("}") } else { x.g.P("key := ", parentDataName, fieldName) - x.genLoader(depth, index, parentDataName) + x.genIndexLoaderCommon(depth, index, parentDataName) } } else { // multi-column index @@ -210,13 +168,13 @@ func (x *Generator) genOneIndexLoader(index *index.LevelIndex, depth int, parent func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { cursor := len(keys) if cursor >= len(index.ColFields) { - keyType := x.mapKeyType(index) + keyType := x.indexMapKeyType(index) x.g.P("key := ", keyType, " {", keys.GenGetArguments(), "}") - x.genLoader(depth, index, parentDataName) + x.genIndexLoaderCommon(depth, index, parentDataName) return } field := index.ColFields[cursor] - fieldName := x.parseKeyFieldName(field) + fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { itemName := fmt.Sprintf("indexItem%d", cursor) x.g.P("for _, ", itemName, " := range ", parentDataName, fieldName, " {") @@ -230,31 +188,31 @@ func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelInd } } -func (x *Generator) genLoader(depth int, index *index.LevelIndex, parentDataName string) { - indexContainerName := x.indexContainerName(index) +func (x *Generator) genIndexLoaderCommon(depth int, index *index.LevelIndex, parentDataName string) { + indexContainerName := x.indexContainerName(index, 0) x.g.P("x.", indexContainerName, "[key] = append(x.", indexContainerName, "[key], ", parentDataName, ")") for i := 1; i <= depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - indexContainerNameI := x.indexContainerNameI(index, i) + indexContainerName := x.indexContainerName(index, i) if i == 1 { - x.g.P("if x.", indexContainerNameI, "[k1] == nil {") - x.g.P("x.", indexContainerNameI, "[k1] = make(", x.mapType(index), ")") + x.g.P("if x.", indexContainerName, "[k1] == nil {") + x.g.P("x.", indexContainerName, "[k1] = make(", x.indexMapType(index), ")") x.g.P("}") - x.g.P("x.", indexContainerNameI, "[k1][key] = append(x.", indexContainerNameI, "[k1][key], ", parentDataName, ")") + x.g.P("x.", indexContainerName, "[k1][key] = append(x.", indexContainerName, "[k1][key], ", parentDataName, ")") } else { var fields []string for j := 1; j <= i; j++ { fields = append(fields, fmt.Sprintf("k%d", j)) } - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - keyName := indexContainerNameI + "Keys" + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + keyName := indexContainerName + "Keys" x.g.P(keyName, " := ", leveledIndexKeyType, "{", strings.Join(fields, ", "), "}") - x.g.P("if x.", indexContainerNameI, "[", keyName, "] == nil {") - x.g.P("x.", indexContainerNameI, "[", keyName, "] = make(", x.mapType(index), ")") + x.g.P("if x.", indexContainerName, "[", keyName, "] == nil {") + x.g.P("x.", indexContainerName, "[", keyName, "] = make(", x.indexMapType(index), ")") x.g.P("}") - x.g.P("x.", indexContainerNameI, "[", keyName, "][key] = append(x.", indexContainerNameI, "[", keyName, "][key], ", parentDataName, ")") + x.g.P("x.", indexContainerName, "[", keyName, "][key] = append(x.", indexContainerName, "[", keyName, "][key], ", parentDataName, ")") } } } @@ -264,11 +222,11 @@ func (x *Generator) genIndexSorter() { for _, index := range levelMessage.Indexes { if len(index.SortedColFields) != 0 { x.g.P("// Index(sort): ", index.Index) - indexContainerName := x.indexContainerName(index) + indexContainerName := x.indexContainerName(index, 0) x.g.P(indexContainerName, "Sorter := func(item []*", x.mapValueType(index), ") func(i, j int) bool {") x.g.P("return func(i, j int) bool {") for i, field := range index.SortedColFields { - fieldName := x.parseKeyFieldName(field) + fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if i == len(index.SortedColFields)-1 { x.g.P("return item[i]", fieldName, " < item[j]", fieldName) } else { @@ -279,14 +237,14 @@ func (x *Generator) genIndexSorter() { } x.g.P("}") x.g.P("}") - x.g.P("for _, item := range x.", x.indexContainerName(index), " {") + x.g.P("for _, item := range x.", x.indexContainerName(index, 0), " {") x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") x.g.P("}") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - x.g.P("for _, item := range x.", x.indexContainerNameI(index, i), " {") + x.g.P("for _, item := range x.", x.indexContainerName(index, i), " {") x.g.P("for _, item1 := range item {") x.g.P(helper.SortPackage.Ident("Slice"), "(item1, ", indexContainerName, "Sorter(item1))") x.g.P("}") @@ -297,20 +255,20 @@ func (x *Generator) genIndexSorter() { } } -func (x *Generator) GenIndexFinders() { - if !x.needGenerate() { +func (x *Generator) genIndexFinders() { + if !x.needGenerateIndex() { return } for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - indexContainerName := x.indexContainerName(index) + indexContainerName := x.indexContainerName(index, 0) messagerName := x.messagerName() x.g.P("// Index: ", index.Index) x.g.P() x.g.P("// Find", index.Name(), "Map finds the index (", index.Index, ") to value (", x.mapValueType(index), ") map.") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") - x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() ", x.mapType(index), " {") + x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() ", x.indexMapType(index), " {") x.g.P("return x.", indexContainerName) x.g.P("}") x.g.P() @@ -323,7 +281,7 @@ func (x *Generator) GenIndexFinders() { if len(index.ColFields) == 1 { x.g.P("return x.", indexContainerName, "[", args, "]") } else { - x.g.P("return x.", indexContainerName, "[", x.mapKeyType(index), "{", args, "}]") + x.g.P("return x.", indexContainerName, "[", x.indexMapKeyType(index), "{", args, "}]") } x.g.P("}") x.g.P() @@ -340,23 +298,23 @@ func (x *Generator) GenIndexFinders() { x.g.P() for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - indexContainerNameI := x.indexContainerNameI(index, i) - partKeys := x.level.Keys[:i] + indexContainerName := x.indexContainerName(index, i) + partKeys := x.keys[:i] partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") map") x.g.P("// specified by (", partArgs, ").") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") - x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") ", x.mapType(index), " {") + x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") ", x.indexMapType(index), " {") if len(partKeys) == 1 { - x.g.P("return x.", indexContainerNameI, "[", partArgs, "]") + x.g.P("return x.", indexContainerName, "[", partArgs, "]") } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P("return x.", indexContainerNameI, "[", leveledIndexKeyType, "{", partArgs, "}]") + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("return x.", indexContainerName, "[", leveledIndexKeyType, "{", partArgs, "}]") } x.g.P("}") x.g.P() @@ -366,7 +324,7 @@ func (x *Generator) GenIndexFinders() { if len(index.ColFields) == 1 { x.g.P("return x.Find", index.Name(), "Map", i, "(", partArgs, ")[", args, "]") } else { - x.g.P("return x.Find", index.Name(), "Map", i, "(", partArgs, ")[", x.mapKeyType(index), "{", args, "}]") + x.g.P("return x.Find", index.Name(), "Map", i, "(", partArgs, ")[", x.indexMapKeyType(index), "{", args, "}]") } x.g.P("}") x.g.P() diff --git a/cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go similarity index 63% rename from cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go rename to cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index 6959bbb0..49eb7c43 100644 --- a/cmd/protoc-gen-go-tableau-loader/orderedindex/ordered_index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -1,4 +1,4 @@ -package orderedindex +package indexes import ( "fmt" @@ -6,44 +6,19 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" - "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/reflect/protoreflect" ) -type Generator struct { - gen *protogen.Plugin - g *protogen.GeneratedFile - descriptor *index.IndexDescriptor - message *protogen.Message - level *leveledindex.Generator -} - -func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { - return &Generator{ - gen: gen, - g: g, - descriptor: descriptor, - message: message, - level: level, - } -} - -func (x *Generator) needGenerate() bool { +func (x *Generator) needGenerateOrderedIndex() bool { return options.NeedGenOrderedIndex(x.message.Desc, options.LangGO) } -func (x *Generator) messagerName() string { - return string(x.message.Desc.Name()) -} - -func (x *Generator) mapType(index *index.LevelIndex) string { +func (x *Generator) orderedIndexMapType(index *index.LevelIndex) string { return fmt.Sprintf("%s_OrderedIndex_%sMap", x.messagerName(), index.Name()) } -func (x *Generator) mapKeyType(index *index.LevelIndex) string { +func (x *Generator) orderedIndexMapKeyType(index *index.LevelIndex) string { if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take first field @@ -54,15 +29,10 @@ func (x *Generator) mapKeyType(index *index.LevelIndex) string { } } -func (x *Generator) mapValueType(index *index.LevelIndex) protogen.GoIdent { - return helper.FindMessageGoIdent(x.gen, index.MD) -} - -func (x *Generator) indexContainerName(index *index.LevelIndex) string { - return fmt.Sprintf("orderedIndex%sMap", strcase.ToCamel(index.Name())) -} - -func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { +func (x *Generator) orderedIndexContainerName(index *index.LevelIndex, i int) string { + if i == 0 { + return fmt.Sprintf("orderedIndex%sMap", strcase.ToCamel(index.Name())) + } return fmt.Sprintf("orderedIndex%sMap%d", strcase.ToCamel(index.Name()), i) } @@ -76,7 +46,7 @@ func (x *Generator) mapCtor(index *index.LevelIndex) string { } } -func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { +func (x *Generator) orderedIndexKeys(index *index.LevelIndex) helper.MapKeys { var keys helper.MapKeys for _, field := range index.ColFields { keys = keys.AddMapKey(helper.MapKey{ @@ -88,27 +58,8 @@ func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { return keys } -func (x *Generator) fieldGetter(fd protoreflect.FieldDescriptor) string { - return fmt.Sprintf(".Get%s()", helper.ParseIndexFieldName(x.gen, fd)) -} - -func (x *Generator) parseKeyFieldNameAndSuffix(field *index.LevelField) (string, string) { - var fieldName, suffix string - for i, leveledFd := range field.LeveledFDList { - fieldName += x.fieldGetter(leveledFd) - if i == len(field.LeveledFDList)-1 && leveledFd.Message() != nil { - switch leveledFd.Message().FullName() { - case "google.protobuf.Timestamp", "google.protobuf.Duration": - suffix = ".GetSeconds()" - default: - } - } - } - return fieldName, suffix -} - -func (x *Generator) GenOrderedIndexTypeDef() { - if !x.needGenerate() { +func (x *Generator) genOrderedIndexTypeDef() { + if !x.needGenerateOrderedIndex() { return } x.g.P("// OrderedIndex types.") @@ -117,8 +68,8 @@ func (x *Generator) GenOrderedIndexTypeDef() { x.g.P("// OrderedIndex: ", index.Index) if len(index.ColFields) != 1 { // multi-column index - keyType := x.mapKeyType(index) - keys := x.indexKeys(index) + keyType := x.orderedIndexMapKeyType(index) + keys := x.orderedIndexKeys(index) // generate key struct x.g.P("type ", keyType, " struct {") @@ -142,52 +93,52 @@ func (x *Generator) GenOrderedIndexTypeDef() { x.g.P("}") x.g.P() } - x.g.P("type ", x.mapType(index), " = ", helper.TreeMapPackage.Ident("TreeMap"), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]") + x.g.P("type ", x.orderedIndexMapType(index), " = ", helper.TreeMapPackage.Ident("TreeMap"), "[", x.orderedIndexMapKeyType(index), ", []*", x.mapValueType(index), "]") x.g.P() } } } -func (x *Generator) GenOrderedIndexField() { - if !x.needGenerate() { +func (x *Generator) genOrderedIndexField() { + if !x.needGenerateOrderedIndex() { return } for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.g.P(x.indexContainerName(index), " *", x.mapType(index)) + x.g.P(x.orderedIndexContainerName(index, 0), " *", x.orderedIndexMapType(index)) for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P(x.indexContainerNameI(index, i), " map[", x.level.Keys[0].Type, "]*", x.mapType(index)) + x.g.P(x.orderedIndexContainerName(index, i), " map[", x.keys[0].Type, "]*", x.orderedIndexMapType(index)) } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P(x.indexContainerNameI(index, i), " map[", leveledIndexKeyType, "]*", x.mapType(index)) + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(x.orderedIndexContainerName(index, i), " map[", leveledIndexKeyType, "]*", x.orderedIndexMapType(index)) } } } } } -func (x *Generator) GenOrderedIndexLoader() { - if !x.needGenerate() { +func (x *Generator) genOrderedIndexLoader() { + if !x.needGenerateOrderedIndex() { return } defer x.genOrderedIndexSorter() x.g.P("// OrderedIndex init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.g.P("x.", x.indexContainerName(index), " = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]()") + x.g.P("x.", x.orderedIndexContainerName(index, 0), " = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.orderedIndexMapKeyType(index), ", []*", x.mapValueType(index), "]()") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", x.level.Keys[0].Type, "]*", x.mapType(index), ")") + x.g.P("x.", x.orderedIndexContainerName(index, i), " = make(map[", x.keys[0].Type, "]*", x.orderedIndexMapType(index), ")") } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P("x.", x.indexContainerNameI(index, i), " = make(map[", leveledIndexKeyType, "]*", x.mapType(index), ")") + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("x.", x.orderedIndexContainerName(index, i), " = make(map[", leveledIndexKeyType, "]*", x.orderedIndexMapType(index), ")") } } } @@ -225,11 +176,11 @@ func (x *Generator) genOneOrderedIndexLoader(index *index.LevelIndex, depth int, x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, fieldName, " {") x.g.P("_ = ", keyName) x.g.P("key := ", valueName, suffix) - x.genLoader(depth, index, parentDataName) + x.genOrderedIndexLoaderCommon(depth, index, parentDataName) x.g.P("}") } else { x.g.P("key := ", parentDataName, fieldName, suffix) - x.genLoader(depth, index, parentDataName) + x.genOrderedIndexLoaderCommon(depth, index, parentDataName) } } else { // multi-column index @@ -241,9 +192,9 @@ func (x *Generator) genOneOrderedIndexLoader(index *index.LevelIndex, depth int, func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { cursor := len(keys) if cursor >= len(index.ColFields) { - keyType := x.mapKeyType(index) + keyType := x.orderedIndexMapKeyType(index) x.g.P("key := ", keyType, " {", keys.GenGetArguments(), "}") - x.genLoader(depth, index, parentDataName) + x.genOrderedIndexLoaderCommon(depth, index, parentDataName) return } field := index.ColFields[cursor] @@ -262,35 +213,35 @@ func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.L } } -func (x *Generator) genLoader(depth int, index *index.LevelIndex, parentDataName string) { - indexContainerName := x.indexContainerName(index) +func (x *Generator) genOrderedIndexLoaderCommon(depth int, index *index.LevelIndex, parentDataName string) { + indexContainerName := x.orderedIndexContainerName(index, 0) x.g.P("value, _ := x.", indexContainerName, ".Get(key)") x.g.P("x.", indexContainerName, ".Put(key, append(value, ", parentDataName, "))") for i := 1; i <= depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - indexContainerNameI := x.indexContainerNameI(index, i) - valueName := indexContainerNameI + "Value" + orderedIndexContainerName := x.orderedIndexContainerName(index, i) + valueName := orderedIndexContainerName + "Value" if i == 1 { - x.g.P("if x.", indexContainerNameI, "[k1] == nil {") - x.g.P("x.", indexContainerNameI, "[k1] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]()") + x.g.P("if x.", orderedIndexContainerName, "[k1] == nil {") + x.g.P("x.", orderedIndexContainerName, "[k1] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.orderedIndexMapKeyType(index), ", []*", x.mapValueType(index), "]()") x.g.P("}") - x.g.P(valueName, ", _ := x.", indexContainerNameI, "[k1].Get(key)") - x.g.P("x.", indexContainerNameI, "[k1].Put(key, append(", valueName, ", ", parentDataName, "))") + x.g.P(valueName, ", _ := x.", orderedIndexContainerName, "[k1].Get(key)") + x.g.P("x.", orderedIndexContainerName, "[k1].Put(key, append(", valueName, ", ", parentDataName, "))") } else { var fields []string for j := 1; j <= i; j++ { fields = append(fields, fmt.Sprintf("k%d", j)) } - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - keyName := indexContainerNameI + "Keys" + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + keyName := orderedIndexContainerName + "Keys" x.g.P(keyName, " := ", leveledIndexKeyType, "{", strings.Join(fields, ", "), "}") - x.g.P("if x.", indexContainerNameI, "[", keyName, "] == nil {") - x.g.P("x.", indexContainerNameI, "[", keyName, "] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.mapKeyType(index), ", []*", x.mapValueType(index), "]()") + x.g.P("if x.", orderedIndexContainerName, "[", keyName, "] == nil {") + x.g.P("x.", orderedIndexContainerName, "[", keyName, "] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.orderedIndexMapKeyType(index), ", []*", x.mapValueType(index), "]()") x.g.P("}") - x.g.P(valueName, ", _ := x.", indexContainerNameI, "[", keyName, "].Get(key)") - x.g.P("x.", indexContainerNameI, "[", keyName, "].Put(key, append(", valueName, ", ", parentDataName, "))") + x.g.P(valueName, ", _ := x.", orderedIndexContainerName, "[", keyName, "].Get(key)") + x.g.P("x.", orderedIndexContainerName, "[", keyName, "].Put(key, append(", valueName, ", ", parentDataName, "))") } } } @@ -300,7 +251,7 @@ func (x *Generator) genOrderedIndexSorter() { for _, index := range levelMessage.OrderedIndexes { if len(index.SortedColFields) != 0 { x.g.P("// OrderedIndex(sort): ", index.Index) - indexContainerName := x.indexContainerName(index) + indexContainerName := x.orderedIndexContainerName(index, 0) x.g.P(indexContainerName, "Sorter := func(item []*", x.mapValueType(index), ") func(i, j int) bool {") x.g.P("return func(i, j int) bool {") for i, field := range index.SortedColFields { @@ -315,16 +266,16 @@ func (x *Generator) genOrderedIndexSorter() { } x.g.P("}") x.g.P("}") - x.g.P("x.", x.indexContainerName(index), ".Range(func(key ", x.mapKeyType(index), ", item []*", x.mapValueType(index), ") bool {") + x.g.P("x.", x.orderedIndexContainerName(index, 0), ".Range(func(key ", x.orderedIndexMapKeyType(index), ", item []*", x.mapValueType(index), ") bool {") x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") x.g.P("return true") x.g.P("})") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - x.g.P("for _, item := range x.", x.indexContainerNameI(index, i), " {") - x.g.P("item.Range(func(key ", x.mapKeyType(index), ", item1 []*", x.mapValueType(index), ") bool {") + x.g.P("for _, item := range x.", x.orderedIndexContainerName(index, i), " {") + x.g.P("item.Range(func(key ", x.orderedIndexMapKeyType(index), ", item1 []*", x.mapValueType(index), ") bool {") x.g.P(helper.SortPackage.Ident("Slice"), "(item1, ", indexContainerName, "Sorter(item1))") x.g.P("return true") x.g.P("})") @@ -335,25 +286,25 @@ func (x *Generator) genOrderedIndexSorter() { } } -func (x *Generator) GenOrderedIndexFinders() { - if !x.needGenerate() { +func (x *Generator) genOrderedIndexFinders() { + if !x.needGenerateOrderedIndex() { return } for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - indexContainerName := x.indexContainerName(index) + indexContainerName := x.orderedIndexContainerName(index, 0) messagerName := x.messagerName() x.g.P("// OrderedIndex: ", index.Index) x.g.P() x.g.P("// Find", index.Name(), "Map finds the ordered index (", index.Index, ") to value (", x.mapValueType(index), ") treemap.") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") - x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() *", x.mapType(index), " {") + x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() *", x.orderedIndexMapType(index), " {") x.g.P("return x.", indexContainerName) x.g.P("}") x.g.P() - keys := x.indexKeys(index) + keys := x.orderedIndexKeys(index) params := keys.GenGetParams() args := keys.GenGetArguments() x.g.P("// Find", index.Name(), " finds a slice of all values of the given key.") @@ -361,7 +312,7 @@ func (x *Generator) GenOrderedIndexFinders() { if len(index.ColFields) == 1 { x.g.P("val, _ := x.", indexContainerName, ".Get(", args, ")") } else { - x.g.P("val, _ := x.", indexContainerName, ".Get(", x.mapKeyType(index), "{", args, "})") + x.g.P("val, _ := x.", indexContainerName, ".Get(", x.orderedIndexMapKeyType(index), "{", args, "})") } x.g.P("return val") x.g.P("}") @@ -379,23 +330,23 @@ func (x *Generator) GenOrderedIndexFinders() { x.g.P() for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - indexContainerNameI := x.indexContainerNameI(index, i) - partKeys := x.level.Keys[:i] + orderedIndexContainerName := x.orderedIndexContainerName(index, i) + partKeys := x.keys[:i] partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") treemap") x.g.P("// specified by (", partArgs, ").") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") - x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") *", x.mapType(index), " {") + x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") *", x.orderedIndexMapType(index), " {") if len(partKeys) == 1 { - x.g.P("return x.", indexContainerNameI, "[", partArgs, "]") + x.g.P("return x.", orderedIndexContainerName, "[", partArgs, "]") } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P("return x.", indexContainerNameI, "[", leveledIndexKeyType, "{", partArgs, "}]") + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("return x.", orderedIndexContainerName, "[", leveledIndexKeyType, "{", partArgs, "}]") } x.g.P("}") x.g.P() @@ -405,7 +356,7 @@ func (x *Generator) GenOrderedIndexFinders() { if len(index.ColFields) == 1 { x.g.P("val, _ := x.Find", index.Name(), "Map", i, "(", partArgs, ").Get(", args, ")") } else { - x.g.P("val, _ := x.Find", index.Name(), "Map", i, "(", partArgs, ").Get(", x.mapKeyType(index), "{", args, "})") + x.g.P("val, _ := x.Find", index.Name(), "Map", i, "(", partArgs, ").Get(", x.orderedIndexMapKeyType(index), "{", args, "})") } x.g.P("return val") x.g.P("}") diff --git a/cmd/protoc-gen-go-tableau-loader/messager.go b/cmd/protoc-gen-go-tableau-loader/messager.go index 4bee71dd..e409faca 100644 --- a/cmd/protoc-gen-go-tableau-loader/messager.go +++ b/cmd/protoc-gen-go-tableau-loader/messager.go @@ -4,13 +4,10 @@ import ( "fmt" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" - idx "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/index" - "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/leveledindex" - "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/orderedindex" + "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/indexes" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/orderedmap" "github.com/tableauio/loader/internal/extensions" "github.com/tableauio/loader/internal/index" - "github.com/tableauio/loader/internal/options" "github.com/tableauio/tableau/proto/tableaupb" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" @@ -67,15 +64,11 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog indexDescriptor := index.ParseIndexDescriptor(message.Desc) orderedMapGenerator := orderedmap.NewGenerator(gen, g, message) - leveledIndexGenerator := leveledindex.NewGenerator(gen, g, indexDescriptor, message) - indexGenerator := idx.NewGenerator(gen, g, indexDescriptor, message, leveledIndexGenerator) - orderedIndexGenerator := orderedindex.NewGenerator(gen, g, indexDescriptor, message, leveledIndexGenerator) + indexGenerator := indexes.NewGenerator(gen, g, indexDescriptor, message) // type definitions orderedMapGenerator.GenOrderedMapTypeDef() - leveledIndexGenerator.GenLeveledIndexTypeDef() indexGenerator.GenIndexTypeDef() - orderedIndexGenerator.GenOrderedIndexTypeDef() g.P("// ", messagerName, " is a wrapper around protobuf message: ", message.GoIdent, ".") g.P("//") @@ -90,7 +83,6 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog g.P("data, originalData *", message.GoIdent) orderedMapGenerator.GenOrderedMapField() indexGenerator.GenIndexField() - orderedIndexGenerator.GenOrderedIndexField() g.P("}") g.P() @@ -156,12 +148,11 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog g.P("}") g.P() - if options.NeedGenOrderedMap(message.Desc, options.LangGO) || options.NeedGenIndex(message.Desc, options.LangGO) || options.NeedGenOrderedIndex(message.Desc, options.LangGO) { + if orderedMapGenerator.NeedGenerate() || indexGenerator.NeedGenerate() { g.P("// processAfterLoad runs after this messager is loaded.") g.P("func (x *", messagerName, ") processAfterLoad() error {") orderedMapGenerator.GenOrderedMapLoader() indexGenerator.GenIndexLoader() - orderedIndexGenerator.GenOrderedIndexLoader() g.P("return nil") g.P("}") g.P() @@ -171,7 +162,6 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog genMapGetters(gen, g, message, 1, nil, messagerName) orderedMapGenerator.GenOrderedMapGetters() indexGenerator.GenIndexFinders() - orderedIndexGenerator.GenOrderedIndexFinders() } func genMapGetters(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protogen.Message, depth int, keys helper.MapKeys, messagerName string) { diff --git a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go index 6990de39..d321a856 100644 --- a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go +++ b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go @@ -23,7 +23,7 @@ func NewGenerator(gen *protogen.Plugin, g *protogen.GeneratedFile, message *prot } } -func (x *Generator) needGenerate() bool { +func (x *Generator) NeedGenerate() bool { return options.NeedGenOrderedMap(x.message.Desc, options.LangGO) } @@ -48,7 +48,7 @@ func (x *Generator) mapValueFieldType(fd protoreflect.FieldDescriptor) string { } func (x *Generator) GenOrderedMapTypeDef() { - if !x.needGenerate() { + if !x.NeedGenerate() { return } x.g.P("// OrderedMap types.") @@ -86,7 +86,7 @@ func (x *Generator) genOrderedMapTypeDef(md protoreflect.MessageDescriptor, dept } func (x *Generator) GenOrderedMapField() { - if !x.needGenerate() { + if !x.NeedGenerate() { return } md := x.message.Desc @@ -100,7 +100,7 @@ func (x *Generator) GenOrderedMapField() { } func (x *Generator) GenOrderedMapLoader() { - if !x.needGenerate() { + if !x.NeedGenerate() { return } x.g.P("// OrderedMap init.") @@ -162,7 +162,7 @@ func (x *Generator) genOrderedMapLoader(md protoreflect.MessageDescriptor, depth } func (x *Generator) GenOrderedMapGetters() { - if !x.needGenerate() { + if !x.NeedGenerate() { return } x.genOrderedMapGetters(x.message.Desc, 1, nil) From 0fd6cb256e1a0adef3dab6611a9ce22c7eb43327 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Mon, 24 Nov 2025 20:07:37 +0800 Subject: [PATCH 05/15] feat(cpp): unify all index-related logic --- .../leveled_index.go => indexes/generator.go} | 73 +++++++-- .../{index => indexes}/index.go | 137 ++++++----------- .../ordered_index.go | 145 ++++++------------ cmd/protoc-gen-cpp-tableau-loader/messager.go | 22 +-- 4 files changed, 160 insertions(+), 217 deletions(-) rename cmd/protoc-gen-cpp-tableau-loader/{leveledindex/leveled_index.go => indexes/generator.go} (56%) rename cmd/protoc-gen-cpp-tableau-loader/{index => indexes}/index.go (77%) rename cmd/protoc-gen-cpp-tableau-loader/{orderedindex => indexes}/ordered_index.go (75%) diff --git a/cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go similarity index 56% rename from cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go rename to cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go index 43f0dc8b..f0954438 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/leveledindex/leveled_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go @@ -1,11 +1,10 @@ -package leveledindex +package indexes import ( "fmt" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" "github.com/tableauio/loader/internal/index" - "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -15,29 +14,30 @@ type Generator struct { descriptor *index.IndexDescriptor message *protogen.Message + // level message maxDepth int - Keys helper.MapKeys - MapFds []protoreflect.FieldDescriptor + keys helper.MapKeys + mapFds []protoreflect.FieldDescriptor } func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message) *Generator { - gen := &Generator{ + generator := &Generator{ g: g, descriptor: descriptor, message: message, } - gen.init() - return gen + generator.initLevelMessage() + return generator } -func (x *Generator) init() { +func (x *Generator) initLevelMessage() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { if fd := levelMessage.FD; fd != nil && fd.IsMap() { - x.Keys = x.Keys.AddMapKey(helper.MapKey{ + x.keys = x.keys.AddMapKey(helper.MapKey{ Type: helper.ParseMapKeyType(fd.MapKey()), Name: helper.ParseMapFieldName(fd), }) - x.MapFds = append(x.MapFds, fd) + x.mapFds = append(x.mapFds, fd) } if len(levelMessage.Indexes) != 0 || len(levelMessage.OrderedIndexes) != 0 { x.maxDepth = levelMessage.Depth @@ -46,27 +46,54 @@ func (x *Generator) init() { } func (x *Generator) NeedGenerate() bool { - return options.NeedGenIndex(x.message.Desc, options.LangCPP) || options.NeedGenOrderedIndex(x.message.Desc, options.LangCPP) + return x.needGenerateIndex() || x.needGenerateOrderedIndex() } -func (x *Generator) KeyType(mapFd protoreflect.FieldDescriptor) string { +func (x *Generator) messagerName() string { + return string(x.message.Desc.Name()) +} + +func (x *Generator) levelKeyType(mapFd protoreflect.FieldDescriptor) string { return fmt.Sprintf("LeveledIndex_%sKey", helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } -func (x *Generator) GenHppLeveledIndexKeys() { +func (x *Generator) mapValueType(index *index.LevelIndex) string { + return helper.ParseCppClassType(index.MD) +} + +func (x *Generator) fieldGetter(fd protoreflect.FieldDescriptor) string { + return fmt.Sprintf(".%s()", helper.ParseIndexFieldName(fd)) +} + +func (x *Generator) parseKeyFieldNameAndSuffix(field *index.LevelField) (string, string) { + var fieldName, suffix string + for i, leveledFd := range field.LeveledFDList { + fieldName += x.fieldGetter(leveledFd) + if i == len(field.LeveledFDList)-1 && leveledFd.Message() != nil { + switch leveledFd.Message().FullName() { + case "google.protobuf.Timestamp", "google.protobuf.Duration": + suffix = ".seconds()" + default: + } + } + } + return fieldName, suffix +} + +func (x *Generator) GenHppIndexFinders() { if !x.NeedGenerate() { return } - for i := 1; i <= x.maxDepth-3 && i <= len(x.MapFds)-1; i++ { + for i := 1; i <= x.maxDepth-3 && i <= len(x.mapFds)-1; i++ { if i == 1 { x.g.P() x.g.P(helper.Indent(1), "// LeveledIndex keys.") x.g.P(" public:") } - fd := x.MapFds[i] - keyType := x.KeyType(fd) + fd := x.mapFds[i] + keyType := x.levelKeyType(fd) x.g.P(helper.Indent(1), "struct ", keyType, " {") - keys := x.Keys[:i+1] + keys := x.keys[:i+1] for _, key := range keys { x.g.P(helper.Indent(2), key.Type, " ", key.Name, ";") } @@ -84,4 +111,16 @@ func (x *Generator) GenHppLeveledIndexKeys() { x.g.P(helper.Indent(2), "}") x.g.P(helper.Indent(1), "};") } + x.genHppIndexFinders() + x.genHppOrderedIndexFinders() +} + +func (x *Generator) GenIndexLoader() { + x.genIndexLoader() + x.genOrderedIndexLoader() +} + +func (x *Generator) GenCppIndexFinders() { + x.genCppIndexFinders() + x.genCppOrderedIndexFinders() } diff --git a/cmd/protoc-gen-cpp-tableau-loader/index/index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go similarity index 77% rename from cmd/protoc-gen-cpp-tableau-loader/index/index.go rename to cmd/protoc-gen-cpp-tableau-loader/indexes/index.go index 64dc0bec..6a6c4923 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/index/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go @@ -1,4 +1,4 @@ -package index +package indexes import ( "fmt" @@ -7,42 +7,19 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" - "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/reflect/protoreflect" ) -type Generator struct { - g *protogen.GeneratedFile - descriptor *index.IndexDescriptor - message *protogen.Message - level *leveledindex.Generator -} - -func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { - return &Generator{ - g: g, - descriptor: descriptor, - message: message, - level: level, - } -} - -func (x *Generator) NeedGenerate() bool { +func (x *Generator) needGenerateIndex() bool { return options.NeedGenIndex(x.message.Desc, options.LangCPP) } -func (x *Generator) messagerName() string { - return string(x.message.Desc.Name()) -} - -func (x *Generator) mapType(index *index.LevelIndex) string { +func (x *Generator) indexMapType(index *index.LevelIndex) string { return fmt.Sprintf("Index_%sMap", index.Name()) } -func (x *Generator) mapKeyType(index *index.LevelIndex) string { +func (x *Generator) indexMapKeyType(index *index.LevelIndex) string { if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take first field @@ -53,19 +30,14 @@ func (x *Generator) mapKeyType(index *index.LevelIndex) string { } } -func (x *Generator) mapValueType(index *index.LevelIndex) string { - return helper.ParseCppClassType(index.MD) -} - -func (x *Generator) mapValueVectorType(index *index.LevelIndex) string { +func (x *Generator) indexMapValueVectorType(index *index.LevelIndex) string { return fmt.Sprintf("Index_%sVector", index.Name()) } -func (x *Generator) indexContainerName(index *index.LevelIndex) string { - return fmt.Sprintf("index_%s_map_", strcase.ToSnake(index.Name())) -} - -func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { +func (x *Generator) indexContainerName(index *index.LevelIndex, i int) string { + if i == 0 { + return fmt.Sprintf("index_%s_map_", strcase.ToSnake(index.Name())) + } return fmt.Sprintf("index_%s_map%d_", strcase.ToSnake(index.Name()), i) } @@ -80,20 +52,8 @@ func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { return keys } -func (x *Generator) fieldGetter(fd protoreflect.FieldDescriptor) string { - return fmt.Sprintf(".%s()", helper.ParseIndexFieldName(fd)) -} - -func (x *Generator) parseKeyFieldName(field *index.LevelField) string { - var fieldName string - for _, leveledFd := range field.LeveledFDList { - fieldName += x.fieldGetter(leveledFd) - } - return fieldName -} - -func (x *Generator) GenHppIndexFinders() { - if !x.NeedGenerate() { +func (x *Generator) genHppIndexFinders() { + if !x.needGenerateIndex() { return } var once sync.Once @@ -103,9 +63,9 @@ func (x *Generator) GenHppIndexFinders() { once.Do(func() { x.g.P(helper.Indent(1), "// Index accessers.") }) x.g.P(helper.Indent(1), "// Index: ", index.Index) x.g.P(" public:") - mapType := x.mapType(index) - keyType := x.mapKeyType(index) - vectorType := x.mapValueVectorType(index) + mapType := x.indexMapType(index) + keyType := x.indexMapKeyType(index) + vectorType := x.indexMapValueVectorType(index) valueType := x.mapValueType(index) keys := x.indexKeys(index) hasher := "" // std::hash by default @@ -144,10 +104,10 @@ func (x *Generator) GenHppIndexFinders() { x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", keys.GenGetParams(), ") const;") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - partKeys := x.level.Keys[:i] + partKeys := x.keys[:i] x.g.P(helper.Indent(1), "// Finds the index (", index.Index, ") to value (", vectorType, ") hash map") x.g.P(helper.Indent(1), "// specified by (", partKeys.GenGetArguments(), ").") x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") @@ -160,36 +120,36 @@ func (x *Generator) GenHppIndexFinders() { x.g.P() x.g.P(" private:") - x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index), ";") + x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index, 0), ";") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P(helper.Indent(1), "std::unordered_map<", x.level.Keys[0].Type, ", ", mapType, "> ", x.indexContainerNameI(index, i), ";") + x.g.P(helper.Indent(1), "std::unordered_map<", x.keys[0].Type, ", ", mapType, "> ", x.indexContainerName(index, i), ";") } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.indexContainerNameI(index, i), ";") + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.indexContainerName(index, i), ";") } } } } } -func (x *Generator) GenCppIndexLoader() { - if !x.NeedGenerate() { +func (x *Generator) genIndexLoader() { + if !x.needGenerateIndex() { return } defer x.genIndexSorter() x.g.P(helper.Indent(1), "// Index init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.g.P(helper.Indent(1), x.indexContainerName(index), ".clear();") + x.g.P(helper.Indent(1), x.indexContainerName(index, 0), ".clear();") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - x.g.P(helper.Indent(1), x.indexContainerNameI(index, i), ".clear();") + x.g.P(helper.Indent(1), x.indexContainerName(index, i), ".clear();") } } } @@ -220,7 +180,7 @@ func (x *Generator) genOneCppIndexLoader(depth int, index *index.LevelIndex, par if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take the first field - fieldName := x.parseKeyFieldName(field) + fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { itemName := fmt.Sprintf("item%d", depth) x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") @@ -244,13 +204,13 @@ func (x *Generator) genOneCppIndexLoader(depth int, index *index.LevelIndex, par func (x *Generator) generateOneCppMulticolumnIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { cursor := len(keys) if cursor >= len(index.ColFields) { - keyType := x.mapKeyType(index) + keyType := x.indexMapKeyType(index) x.g.P(helper.Indent(ident+1), keyType, " key{", keys.GenGetArguments(), "};") x.genLoader(depth, ident+1, index, "key", parentDataName) return } field := index.ColFields[cursor] - fieldName := x.parseKeyFieldName(field) + fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { itemName := fmt.Sprintf("index_item%d", cursor) x.g.P(helper.Indent(ident+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") @@ -269,19 +229,19 @@ func (x *Generator) generateOneCppMulticolumnIndex(depth, ident int, index *inde } func (x *Generator) genLoader(depth, ident int, index *index.LevelIndex, key, parentDataName string) { - x.g.P(helper.Indent(ident), x.indexContainerName(index), "[", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.indexContainerName(index, 0), "[", key, "].push_back(&", parentDataName, ");") for i := 1; i <= depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.indexContainerName(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") } else { var fields []string for j := 1; j <= i; j++ { fields = append(fields, fmt.Sprintf("item%d.first", j)) } - x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.indexContainerName(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") } } } @@ -292,12 +252,13 @@ func (x *Generator) genIndexSorter() { if len(index.SortedColFields) != 0 { valueType := x.mapValueType(index) x.g.P(helper.Indent(1), "// Index(sort): ", index.Index) - indexContainerName := x.indexContainerName(index) + indexContainerName := x.indexContainerName(index, 0) sorterDef := "auto " + indexContainerName + "sorter = [](" x.g.P(helper.Indent(1), sorterDef, "const ", valueType, "* a,") x.g.P(helper.Indent(1), helper.Whitespace(len(sorterDef)), "const ", valueType, "* b) {") for i, field := range index.SortedColFields { - fieldName := strings.Replace(x.parseKeyFieldName(field), ".", "->", 1) + fieldName, _ := x.parseKeyFieldNameAndSuffix(field) + fieldName = strings.Replace(fieldName, ".", "->", 1) if i == len(index.SortedColFields)-1 { x.g.P(helper.Indent(2), "return a", fieldName, " < b", fieldName, ";") } else { @@ -311,10 +272,10 @@ func (x *Generator) genIndexSorter() { x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(1), "}") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerNameI(index, i), ") {") + x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerName(index, i), ") {") x.g.P(helper.Indent(2), "for (auto&& item1 : item.second) {") x.g.P(helper.Indent(3), "std::sort(item1.second.begin(), item1.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(2), "}") @@ -325,15 +286,15 @@ func (x *Generator) genIndexSorter() { } } -func (x *Generator) GenCppIndexFinders() { - if !x.NeedGenerate() { +func (x *Generator) genCppIndexFinders() { + if !x.needGenerateIndex() { return } for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - vectorType := x.mapValueVectorType(index) - mapType := x.mapType(index) - indexContainerName := x.indexContainerName(index) + vectorType := x.indexMapValueVectorType(index) + mapType := x.indexMapType(index) + indexContainerName := x.indexContainerName(index, 0) messagerName := x.messagerName() x.g.P("// Index: ", index.Index) @@ -366,20 +327,20 @@ func (x *Generator) GenCppIndexFinders() { x.g.P() for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - indexContainerNameI := x.indexContainerNameI(index, i) - partKeys := x.level.Keys[:i] + indexContainerName := x.indexContainerName(index, i) + partKeys := x.keys[:i] partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() x.g.P("const ", messagerName, "::", mapType, "* ", messagerName, "::Find", index.Name(), "Map(", partParams, ") const {") if len(partKeys) == 1 { - x.g.P(helper.Indent(1), "auto iter = ", indexContainerNameI, ".find(", partArgs, ");") + x.g.P(helper.Indent(1), "auto iter = ", indexContainerName, ".find(", partArgs, ");") } else { - x.g.P(helper.Indent(1), "auto iter = ", indexContainerNameI, ".find({", partArgs, "});") + x.g.P(helper.Indent(1), "auto iter = ", indexContainerName, ".find({", partArgs, "});") } - x.g.P(helper.Indent(1), "if (iter == ", indexContainerNameI, ".end()) {") + x.g.P(helper.Indent(1), "if (iter == ", indexContainerName, ".end()) {") x.g.P(helper.Indent(2), "return nullptr;") x.g.P(helper.Indent(1), "}") x.g.P(helper.Indent(1), "return &iter->second;") diff --git a/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go similarity index 75% rename from cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go rename to cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go index b7799b32..5a2e2b27 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/orderedindex/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go @@ -1,4 +1,4 @@ -package orderedindex +package indexes import ( "fmt" @@ -7,42 +7,19 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" - "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/leveledindex" "github.com/tableauio/loader/internal/index" "github.com/tableauio/loader/internal/options" - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/reflect/protoreflect" ) -type Generator struct { - g *protogen.GeneratedFile - descriptor *index.IndexDescriptor - message *protogen.Message - level *leveledindex.Generator -} - -func NewGenerator(g *protogen.GeneratedFile, descriptor *index.IndexDescriptor, message *protogen.Message, level *leveledindex.Generator) *Generator { - return &Generator{ - g: g, - descriptor: descriptor, - message: message, - level: level, - } -} - -func (x *Generator) NeedGenerate() bool { +func (x *Generator) needGenerateOrderedIndex() bool { return options.NeedGenOrderedIndex(x.message.Desc, options.LangCPP) } -func (x *Generator) messagerName() string { - return string(x.message.Desc.Name()) -} - -func (x *Generator) mapType(index *index.LevelIndex) string { +func (x *Generator) orderedIndexMapType(index *index.LevelIndex) string { return fmt.Sprintf("OrderedIndex_%sMap", index.Name()) } -func (x *Generator) mapKeyType(index *index.LevelIndex) string { +func (x *Generator) orderedIndexMapKeyType(index *index.LevelIndex) string { if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take first field @@ -53,23 +30,18 @@ func (x *Generator) mapKeyType(index *index.LevelIndex) string { } } -func (x *Generator) mapValueType(index *index.LevelIndex) string { - return helper.ParseCppClassType(index.MD) -} - -func (x *Generator) mapValueVectorType(index *index.LevelIndex) string { +func (x *Generator) orderedIndexMapValueVectorType(index *index.LevelIndex) string { return fmt.Sprintf("OrderedIndex_%sVector", index.Name()) } -func (x *Generator) indexContainerName(index *index.LevelIndex) string { - return fmt.Sprintf("ordered_index_%s_map_", strcase.ToSnake(index.Name())) -} - -func (x *Generator) indexContainerNameI(index *index.LevelIndex, i int) string { +func (x *Generator) orderedIndexContainerName(index *index.LevelIndex, i int) string { + if i == 0 { + return fmt.Sprintf("ordered_index_%s_map_", strcase.ToSnake(index.Name())) + } return fmt.Sprintf("ordered_index_%s_map%d_", strcase.ToSnake(index.Name()), i) } -func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { +func (x *Generator) orderedIndexKeys(index *index.LevelIndex) helper.MapKeys { var keys helper.MapKeys for _, field := range index.ColFields { keys = keys.AddMapKey(helper.MapKey{ @@ -80,27 +52,8 @@ func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { return keys } -func (x *Generator) fieldGetter(fd protoreflect.FieldDescriptor) string { - return fmt.Sprintf(".%s()", helper.ParseIndexFieldName(fd)) -} - -func (x *Generator) parseKeyFieldNameAndSuffix(field *index.LevelField) (string, string) { - var fieldName, suffix string - for i, leveledFd := range field.LeveledFDList { - fieldName += x.fieldGetter(leveledFd) - if i == len(field.LeveledFDList)-1 && leveledFd.Message() != nil { - switch leveledFd.Message().FullName() { - case "google.protobuf.Timestamp", "google.protobuf.Duration": - suffix = ".seconds()" - default: - } - } - } - return fieldName, suffix -} - -func (x *Generator) GenHppOrderedIndexFinders() { - if !x.NeedGenerate() { +func (x *Generator) genHppOrderedIndexFinders() { + if !x.needGenerateOrderedIndex() { return } var once sync.Once @@ -110,11 +63,11 @@ func (x *Generator) GenHppOrderedIndexFinders() { once.Do(func() { x.g.P(helper.Indent(1), "// OrderedIndex accessers.") }) x.g.P(helper.Indent(1), "// OrderedIndex: ", index.Index) x.g.P(" public:") - mapType := x.mapType(index) - keyType := x.mapKeyType(index) - vectorType := x.mapValueVectorType(index) + mapType := x.orderedIndexMapType(index) + keyType := x.orderedIndexMapKeyType(index) + vectorType := x.orderedIndexMapValueVectorType(index) valueType := x.mapValueType(index) - keys := x.indexKeys(index) + keys := x.orderedIndexKeys(index) if len(index.ColFields) != 1 { // multi-column index // Generate key struct @@ -141,10 +94,10 @@ func (x *Generator) GenHppOrderedIndexFinders() { x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") x.g.P(helper.Indent(1), "const ", helper.ParseCppClassType(index.MD), "* FindFirst", index.Name(), "(", keys.GenGetParams(), ") const;") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - partKeys := x.level.Keys[:i] + partKeys := x.keys[:i] x.g.P(helper.Indent(1), "// Finds the ordered index (", index.Index, ") to value (", vectorType, ") map") x.g.P(helper.Indent(1), "// specified by (", partKeys.GenGetArguments(), ").") x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") @@ -157,36 +110,36 @@ func (x *Generator) GenHppOrderedIndexFinders() { x.g.P() x.g.P(" private:") - x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index), ";") + x.g.P(helper.Indent(1), mapType, " ", x.orderedIndexContainerName(index, 0), ";") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P(helper.Indent(1), "std::unordered_map<", x.level.Keys[0].Type, ", ", mapType, "> ", x.indexContainerNameI(index, i), ";") + x.g.P(helper.Indent(1), "std::unordered_map<", x.keys[0].Type, ", ", mapType, "> ", x.orderedIndexContainerName(index, i), ";") } else { - leveledIndexKeyType := x.level.KeyType(x.level.MapFds[i-1]) - x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.indexContainerNameI(index, i), ";") + leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.orderedIndexContainerName(index, i), ";") } } } } } -func (x *Generator) GenCppOrderedIndexLoader() { - if !x.NeedGenerate() { +func (x *Generator) genOrderedIndexLoader() { + if !x.needGenerateOrderedIndex() { return } defer x.genOrderedIndexSorter() x.g.P(helper.Indent(1), "// OrderedIndex init.") for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.g.P(helper.Indent(1), x.indexContainerName(index), ".clear();") + x.g.P(helper.Indent(1), x.orderedIndexContainerName(index, 0), ".clear();") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - x.g.P(helper.Indent(1), x.indexContainerNameI(index, i), ".clear();") + x.g.P(helper.Indent(1), x.orderedIndexContainerName(index, i), ".clear();") } } } @@ -225,11 +178,11 @@ func (x *Generator) genOneCppOrderedIndexLoader(depth int, index *index.LevelInd if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } - x.genLoader(depth, depth+2, index, key, parentDataName) + x.genOrderedLoader(depth, depth+2, index, key, parentDataName) x.g.P(helper.Indent(depth+1), "}") } else { key := parentDataName + fieldName + suffix - x.genLoader(depth, depth+1, index, key, parentDataName) + x.genOrderedLoader(depth, depth+1, index, key, parentDataName) } } else { // multi-column index @@ -241,9 +194,9 @@ func (x *Generator) genOneCppOrderedIndexLoader(depth int, index *index.LevelInd func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { cursor := len(keys) if cursor >= len(index.ColFields) { - keyType := x.mapKeyType(index) + keyType := x.orderedIndexMapKeyType(index) x.g.P(helper.Indent(ident+1), keyType, " key{", keys.GenGetArguments(), "};") - x.genLoader(depth, ident+1, index, "key", parentDataName) + x.genOrderedLoader(depth, ident+1, index, "key", parentDataName) return } field := index.ColFields[cursor] @@ -265,20 +218,20 @@ func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth, ident int, inde } } -func (x *Generator) genLoader(depth, ident int, index *index.LevelIndex, key, parentDataName string) { - x.g.P(helper.Indent(ident), x.indexContainerName(index), "[", key, "].push_back(&", parentDataName, ");") +func (x *Generator) genOrderedLoader(depth, ident int, index *index.LevelIndex, key, parentDataName string) { + x.g.P(helper.Indent(ident), x.orderedIndexContainerName(index, 0), "[", key, "].push_back(&", parentDataName, ");") for i := 1; i <= depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } if i == 1 { - x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.orderedIndexContainerName(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") } else { var fields []string for j := 1; j <= i; j++ { fields = append(fields, fmt.Sprintf("item%d.first", j)) } - x.g.P(helper.Indent(ident), x.indexContainerNameI(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.orderedIndexContainerName(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") } } } @@ -289,7 +242,7 @@ func (x *Generator) genOrderedIndexSorter() { if len(index.SortedColFields) != 0 { valueType := x.mapValueType(index) x.g.P(helper.Indent(1), "// OrderedIndex(sort): ", index.Index) - indexContainerName := x.indexContainerName(index) + indexContainerName := x.orderedIndexContainerName(index, 0) sorterDef := "auto " + indexContainerName + "sorter = [](" x.g.P(helper.Indent(1), sorterDef, "const ", valueType, "* a,") x.g.P(helper.Indent(1), helper.Whitespace(len(sorterDef)), "const ", valueType, "* b) {") @@ -309,10 +262,10 @@ func (x *Generator) genOrderedIndexSorter() { x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(1), "}") for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - x.g.P(helper.Indent(1), "for (auto&& item : ", x.indexContainerNameI(index, i), ") {") + x.g.P(helper.Indent(1), "for (auto&& item : ", x.orderedIndexContainerName(index, i), ") {") x.g.P(helper.Indent(2), "for (auto&& item1 : item.second) {") x.g.P(helper.Indent(3), "std::sort(item1.second.begin(), item1.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(2), "}") @@ -323,22 +276,22 @@ func (x *Generator) genOrderedIndexSorter() { } } -func (x *Generator) GenCppOrderedIndexFinders() { - if !x.NeedGenerate() { +func (x *Generator) genCppOrderedIndexFinders() { + if !x.needGenerateOrderedIndex() { return } for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - vectorType := x.mapValueVectorType(index) - mapType := x.mapType(index) - indexContainerName := x.indexContainerName(index) + vectorType := x.orderedIndexMapValueVectorType(index) + mapType := x.orderedIndexMapType(index) + indexContainerName := x.orderedIndexContainerName(index, 0) messagerName := x.messagerName() x.g.P("// OrderedIndex: ", index.Index) x.g.P("const ", messagerName, "::", mapType, "& ", messagerName, "::Find", index.Name(), "Map() const { return ", indexContainerName, " ;}") x.g.P() - keys := x.indexKeys(index) + keys := x.orderedIndexKeys(index) params := keys.GenGetParams() args := keys.GenGetArguments() x.g.P("const ", messagerName, "::", vectorType, "* ", messagerName, "::Find", index.Name(), "(", params, ") const {") @@ -364,11 +317,11 @@ func (x *Generator) GenCppOrderedIndexFinders() { x.g.P() for i := 1; i <= levelMessage.Depth-2; i++ { - if i > len(x.level.Keys) { + if i > len(x.keys) { break } - indexContainerNameI := x.indexContainerNameI(index, i) - partKeys := x.level.Keys[:i] + indexContainerNameI := x.orderedIndexContainerName(index, i) + partKeys := x.keys[:i] partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() x.g.P("const ", messagerName, "::", mapType, "* ", messagerName, "::Find", index.Name(), "Map(", partParams, ") const {") diff --git a/cmd/protoc-gen-cpp-tableau-loader/messager.go b/cmd/protoc-gen-cpp-tableau-loader/messager.go index 15ac213f..9d17157b 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/messager.go +++ b/cmd/protoc-gen-cpp-tableau-loader/messager.go @@ -4,9 +4,7 @@ import ( "strings" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" - idx "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/index" - "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/leveledindex" - "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/orderedindex" + "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/indexes" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/orderedmap" "github.com/tableauio/loader/internal/extensions" "github.com/tableauio/loader/internal/index" @@ -86,9 +84,7 @@ func genHppMessage(g *protogen.GeneratedFile, message *protogen.Message) { indexDescriptor := index.ParseIndexDescriptor(message.Desc) orderedMapGenerator := orderedmap.NewGenerator(g, message) - leveledIndexGenerator := leveledindex.NewGenerator(g, indexDescriptor, message) - indexGenerator := idx.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) - orderedIndexGenerator := orderedindex.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) + indexGenerator := indexes.NewGenerator(g, indexDescriptor, message) g.P("class ", message.Desc.Name(), " : public Messager {") g.P(" public:") @@ -98,7 +94,7 @@ func genHppMessage(g *protogen.GeneratedFile, message *protogen.Message) { g.P(helper.Indent(1), "const google::protobuf::Message* Message() const override { return &data_; }") g.P() - if orderedMapGenerator.NeedGenerate() || indexGenerator.NeedGenerate() || orderedIndexGenerator.NeedGenerate() { + if orderedMapGenerator.NeedGenerate() || indexGenerator.NeedGenerate() { g.P(" private:") g.P(helper.Indent(1), "virtual bool ProcessAfterLoad() override final;") g.P() @@ -111,9 +107,7 @@ func genHppMessage(g *protogen.GeneratedFile, message *protogen.Message) { g.P(helper.Indent(1), "static const std::string kProtoName;") g.P(helper.Indent(1), cppFullName, " data_;") orderedMapGenerator.GenHppOrderedMapGetters() - leveledIndexGenerator.GenHppLeveledIndexKeys() indexGenerator.GenHppIndexFinders() - orderedIndexGenerator.GenHppOrderedIndexFinders() g.P("};") g.P() } @@ -164,9 +158,7 @@ func genCppMessage(g *protogen.GeneratedFile, message *protogen.Message) { indexDescriptor := index.ParseIndexDescriptor(message.Desc) orderedMapGenerator := orderedmap.NewGenerator(g, message) - leveledIndexGenerator := leveledindex.NewGenerator(g, indexDescriptor, message) - indexGenerator := idx.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) - orderedIndexGenerator := orderedindex.NewGenerator(g, indexDescriptor, message, leveledIndexGenerator) + indexGenerator := indexes.NewGenerator(g, indexDescriptor, message) g.P("const std::string ", messagerName, "::kProtoName = ", cppFullName, `::GetDescriptor()->name();`) g.P() @@ -179,11 +171,10 @@ func genCppMessage(g *protogen.GeneratedFile, message *protogen.Message) { g.P("}") g.P() - if orderedMapGenerator.NeedGenerate() || indexGenerator.NeedGenerate() || orderedIndexGenerator.NeedGenerate() { + if orderedMapGenerator.NeedGenerate() || indexGenerator.NeedGenerate() { g.P("bool ", messagerName, "::ProcessAfterLoad() {") orderedMapGenerator.GenOrderedMapLoader() - indexGenerator.GenCppIndexLoader() - orderedIndexGenerator.GenCppOrderedIndexLoader() + indexGenerator.GenIndexLoader() g.P(helper.Indent(1), "return true;") g.P("}") g.P() @@ -193,7 +184,6 @@ func genCppMessage(g *protogen.GeneratedFile, message *protogen.Message) { genCppMapGetters(g, message.Desc, 1, nil, messagerName) orderedMapGenerator.GenOrderedMapGetters() indexGenerator.GenCppIndexFinders() - orderedIndexGenerator.GenCppOrderedIndexFinders() } func genCppMapGetters(g *protogen.GeneratedFile, md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys, messagerName string) { From 0bc18655d6fa080eeda2706ddfec06a885d9ed28 Mon Sep 17 00:00:00 2001 From: wenchy Date: Mon, 8 Dec 2025 22:11:46 +0800 Subject: [PATCH 06/15] refactor: FruitConf fields renaming --- .../src/protoconf/item_conf.pc.cc | 70 ++++++------- .../src/protoconf/item_conf.pc.h | 30 +++--- .../protoconf/loader/item_conf.pc.go | 98 +++++++++---------- test/proto/item_conf.proto | 12 +-- 4 files changed, 105 insertions(+), 105 deletions(-) diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index 69cb1dd1..b4902cc2 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -393,82 +393,82 @@ bool FruitConf::Load(const std::filesystem::path& dir, Format fmt, std::shared_p bool FruitConf::ProcessAfterLoad() { // OrderedIndex init. - ordered_index_fruit_map_.clear(); - ordered_index_fruit_map1_.clear(); - for (auto&& item1 : data_.fruits_map()) { - for (auto&& item2 : item1.second.fruit_map()) { + ordered_index_item_map_.clear(); + ordered_index_item_map1_.clear(); + for (auto&& item1 : data_.fruit_map()) { + for (auto&& item2 : item1.second.item_map()) { { - // OrderedIndex: Price - ordered_index_fruit_map_[item2.second.price()].push_back(&item2.second); - ordered_index_fruit_map1_[item1.first][item2.second.price()].push_back(&item2.second); + // OrderedIndex: Price + ordered_index_item_map_[item2.second.price()].push_back(&item2.second); + ordered_index_item_map1_[item1.first][item2.second.price()].push_back(&item2.second); } } } - // OrderedIndex(sort): Price - auto ordered_index_fruit_map_sorter = [](const protoconf::FruitConf::Fruits::Fruit* a, - const protoconf::FruitConf::Fruits::Fruit* b) { - return a->fruit_id() < b->fruit_id(); + // OrderedIndex(sort): Price + auto ordered_index_item_map_sorter = [](const protoconf::FruitConf::Fruit::Item* a, + const protoconf::FruitConf::Fruit::Item* b) { + return a->id() < b->id(); }; - for (auto&& item : ordered_index_fruit_map_) { - std::sort(item.second.begin(), item.second.end(), ordered_index_fruit_map_sorter); + for (auto&& item : ordered_index_item_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); } - for (auto&& item : ordered_index_fruit_map1_) { + for (auto&& item : ordered_index_item_map1_) { for (auto&& item1 : item.second) { - std::sort(item1.second.begin(), item1.second.end(), ordered_index_fruit_map_sorter); + std::sort(item1.second.begin(), item1.second.end(), ordered_index_item_map_sorter); } } return true; } -const protoconf::FruitConf::Fruits* FruitConf::Get(int32_t fruit_type) const { - auto iter = data_.fruits_map().find(fruit_type); - if (iter == data_.fruits_map().end()) { +const protoconf::FruitConf::Fruit* FruitConf::Get(int32_t fruit_type) const { + auto iter = data_.fruit_map().find(fruit_type); + if (iter == data_.fruit_map().end()) { return nullptr; } return &iter->second; } -const protoconf::FruitConf::Fruits::Fruit* FruitConf::Get(int32_t fruit_type, int32_t fruit_id) const { +const protoconf::FruitConf::Fruit::Item* FruitConf::Get(int32_t fruit_type, int32_t id) const { const auto* conf = Get(fruit_type); if (conf == nullptr) { return nullptr; } - auto iter = conf->fruit_map().find(fruit_id); - if (iter == conf->fruit_map().end()) { + auto iter = conf->item_map().find(id); + if (iter == conf->item_map().end()) { return nullptr; } return &iter->second; } -// OrderedIndex: Price -const FruitConf::OrderedIndex_FruitMap& FruitConf::FindFruitMap() const { return ordered_index_fruit_map_ ;} +// OrderedIndex: Price +const FruitConf::OrderedIndex_ItemMap& FruitConf::FindItemMap() const { return ordered_index_item_map_ ;} -const FruitConf::OrderedIndex_FruitVector* FruitConf::FindFruit(int32_t price) const { - auto iter = ordered_index_fruit_map_.find(price); - if (iter == ordered_index_fruit_map_.end()) { +const FruitConf::OrderedIndex_ItemVector* FruitConf::FindItem(int32_t price) const { + auto iter = ordered_index_item_map_.find(price); + if (iter == ordered_index_item_map_.end()) { return nullptr; } return &iter->second; } -const protoconf::FruitConf::Fruits::Fruit* FruitConf::FindFirstFruit(int32_t price) const { - auto conf = FindFruit(price); +const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t price) const { + auto conf = FindItem(price); if (conf == nullptr || conf->empty()) { return nullptr; } return conf->front(); } -const FruitConf::OrderedIndex_FruitMap* FruitConf::FindFruitMap(int32_t fruit_type) const { - auto iter = ordered_index_fruit_map1_.find(fruit_type); - if (iter == ordered_index_fruit_map1_.end()) { +const FruitConf::OrderedIndex_ItemMap* FruitConf::FindItemMap(int32_t fruit_type) const { + auto iter = ordered_index_item_map1_.find(fruit_type); + if (iter == ordered_index_item_map1_.end()) { return nullptr; } return &iter->second; } -const FruitConf::OrderedIndex_FruitVector* FruitConf::FindFruit(int32_t fruit_type, int32_t price) const { - auto map = FindFruitMap(fruit_type); +const FruitConf::OrderedIndex_ItemVector* FruitConf::FindItem(int32_t fruit_type, int32_t price) const { + auto map = FindItemMap(fruit_type); if (map == nullptr) { return nullptr; } @@ -479,8 +479,8 @@ const FruitConf::OrderedIndex_FruitVector* FruitConf::FindFruit(int32_t fruit_ty return &iter->second; } -const protoconf::FruitConf::Fruits::Fruit* FruitConf::FindFirstFruit(int32_t fruit_type, int32_t price) const { - auto conf = FindFruit(fruit_type, price); +const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t fruit_type, int32_t price) const { + auto conf = FindItem(fruit_type, price); if (conf == nullptr || conf->empty()) { return nullptr; } diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index 3e9dacac..24c50e94 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -277,37 +277,37 @@ class FruitConf : public Messager { virtual bool ProcessAfterLoad() override final; public: - const protoconf::FruitConf::Fruits* Get(int32_t fruit_type) const; - const protoconf::FruitConf::Fruits::Fruit* Get(int32_t fruit_type, int32_t fruit_id) const; + const protoconf::FruitConf::Fruit* Get(int32_t fruit_type) const; + const protoconf::FruitConf::Fruit::Item* Get(int32_t fruit_type, int32_t id) const; private: static const std::string kProtoName; protoconf::FruitConf data_; // OrderedIndex accessers. - // OrderedIndex: Price + // OrderedIndex: Price public: - using OrderedIndex_FruitVector = std::vector; - using OrderedIndex_FruitMap = std::map; - // Finds the ordered index (Price) to value (OrderedIndex_FruitVector) map. + using OrderedIndex_ItemVector = std::vector; + using OrderedIndex_ItemMap = std::map; + // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map. // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_FruitMap& FindFruitMap() const; + const OrderedIndex_ItemMap& FindItemMap() const; // Finds a vector of all values of the given key(s). - const OrderedIndex_FruitVector* FindFruit(int32_t price) const; + const OrderedIndex_ItemVector* FindItem(int32_t price) const; // Finds the first value of the given key(s). - const protoconf::FruitConf::Fruits::Fruit* FindFirstFruit(int32_t price) const; - // Finds the ordered index (Price) to value (OrderedIndex_FruitVector) map + const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t price) const; + // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map // specified by (fruit_type). // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_FruitMap* FindFruitMap(int32_t fruit_type) const; + const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; // Finds a vector of all values of the given key(s) specified by (fruit_type). - const OrderedIndex_FruitVector* FindFruit(int32_t fruit_type, int32_t price) const; + const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; // Finds the first value of the given key(s) specified by (fruit_type). - const protoconf::FruitConf::Fruits::Fruit* FindFirstFruit(int32_t fruit_type, int32_t price) const; + const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; private: - OrderedIndex_FruitMap ordered_index_fruit_map_; - std::unordered_map ordered_index_fruit_map1_; + OrderedIndex_ItemMap ordered_index_item_map_; + std::unordered_map ordered_index_item_map1_; }; } // namespace tableau diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index fc972bbf..8a0066d2 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -599,8 +599,8 @@ func (x *ItemConf) FindFirstParamExtType(param int32, extType protoconf.FruitTyp } // OrderedIndex types. -// OrderedIndex: Price -type FruitConf_OrderedIndex_FruitMap = treemap.TreeMap[int32, []*protoconf.FruitConf_Fruits_Fruit] +// OrderedIndex: Price +type FruitConf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.FruitConf_Fruit_Item] // FruitConf is a wrapper around protobuf message: protoconf.FruitConf. // @@ -611,9 +611,9 @@ type FruitConf_OrderedIndex_FruitMap = treemap.TreeMap[int32, []*protoconf.Fruit // 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... type FruitConf struct { UnimplementedMessager - data, originalData *protoconf.FruitConf - orderedIndexFruitMap *FruitConf_OrderedIndex_FruitMap - orderedIndexFruitMap1 map[int32]*FruitConf_OrderedIndex_FruitMap + data, originalData *protoconf.FruitConf + orderedIndexItemMap *FruitConf_OrderedIndex_ItemMap + orderedIndexItemMap1 map[int32]*FruitConf_OrderedIndex_ItemMap } // Name returns the FruitConf's message name. @@ -673,38 +673,38 @@ func (x *FruitConf) originalMessage() proto.Message { // processAfterLoad runs after this messager is loaded. func (x *FruitConf) processAfterLoad() error { // OrderedIndex init. - x.orderedIndexFruitMap = treemap.New[int32, []*protoconf.FruitConf_Fruits_Fruit]() - x.orderedIndexFruitMap1 = make(map[int32]*FruitConf_OrderedIndex_FruitMap) - for k1, v1 := range x.data.GetFruitsMap() { + x.orderedIndexItemMap = treemap.New[int32, []*protoconf.FruitConf_Fruit_Item]() + x.orderedIndexItemMap1 = make(map[int32]*FruitConf_OrderedIndex_ItemMap) + for k1, v1 := range x.data.GetFruitMap() { _ = k1 - for k2, v2 := range v1.GetFruitMap() { + for k2, v2 := range v1.GetItemMap() { _ = k2 { - // OrderedIndex: Price + // OrderedIndex: Price key := v2.GetPrice() - value, _ := x.orderedIndexFruitMap.Get(key) - x.orderedIndexFruitMap.Put(key, append(value, v2)) - if x.orderedIndexFruitMap1[k1] == nil { - x.orderedIndexFruitMap1[k1] = treemap.New[int32, []*protoconf.FruitConf_Fruits_Fruit]() + value, _ := x.orderedIndexItemMap.Get(key) + x.orderedIndexItemMap.Put(key, append(value, v2)) + if x.orderedIndexItemMap1[k1] == nil { + x.orderedIndexItemMap1[k1] = treemap.New[int32, []*protoconf.FruitConf_Fruit_Item]() } - orderedIndexFruitMap1Value, _ := x.orderedIndexFruitMap1[k1].Get(key) - x.orderedIndexFruitMap1[k1].Put(key, append(orderedIndexFruitMap1Value, v2)) + orderedIndexItemMap1Value, _ := x.orderedIndexItemMap1[k1].Get(key) + x.orderedIndexItemMap1[k1].Put(key, append(orderedIndexItemMap1Value, v2)) } } } - // OrderedIndex(sort): Price - orderedIndexFruitMapSorter := func(item []*protoconf.FruitConf_Fruits_Fruit) func(i, j int) bool { + // OrderedIndex(sort): Price + orderedIndexItemMapSorter := func(item []*protoconf.FruitConf_Fruit_Item) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetFruitId() < item[j].GetFruitId() + return item[i].GetId() < item[j].GetId() } } - x.orderedIndexFruitMap.Range(func(key int32, item []*protoconf.FruitConf_Fruits_Fruit) bool { - sort.Slice(item, orderedIndexFruitMapSorter(item)) + x.orderedIndexItemMap.Range(func(key int32, item []*protoconf.FruitConf_Fruit_Item) bool { + sort.Slice(item, orderedIndexItemMapSorter(item)) return true }) - for _, item := range x.orderedIndexFruitMap1 { - item.Range(func(key int32, item1 []*protoconf.FruitConf_Fruits_Fruit) bool { - sort.Slice(item1, orderedIndexFruitMapSorter(item1)) + for _, item := range x.orderedIndexItemMap1 { + item.Range(func(key int32, item1 []*protoconf.FruitConf_Fruit_Item) bool { + sort.Slice(item1, orderedIndexItemMapSorter(item1)) return true }) } @@ -713,8 +713,8 @@ func (x *FruitConf) processAfterLoad() error { // Get1 finds value in the 1-level map. It will return // NotFound error if the key is not found. -func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruits, error) { - d := x.Data().GetFruitsMap() +func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruit, error) { + d := x.Data().GetFruitMap() if val, ok := d[fruitType]; !ok { return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) } else { @@ -724,60 +724,60 @@ func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruits, error) { // Get2 finds value in the 2-level map. It will return // NotFound error if the key is not found. -func (x *FruitConf) Get2(fruitType int32, fruitId int32) (*protoconf.FruitConf_Fruits_Fruit, error) { +func (x *FruitConf) Get2(fruitType int32, id int32) (*protoconf.FruitConf_Fruit_Item, error) { conf, err := x.Get1(fruitType) if err != nil { return nil, err } - d := conf.GetFruitMap() - if val, ok := d[fruitId]; !ok { - return nil, fmt.Errorf("fruitId(%v) %w", fruitId, ErrNotFound) + d := conf.GetItemMap() + if val, ok := d[id]; !ok { + return nil, fmt.Errorf("id(%v) %w", id, ErrNotFound) } else { return val, nil } } -// OrderedIndex: Price +// OrderedIndex: Price -// FindFruitMap finds the ordered index (Price) to value (protoconf.FruitConf_Fruits_Fruit) treemap. +// FindItemMap finds the ordered index (Price) to value (protoconf.FruitConf_Fruit_Item) treemap. // One key may correspond to multiple values, which are contained by a slice. -func (x *FruitConf) FindFruitMap() *FruitConf_OrderedIndex_FruitMap { - return x.orderedIndexFruitMap +func (x *FruitConf) FindItemMap() *FruitConf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap } -// FindFruit finds a slice of all values of the given key. -func (x *FruitConf) FindFruit(price int32) []*protoconf.FruitConf_Fruits_Fruit { - val, _ := x.orderedIndexFruitMap.Get(price) +// FindItem finds a slice of all values of the given key. +func (x *FruitConf) FindItem(price int32) []*protoconf.FruitConf_Fruit_Item { + val, _ := x.orderedIndexItemMap.Get(price) return val } -// FindFirstFruit finds the first value of the given key, +// FindFirstItem finds the first value of the given key, // or nil if no value found. -func (x *FruitConf) FindFirstFruit(price int32) *protoconf.FruitConf_Fruits_Fruit { - val := x.FindFruit(price) +func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { + val := x.FindItem(price) if len(val) > 0 { return val[0] } return nil } -// FindFruitMap1 finds the index (Price) to value (protoconf.FruitConf_Fruits_Fruit) treemap +// FindItemMap1 finds the index (Price) to value (protoconf.FruitConf_Fruit_Item) treemap // specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. -func (x *FruitConf) FindFruitMap1(fruitType int32) *FruitConf_OrderedIndex_FruitMap { - return x.orderedIndexFruitMap1[fruitType] +func (x *FruitConf) FindItemMap1(fruitType int32) *FruitConf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap1[fruitType] } -// FindFruit1 finds a slice of all values of the given key specified by (fruitType). -func (x *FruitConf) FindFruit1(fruitType int32, price int32) []*protoconf.FruitConf_Fruits_Fruit { - val, _ := x.FindFruitMap1(fruitType).Get(price) +// FindItem1 finds a slice of all values of the given key specified by (fruitType). +func (x *FruitConf) FindItem1(fruitType int32, price int32) []*protoconf.FruitConf_Fruit_Item { + val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstFruit1 finds the first value of the given key specified by (fruitType), +// FindFirstItem1 finds the first value of the given key specified by (fruitType), // or nil if no value found. -func (x *FruitConf) FindFirstFruit1(fruitType int32, price int32) *protoconf.FruitConf_Fruits_Fruit { - val := x.FindFruit1(fruitType, price) +func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.FruitConf_Fruit_Item { + val := x.FindItem1(fruitType, price) if len(val) > 0 { return val[0] } diff --git a/test/proto/item_conf.proto b/test/proto/item_conf.proto index 6cc03808..3926834d 100644 --- a/test/proto/item_conf.proto +++ b/test/proto/item_conf.proto @@ -82,15 +82,15 @@ message UseEffect { message FruitConf { option (tableau.worksheet) = { name: "FruitConf" - ordered_index: "Price" + ordered_index: "Price" }; - map fruits_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; - message Fruits { + map fruit_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; + message Fruit { protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; - map fruit_map = 2 [(tableau.field) = { key: "FruitID" layout: LAYOUT_VERTICAL }]; - message Fruit { - int32 fruit_id = 1 [(tableau.field) = { name: "FruitID" }]; + map item_map = 2 [(tableau.field) = { key: "ID" layout: LAYOUT_VERTICAL }]; + message Item { + int32 id = 1 [(tableau.field) = { name: "ID" }]; int32 price = 2 [(tableau.field) = { name: "Price" }]; } } From d5515d052fca8e67fa960216e691d3c7bd0b0982 Mon Sep 17 00:00:00 2001 From: wenchy Date: Mon, 8 Dec 2025 22:42:11 +0800 Subject: [PATCH 07/15] rename: LeveledIndex -> LevelIndex --- .../indexes/generator.go | 4 +-- .../indexes/index.go | 4 +-- .../indexes/ordered_index.go | 4 +-- .../indexes/generator.go | 4 +-- .../indexes/index.go | 16 ++++++------ .../indexes/orderedindex.go | 16 ++++++------ .../src/protoconf/test_conf.pc.h | 26 +++++++++---------- .../protoconf/loader/test_conf.pc.go | 22 ++++++++-------- 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go index f0954438..93f25816 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go @@ -54,7 +54,7 @@ func (x *Generator) messagerName() string { } func (x *Generator) levelKeyType(mapFd protoreflect.FieldDescriptor) string { - return fmt.Sprintf("LeveledIndex_%sKey", helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) + return fmt.Sprintf("LevelIndex_%sKey", helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } func (x *Generator) mapValueType(index *index.LevelIndex) string { @@ -87,7 +87,7 @@ func (x *Generator) GenHppIndexFinders() { for i := 1; i <= x.maxDepth-3 && i <= len(x.mapFds)-1; i++ { if i == 1 { x.g.P() - x.g.P(helper.Indent(1), "// LeveledIndex keys.") + x.g.P(helper.Indent(1), "// LevelIndex keys.") x.g.P(" public:") } fd := x.mapFds[i] diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go index 6a6c4923..410fff8b 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go @@ -128,8 +128,8 @@ func (x *Generator) genHppIndexFinders() { if i == 1 { x.g.P(helper.Indent(1), "std::unordered_map<", x.keys[0].Type, ", ", mapType, "> ", x.indexContainerName(index, i), ";") } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.indexContainerName(index, i), ";") + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(helper.Indent(1), "std::unordered_map<", levelIndexKeyType, ", ", mapType, ", ", levelIndexKeyType, "Hasher> ", x.indexContainerName(index, i), ";") } } } diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go index 5a2e2b27..e8ce03d8 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go @@ -118,8 +118,8 @@ func (x *Generator) genHppOrderedIndexFinders() { if i == 1 { x.g.P(helper.Indent(1), "std::unordered_map<", x.keys[0].Type, ", ", mapType, "> ", x.orderedIndexContainerName(index, i), ";") } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P(helper.Indent(1), "std::unordered_map<", leveledIndexKeyType, ", ", mapType, ", ", leveledIndexKeyType, "Hasher> ", x.orderedIndexContainerName(index, i), ";") + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(helper.Indent(1), "std::unordered_map<", levelIndexKeyType, ", ", mapType, ", ", levelIndexKeyType, "Hasher> ", x.orderedIndexContainerName(index, i), ";") } } } diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/generator.go b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go index ea4d5cdb..69d6d6d7 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/generator.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go @@ -57,7 +57,7 @@ func (x *Generator) messagerName() string { } func (x *Generator) levelKeyType(mapFd protoreflect.FieldDescriptor) string { - return fmt.Sprintf("%s_LeveledIndex_%sKey", x.messagerName(), helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) + return fmt.Sprintf("%s_LevelIndex_%sKey", x.messagerName(), helper.ParseLeveledMapPrefix(x.message.Desc, mapFd)) } func (x *Generator) mapValueType(index *index.LevelIndex) protogen.GoIdent { @@ -90,7 +90,7 @@ func (x *Generator) GenIndexTypeDef() { for i := 1; i <= x.maxDepth-3 && i <= len(x.mapFds)-1; i++ { if i == 1 { x.g.P() - x.g.P("// LeveledIndex keys.") + x.g.P("// LevelIndex keys.") } fd := x.mapFds[i] keyType := x.levelKeyType(fd) diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go index 015ab2fd..51f9027e 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -89,8 +89,8 @@ func (x *Generator) genIndexField() { if i == 1 { x.g.P(x.indexContainerName(index, i), " map[", x.keys[0].Type, "]", x.indexMapType(index)) } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P(x.indexContainerName(index, i), " map[", leveledIndexKeyType, "]", x.indexMapType(index)) + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(x.indexContainerName(index, i), " map[", levelIndexKeyType, "]", x.indexMapType(index)) } } } @@ -113,8 +113,8 @@ func (x *Generator) genIndexLoader() { if i == 1 { x.g.P("x.", x.indexContainerName(index, i), " = make(map[", x.keys[0].Type, "]", x.indexMapType(index), ")") } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P("x.", x.indexContainerName(index, i), " = make(map[", leveledIndexKeyType, "]", x.indexMapType(index), ")") + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("x.", x.indexContainerName(index, i), " = make(map[", levelIndexKeyType, "]", x.indexMapType(index), ")") } } } @@ -206,9 +206,9 @@ func (x *Generator) genIndexLoaderCommon(depth int, index *index.LevelIndex, par for j := 1; j <= i; j++ { fields = append(fields, fmt.Sprintf("k%d", j)) } - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) keyName := indexContainerName + "Keys" - x.g.P(keyName, " := ", leveledIndexKeyType, "{", strings.Join(fields, ", "), "}") + x.g.P(keyName, " := ", levelIndexKeyType, "{", strings.Join(fields, ", "), "}") x.g.P("if x.", indexContainerName, "[", keyName, "] == nil {") x.g.P("x.", indexContainerName, "[", keyName, "] = make(", x.indexMapType(index), ")") x.g.P("}") @@ -313,8 +313,8 @@ func (x *Generator) genIndexFinders() { if len(partKeys) == 1 { x.g.P("return x.", indexContainerName, "[", partArgs, "]") } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P("return x.", indexContainerName, "[", leveledIndexKeyType, "{", partArgs, "}]") + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("return x.", indexContainerName, "[", levelIndexKeyType, "{", partArgs, "}]") } x.g.P("}") x.g.P() diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index 49eb7c43..b830b115 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -113,8 +113,8 @@ func (x *Generator) genOrderedIndexField() { if i == 1 { x.g.P(x.orderedIndexContainerName(index, i), " map[", x.keys[0].Type, "]*", x.orderedIndexMapType(index)) } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P(x.orderedIndexContainerName(index, i), " map[", leveledIndexKeyType, "]*", x.orderedIndexMapType(index)) + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P(x.orderedIndexContainerName(index, i), " map[", levelIndexKeyType, "]*", x.orderedIndexMapType(index)) } } } @@ -137,8 +137,8 @@ func (x *Generator) genOrderedIndexLoader() { if i == 1 { x.g.P("x.", x.orderedIndexContainerName(index, i), " = make(map[", x.keys[0].Type, "]*", x.orderedIndexMapType(index), ")") } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P("x.", x.orderedIndexContainerName(index, i), " = make(map[", leveledIndexKeyType, "]*", x.orderedIndexMapType(index), ")") + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("x.", x.orderedIndexContainerName(index, i), " = make(map[", levelIndexKeyType, "]*", x.orderedIndexMapType(index), ")") } } } @@ -234,9 +234,9 @@ func (x *Generator) genOrderedIndexLoaderCommon(depth int, index *index.LevelInd for j := 1; j <= i; j++ { fields = append(fields, fmt.Sprintf("k%d", j)) } - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) keyName := orderedIndexContainerName + "Keys" - x.g.P(keyName, " := ", leveledIndexKeyType, "{", strings.Join(fields, ", "), "}") + x.g.P(keyName, " := ", levelIndexKeyType, "{", strings.Join(fields, ", "), "}") x.g.P("if x.", orderedIndexContainerName, "[", keyName, "] == nil {") x.g.P("x.", orderedIndexContainerName, "[", keyName, "] = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.orderedIndexMapKeyType(index), ", []*", x.mapValueType(index), "]()") x.g.P("}") @@ -345,8 +345,8 @@ func (x *Generator) genOrderedIndexFinders() { if len(partKeys) == 1 { x.g.P("return x.", orderedIndexContainerName, "[", partArgs, "]") } else { - leveledIndexKeyType := x.levelKeyType(x.mapFds[i-1]) - x.g.P("return x.", orderedIndexContainerName, "[", leveledIndexKeyType, "{", partArgs, "}]") + levelIndexKeyType := x.levelKeyType(x.mapFds[i-1]) + x.g.P("return x.", orderedIndexContainerName, "[", levelIndexKeyType, "{", partArgs, "}]") } x.g.P("}") x.g.P() diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 8f21a5a0..46edb6ab 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -53,38 +53,38 @@ class ActivityConf : public Messager { private: OrderedMap_ActivityMap ordered_map_; - // LeveledIndex keys. + // LevelIndex keys. public: - struct LeveledIndex_Activity_ChapterKey { + struct LevelIndex_Activity_ChapterKey { uint64_t activity_id; uint32_t chapter_id; #if __cplusplus >= 202002L - bool operator==(const LeveledIndex_Activity_ChapterKey& other) const = default; + bool operator==(const LevelIndex_Activity_ChapterKey& other) const = default; #else - bool operator==(const LeveledIndex_Activity_ChapterKey& other) const { + bool operator==(const LevelIndex_Activity_ChapterKey& other) const { return std::tie(activity_id, chapter_id) == std::tie(other.activity_id, other.chapter_id); } #endif }; - struct LeveledIndex_Activity_ChapterKeyHasher { - std::size_t operator()(const LeveledIndex_Activity_ChapterKey& key) const { + struct LevelIndex_Activity_ChapterKeyHasher { + std::size_t operator()(const LevelIndex_Activity_ChapterKey& key) const { return util::SugaredHashCombine(key.activity_id, key.chapter_id); } }; - struct LeveledIndex_protoconf_SectionKey { + struct LevelIndex_protoconf_SectionKey { uint64_t activity_id; uint32_t chapter_id; uint32_t section_id; #if __cplusplus >= 202002L - bool operator==(const LeveledIndex_protoconf_SectionKey& other) const = default; + bool operator==(const LevelIndex_protoconf_SectionKey& other) const = default; #else - bool operator==(const LeveledIndex_protoconf_SectionKey& other) const { + bool operator==(const LevelIndex_protoconf_SectionKey& other) const { return std::tie(activity_id, chapter_id, section_id) == std::tie(other.activity_id, other.chapter_id, other.section_id); } #endif }; - struct LeveledIndex_protoconf_SectionKeyHasher { - std::size_t operator()(const LeveledIndex_protoconf_SectionKey& key) const { + struct LevelIndex_protoconf_SectionKeyHasher { + std::size_t operator()(const LevelIndex_protoconf_SectionKey& key) const { return util::SugaredHashCombine(key.activity_id, key.chapter_id, key.section_id); } }; @@ -192,8 +192,8 @@ class ActivityConf : public Messager { private: Index_AwardMap index_award_map_; std::unordered_map index_award_map1_; - std::unordered_map index_award_map2_; - std::unordered_map index_award_map3_; + std::unordered_map index_award_map2_; + std::unordered_map index_award_map3_; }; class ChapterConf : public Messager { diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index bfbfb2de..2c1b62ea 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -31,12 +31,12 @@ type ActivityConf_OrderedMap_Activity_ChapterMap = treemap.TreeMap[uint32, *Acti type ActivityConf_OrderedMap_ActivityValue = pair.Pair[*ActivityConf_OrderedMap_Activity_ChapterMap, *protoconf.ActivityConf_Activity] type ActivityConf_OrderedMap_ActivityMap = treemap.TreeMap[uint64, *ActivityConf_OrderedMap_ActivityValue] -// LeveledIndex keys. -type ActivityConf_LeveledIndex_Activity_ChapterKey struct { +// LevelIndex keys. +type ActivityConf_LevelIndex_Activity_ChapterKey struct { ActivityId uint64 ChapterId uint32 } -type ActivityConf_LeveledIndex_protoconf_SectionKey struct { +type ActivityConf_LevelIndex_protoconf_SectionKey struct { ActivityId uint64 ChapterId uint32 SectionId uint32 @@ -73,8 +73,8 @@ type ActivityConf struct { indexNamedChapterMap1 map[uint64]ActivityConf_Index_NamedChapterMap indexAwardMap ActivityConf_Index_AwardMap indexAwardMap1 map[uint64]ActivityConf_Index_AwardMap - indexAwardMap2 map[ActivityConf_LeveledIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap - indexAwardMap3 map[ActivityConf_LeveledIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap + indexAwardMap2 map[ActivityConf_LevelIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap + indexAwardMap3 map[ActivityConf_LevelIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap } // Name returns the ActivityConf's message name. @@ -171,8 +171,8 @@ func (x *ActivityConf) processAfterLoad() error { x.indexNamedChapterMap1 = make(map[uint64]ActivityConf_Index_NamedChapterMap) x.indexAwardMap = make(ActivityConf_Index_AwardMap) x.indexAwardMap1 = make(map[uint64]ActivityConf_Index_AwardMap) - x.indexAwardMap2 = make(map[ActivityConf_LeveledIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap) - x.indexAwardMap3 = make(map[ActivityConf_LeveledIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap) + x.indexAwardMap2 = make(map[ActivityConf_LevelIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap) + x.indexAwardMap3 = make(map[ActivityConf_LevelIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap) for k1, v1 := range x.data.GetActivityMap() { _ = k1 { @@ -212,12 +212,12 @@ func (x *ActivityConf) processAfterLoad() error { x.indexAwardMap1[k1] = make(ActivityConf_Index_AwardMap) } x.indexAwardMap1[k1][key] = append(x.indexAwardMap1[k1][key], v4) - indexAwardMap2Keys := ActivityConf_LeveledIndex_Activity_ChapterKey{k1, k2} + indexAwardMap2Keys := ActivityConf_LevelIndex_Activity_ChapterKey{k1, k2} if x.indexAwardMap2[indexAwardMap2Keys] == nil { x.indexAwardMap2[indexAwardMap2Keys] = make(ActivityConf_Index_AwardMap) } x.indexAwardMap2[indexAwardMap2Keys][key] = append(x.indexAwardMap2[indexAwardMap2Keys][key], v4) - indexAwardMap3Keys := ActivityConf_LeveledIndex_protoconf_SectionKey{k1, k2, k3} + indexAwardMap3Keys := ActivityConf_LevelIndex_protoconf_SectionKey{k1, k2, k3} if x.indexAwardMap3[indexAwardMap3Keys] == nil { x.indexAwardMap3[indexAwardMap3Keys] = make(ActivityConf_Index_AwardMap) } @@ -506,7 +506,7 @@ func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf. // specified by (activityId, chapterId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap2(activityId uint64, chapterId uint32) ActivityConf_Index_AwardMap { - return x.indexAwardMap2[ActivityConf_LeveledIndex_Activity_ChapterKey{activityId, chapterId}] + return x.indexAwardMap2[ActivityConf_LevelIndex_Activity_ChapterKey{activityId, chapterId}] } // FindAward2 finds a slice of all values of the given key specified by (activityId, chapterId). @@ -528,7 +528,7 @@ func (x *ActivityConf) FindFirstAward2(activityId uint64, chapterId uint32, id u // specified by (activityId, chapterId, sectionId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap3(activityId uint64, chapterId uint32, sectionId uint32) ActivityConf_Index_AwardMap { - return x.indexAwardMap3[ActivityConf_LeveledIndex_protoconf_SectionKey{activityId, chapterId, sectionId}] + return x.indexAwardMap3[ActivityConf_LevelIndex_protoconf_SectionKey{activityId, chapterId, sectionId}] } // FindAward3 finds a slice of all values of the given key specified by (activityId, chapterId, sectionId). From 68493a71720cf04d04f212dd8e898671bd08052d Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 9 Dec 2025 16:15:20 +0800 Subject: [PATCH 08/15] feat(go): add level --- .../indexes/generator.go | 2 +- .../indexes/index.go | 26 +- .../indexes/orderedindex.go | 26 +- internal/index/descriptor.go | 24 +- .../protoconf/loader/hub.pc.go | 4 + .../protoconf/loader/item_conf.pc.go | 294 +++++++++++++++++- .../protoconf/loader/messager_container.pc.go | 6 + .../protoconf/loader/test_conf.pc.go | 37 +-- test/proto/item_conf.proto | 28 ++ test/testdata/conf/Fruit2Conf.json | 1 + 10 files changed, 371 insertions(+), 77 deletions(-) create mode 100644 test/testdata/conf/Fruit2Conf.json diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/generator.go b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go index 69d6d6d7..9b830856 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/generator.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go @@ -43,7 +43,7 @@ func (x *Generator) initLevelMessage() { x.mapFds = append(x.mapFds, fd) } if len(levelMessage.Indexes) != 0 || len(levelMessage.OrderedIndexes) != 0 { - x.maxDepth = levelMessage.Depth + x.maxDepth = levelMessage.MapDepth } } } diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go index 51f9027e..4e9de2bc 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -82,7 +82,7 @@ func (x *Generator) genIndexField() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { x.g.P(x.indexContainerName(index, 0), " ", x.indexMapType(index)) - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -106,7 +106,7 @@ func (x *Generator) genIndexLoader() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { x.g.P("x.", x.indexContainerName(index, 0), " = make(", x.indexMapType(index), ")") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -122,18 +122,22 @@ func (x *Generator) genIndexLoader() { parentDataName := "x.data" for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.genOneIndexLoader(index, levelMessage.Depth, parentDataName) + x.genOneIndexLoader(index, levelMessage.MapDepth, parentDataName) } - keyName := fmt.Sprintf("k%d", levelMessage.Depth) + keyName := fmt.Sprintf("k%d", levelMessage.MapDepth) valueName := fmt.Sprintf("v%d", levelMessage.Depth) if levelMessage.FD == nil { break } - if !levelMessage.NextLevel.NeedGen() { + if !levelMessage.NextLevel.NeedGenIndex() { break } - x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") - x.g.P("_ = ", keyName) + if levelMessage.FD.IsMap() { + x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") + x.g.P("_ = ", keyName) + } else { + x.g.P("for _ , ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") + } parentDataName = valueName defer x.g.P("}") } @@ -147,10 +151,8 @@ func (x *Generator) genOneIndexLoader(index *index.LevelIndex, depth int, parent field := index.ColFields[0] // just take the first field fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { - keyName := fmt.Sprintf("k%d", depth) valueName := fmt.Sprintf("v%d", depth) - x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, fieldName, " {") - x.g.P("_ = ", keyName) + x.g.P("for _ , ", valueName, " := range ", parentDataName, fieldName, " {") x.g.P("key := ", valueName) x.genIndexLoaderCommon(depth, index, parentDataName) x.g.P("}") @@ -240,7 +242,7 @@ func (x *Generator) genIndexSorter() { x.g.P("for _, item := range x.", x.indexContainerName(index, 0), " {") x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") x.g.P("}") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -297,7 +299,7 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index b830b115..ade44b7e 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -106,7 +106,7 @@ func (x *Generator) genOrderedIndexField() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { x.g.P(x.orderedIndexContainerName(index, 0), " *", x.orderedIndexMapType(index)) - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -130,7 +130,7 @@ func (x *Generator) genOrderedIndexLoader() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { x.g.P("x.", x.orderedIndexContainerName(index, 0), " = ", helper.TreeMapPackage.Ident(x.mapCtor(index)), "[", x.orderedIndexMapKeyType(index), ", []*", x.mapValueType(index), "]()") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -146,18 +146,22 @@ func (x *Generator) genOrderedIndexLoader() { parentDataName := "x.data" for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.genOneOrderedIndexLoader(index, levelMessage.Depth, parentDataName) + x.genOneOrderedIndexLoader(index, levelMessage.MapDepth, parentDataName) } - keyName := fmt.Sprintf("k%d", levelMessage.Depth) + keyName := fmt.Sprintf("k%d", levelMessage.MapDepth) valueName := fmt.Sprintf("v%d", levelMessage.Depth) if levelMessage.FD == nil { break } - if !levelMessage.NextLevel.NeedGen() { + if !levelMessage.NextLevel.NeedGenOrderedIndex() { break } - x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") - x.g.P("_ = ", keyName) + if levelMessage.FD.IsMap() { + x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") + x.g.P("_ = ", keyName) + } else { + x.g.P("for _ , ", valueName, " := range ", parentDataName, x.fieldGetter(levelMessage.FD), " {") + } parentDataName = valueName defer x.g.P("}") } @@ -171,10 +175,8 @@ func (x *Generator) genOneOrderedIndexLoader(index *index.LevelIndex, depth int, field := index.ColFields[0] // just take the first field fieldName, suffix := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { - keyName := fmt.Sprintf("k%d", depth) valueName := fmt.Sprintf("v%d", depth) - x.g.P("for ", keyName, ", ", valueName, " := range ", parentDataName, fieldName, " {") - x.g.P("_ = ", keyName) + x.g.P("for _ , ", valueName, " := range ", parentDataName, fieldName, " {") x.g.P("key := ", valueName, suffix) x.genOrderedIndexLoaderCommon(depth, index, parentDataName) x.g.P("}") @@ -270,7 +272,7 @@ func (x *Generator) genOrderedIndexSorter() { x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") x.g.P("return true") x.g.P("})") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -329,7 +331,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } diff --git a/internal/index/descriptor.go b/internal/index/descriptor.go index 13dea3c4..5fdcdd0d 100644 --- a/internal/index/descriptor.go +++ b/internal/index/descriptor.go @@ -54,14 +54,21 @@ type LevelMessage struct { Indexes, OrderedIndexes []*LevelIndex // depth of message hierarchy - Depth int + Depth, MapDepth int } -func (l *LevelMessage) NeedGen() bool { +func (l *LevelMessage) NeedGenIndex() bool { if l == nil { return false } - return len(l.Indexes) != 0 || len(l.OrderedIndexes) != 0 || l.NextLevel.NeedGen() + return len(l.Indexes) != 0 || l.NextLevel.NeedGenIndex() +} + +func (l *LevelMessage) NeedGenOrderedIndex() bool { + if l == nil { + return false + } + return len(l.OrderedIndexes) != 0 || l.NextLevel.NeedGenOrderedIndex() } type LevelIndex struct { @@ -80,18 +87,19 @@ func (l *LevelIndex) Name() string { return name } -func parseLevelMessage(md protoreflect.MessageDescriptor, depth int) *LevelMessage { +func parseLevelMessage(md protoreflect.MessageDescriptor, depth, mapDepth int) *LevelMessage { levelInfo := &LevelMessage{ - Depth: depth, + Depth: depth, + MapDepth: mapDepth, } for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() && fd.MapValue().Kind() == protoreflect.MessageKind { - levelInfo.NextLevel = parseLevelMessage(fd.MapValue().Message(), depth+1) + levelInfo.NextLevel = parseLevelMessage(fd.MapValue().Message(), depth+1, mapDepth+1) levelInfo.FD = fd return levelInfo } else if fd.IsList() && fd.Kind() == protoreflect.MessageKind { - levelInfo.NextLevel = parseLevelMessage(fd.Message(), depth+1) + levelInfo.NextLevel = parseLevelMessage(fd.Message(), depth+1, mapDepth) levelInfo.FD = fd return levelInfo } @@ -174,7 +182,7 @@ func parseCols(cols []string, prefix string, md protoreflect.MessageDescriptor, func ParseIndexDescriptor(md protoreflect.MessageDescriptor) *IndexDescriptor { descriptor := &IndexDescriptor{ - LevelMessage: parseLevelMessage(md, 1), + LevelMessage: parseLevelMessage(md, 1, 1), } indexes, orderedIndexes := ParseWSOptionIndex(md) // parse indexes into level message diff --git a/test/go-tableau-loader/protoconf/loader/hub.pc.go b/test/go-tableau-loader/protoconf/loader/hub.pc.go index 1d737393..67ece84a 100644 --- a/test/go-tableau-loader/protoconf/loader/hub.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hub.pc.go @@ -228,6 +228,10 @@ func (h *Hub) GetFruitConf() *FruitConf { return h.mc.Load().GetFruitConf() } +func (h *Hub) GetFruit2Conf() *Fruit2Conf { + return h.mc.Load().GetFruit2Conf() +} + func (h *Hub) GetPatchReplaceConf() *PatchReplaceConf { return h.mc.Load().GetPatchReplaceConf() } diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index 8a0066d2..be2eb9ee 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -188,8 +188,7 @@ func (x *ItemConf) processAfterLoad() error { } { // Index: Param@ItemInfo - for k2, v2 := range v1.GetParamList() { - _ = k2 + for _, v2 := range v1.GetParamList() { key := v2 x.indexItemInfoMap[key] = append(x.indexItemInfoMap[key], v1) } @@ -201,8 +200,7 @@ func (x *ItemConf) processAfterLoad() error { } { // Index: ExtType@ItemExtInfo - for k2, v2 := range v1.GetExtTypeList() { - _ = k2 + for _, v2 := range v1.GetExtTypeList() { key := v2 x.indexItemExtInfoMap[key] = append(x.indexItemExtInfoMap[key], v1) } @@ -228,8 +226,7 @@ func (x *ItemConf) processAfterLoad() error { } { // Index: PathName@ItemPathName - for k2, v2 := range v1.GetPath().GetNameList() { - _ = k2 + for _, v2 := range v1.GetPath().GetNameList() { key := v2 x.indexItemPathNameMap[key] = append(x.indexItemPathNameMap[key], v1) } @@ -273,8 +270,7 @@ func (x *ItemConf) processAfterLoad() error { _ = k1 { // OrderedIndex: ExtType@ExtType - for k2, v2 := range v1.GetExtTypeList() { - _ = k2 + for _, v2 := range v1.GetExtTypeList() { key := v2 value, _ := x.orderedIndexExtTypeMap.Get(key) x.orderedIndexExtTypeMap.Put(key, append(value, v1)) @@ -784,6 +780,285 @@ func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.Frui return nil } +// Index types. +// Index: CountryName +type Fruit2Conf_Index_CountryMap = map[string][]*protoconf.Fruit2Conf_Fruit_Country + +// Index: CountryItemAttrName +type Fruit2Conf_Index_AttrMap = map[string][]*protoconf.Fruit2Conf_Fruit_Country_Item_Attr + +// OrderedIndex types. +// OrderedIndex: CountryItemPrice +type Fruit2Conf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item] + +// Fruit2Conf is a wrapper around protobuf message: protoconf.Fruit2Conf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... +type Fruit2Conf struct { + UnimplementedMessager + data, originalData *protoconf.Fruit2Conf + indexCountryMap Fruit2Conf_Index_CountryMap + indexAttrMap Fruit2Conf_Index_AttrMap + indexAttrMap1 map[int32]Fruit2Conf_Index_AttrMap + orderedIndexItemMap *Fruit2Conf_OrderedIndex_ItemMap + orderedIndexItemMap1 map[int32]*Fruit2Conf_OrderedIndex_ItemMap +} + +// Name returns the Fruit2Conf's message name. +func (x *Fruit2Conf) Name() string { + return string((*protoconf.Fruit2Conf)(nil).ProtoReflect().Descriptor().Name()) +} + +// Data returns the Fruit2Conf's inner message data. +func (x *Fruit2Conf) Data() *protoconf.Fruit2Conf { + if x != nil { + return x.data + } + return nil +} + +// Load fills Fruit2Conf's inner message from file in the specified directory and format. +func (x *Fruit2Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.Fruit2Conf{} + err := load.LoadMessagerInDir(x.data, dir, format, opts) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.Fruit2Conf) + } + return x.processAfterLoad() +} + +// Store writes Fruit2Conf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *Fruit2Conf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the Fruit2Conf's inner message data. +func (x *Fruit2Conf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *Fruit2Conf) Messager() Messager { + return x +} + +// originalMessage returns the Fruit2Conf's original inner message. +func (x *Fruit2Conf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *Fruit2Conf) processAfterLoad() error { + // Index init. + x.indexCountryMap = make(Fruit2Conf_Index_CountryMap) + x.indexAttrMap = make(Fruit2Conf_Index_AttrMap) + x.indexAttrMap1 = make(map[int32]Fruit2Conf_Index_AttrMap) + for k1, v1 := range x.data.GetFruitMap() { + _ = k1 + for _, v2 := range v1.GetCountryList() { + { + // Index: CountryName + key := v2.GetName() + x.indexCountryMap[key] = append(x.indexCountryMap[key], v2) + } + for k2, v3 := range v2.GetItemMap() { + _ = k2 + for _, v4 := range v3.GetAttrList() { + { + // Index: CountryItemAttrName + key := v4.GetName() + x.indexAttrMap[key] = append(x.indexAttrMap[key], v4) + if x.indexAttrMap1[k1] == nil { + x.indexAttrMap1[k1] = make(Fruit2Conf_Index_AttrMap) + } + x.indexAttrMap1[k1][key] = append(x.indexAttrMap1[k1][key], v4) + } + } + } + } + } + // OrderedIndex init. + x.orderedIndexItemMap = treemap.New[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item]() + x.orderedIndexItemMap1 = make(map[int32]*Fruit2Conf_OrderedIndex_ItemMap) + for k1, v1 := range x.data.GetFruitMap() { + _ = k1 + for _, v2 := range v1.GetCountryList() { + for k2, v3 := range v2.GetItemMap() { + _ = k2 + { + // OrderedIndex: CountryItemPrice + key := v3.GetPrice() + value, _ := x.orderedIndexItemMap.Get(key) + x.orderedIndexItemMap.Put(key, append(value, v3)) + if x.orderedIndexItemMap1[k1] == nil { + x.orderedIndexItemMap1[k1] = treemap.New[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item]() + } + orderedIndexItemMap1Value, _ := x.orderedIndexItemMap1[k1].Get(key) + x.orderedIndexItemMap1[k1].Put(key, append(orderedIndexItemMap1Value, v3)) + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + orderedIndexItemMapSorter := func(item []*protoconf.Fruit2Conf_Fruit_Country_Item) func(i, j int) bool { + return func(i, j int) bool { + return item[i].GetId() < item[j].GetId() + } + } + x.orderedIndexItemMap.Range(func(key int32, item []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { + sort.Slice(item, orderedIndexItemMapSorter(item)) + return true + }) + for _, item := range x.orderedIndexItemMap1 { + item.Range(func(key int32, item1 []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { + sort.Slice(item1, orderedIndexItemMapSorter(item1)) + return true + }) + } + return nil +} + +// Get1 finds value in the 1-level map. It will return +// NotFound error if the key is not found. +func (x *Fruit2Conf) Get1(fruitType int32) (*protoconf.Fruit2Conf_Fruit, error) { + d := x.Data().GetFruitMap() + if val, ok := d[fruitType]; !ok { + return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) + } else { + return val, nil + } +} + +// Index: CountryName + +// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit2Conf_Fruit_Country) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindCountryMap() Fruit2Conf_Index_CountryMap { + return x.indexCountryMap +} + +// FindCountry finds a slice of all values of the given key. +func (x *Fruit2Conf) FindCountry(name string) []*protoconf.Fruit2Conf_Fruit_Country { + return x.indexCountryMap[name] +} + +// FindFirstCountry finds the first value of the given key, +// or nil if no value found. +func (x *Fruit2Conf) FindFirstCountry(name string) *protoconf.Fruit2Conf_Fruit_Country { + val := x.FindCountry(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// Index: CountryItemAttrName + +// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindAttrMap() Fruit2Conf_Index_AttrMap { + return x.indexAttrMap +} + +// FindAttr finds a slice of all values of the given key. +func (x *Fruit2Conf) FindAttr(name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + return x.indexAttrMap[name] +} + +// FindFirstAttr finds the first value of the given key, +// or nil if no value found. +func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + val := x.FindAttr(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindAttrMap1 finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map +// specified by (fruitType). +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindAttrMap1(fruitType int32) Fruit2Conf_Index_AttrMap { + return x.indexAttrMap1[fruitType] +} + +// FindAttr1 finds a slice of all values of the given key specified by (fruitType). +func (x *Fruit2Conf) FindAttr1(fruitType int32, name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + return x.FindAttrMap1(fruitType)[name] +} + +// FindFirstAttr1 finds the first value of the given key specified by (fruitType), +// or nil if no value found. +func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + val := x.FindAttr1(fruitType, name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// OrderedIndex: CountryItemPrice + +// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindItemMap() *Fruit2Conf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap +} + +// FindItem finds a slice of all values of the given key. +func (x *Fruit2Conf) FindItem(price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { + val, _ := x.orderedIndexItemMap.Get(price) + return val +} + +// FindFirstItem finds the first value of the given key, +// or nil if no value found. +func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { + val := x.FindItem(price) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindItemMap1 finds the index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap +// specified by (fruitType). +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindItemMap1(fruitType int32) *Fruit2Conf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap1[fruitType] +} + +// FindItem1 finds a slice of all values of the given key specified by (fruitType). +func (x *Fruit2Conf) FindItem1(fruitType int32, price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { + val, _ := x.FindItemMap1(fruitType).Get(price) + return val +} + +// FindFirstItem1 finds the first value of the given key specified by (fruitType), +// or nil if no value found. +func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { + val := x.FindItem1(fruitType, price) + if len(val) > 0 { + return val[0] + } + return nil +} + func init() { Register(func() Messager { return new(ItemConf) @@ -791,4 +1066,7 @@ func init() { Register(func() Messager { return new(FruitConf) }) + Register(func() Messager { + return new(Fruit2Conf) + }) } diff --git a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go index d9d00acc..31627cbe 100644 --- a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go +++ b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go @@ -17,6 +17,7 @@ type MessagerContainer struct { heroBaseConf *HeroBaseConf itemConf *ItemConf fruitConf *FruitConf + fruit2Conf *Fruit2Conf patchReplaceConf *PatchReplaceConf patchMergeConf *PatchMergeConf recursivePatchConf *RecursivePatchConf @@ -34,6 +35,7 @@ func newMessagerContainer(messagerMap MessagerMap) *MessagerContainer { heroBaseConf: GetMessager[*HeroBaseConf](messagerMap), itemConf: GetMessager[*ItemConf](messagerMap), fruitConf: GetMessager[*FruitConf](messagerMap), + fruit2Conf: GetMessager[*Fruit2Conf](messagerMap), patchReplaceConf: GetMessager[*PatchReplaceConf](messagerMap), patchMergeConf: GetMessager[*PatchMergeConf](messagerMap), recursivePatchConf: GetMessager[*RecursivePatchConf](messagerMap), @@ -74,6 +76,10 @@ func (mc *MessagerContainer) GetFruitConf() *FruitConf { return mc.fruitConf } +func (mc *MessagerContainer) GetFruit2Conf() *Fruit2Conf { + return mc.fruit2Conf +} + func (mc *MessagerContainer) GetPatchReplaceConf() *PatchReplaceConf { return mc.patchReplaceConf } diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index 2c1b62ea..5f2d67a5 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -36,11 +36,6 @@ type ActivityConf_LevelIndex_Activity_ChapterKey struct { ActivityId uint64 ChapterId uint32 } -type ActivityConf_LevelIndex_protoconf_SectionKey struct { - ActivityId uint64 - ChapterId uint32 - SectionId uint32 -} // Index types. // Index: ActivityName @@ -74,7 +69,6 @@ type ActivityConf struct { indexAwardMap ActivityConf_Index_AwardMap indexAwardMap1 map[uint64]ActivityConf_Index_AwardMap indexAwardMap2 map[ActivityConf_LevelIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap - indexAwardMap3 map[ActivityConf_LevelIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap } // Name returns the ActivityConf's message name. @@ -172,7 +166,6 @@ func (x *ActivityConf) processAfterLoad() error { x.indexAwardMap = make(ActivityConf_Index_AwardMap) x.indexAwardMap1 = make(map[uint64]ActivityConf_Index_AwardMap) x.indexAwardMap2 = make(map[ActivityConf_LevelIndex_Activity_ChapterKey]ActivityConf_Index_AwardMap) - x.indexAwardMap3 = make(map[ActivityConf_LevelIndex_protoconf_SectionKey]ActivityConf_Index_AwardMap) for k1, v1 := range x.data.GetActivityMap() { _ = k1 { @@ -202,8 +195,7 @@ func (x *ActivityConf) processAfterLoad() error { } for k3, v3 := range v2.GetSectionMap() { _ = k3 - for k4, v4 := range v3.GetSectionItemList() { - _ = k4 + for _, v4 := range v3.GetSectionItemList() { { // Index: SectionItemID@Award key := v4.GetId() @@ -217,11 +209,6 @@ func (x *ActivityConf) processAfterLoad() error { x.indexAwardMap2[indexAwardMap2Keys] = make(ActivityConf_Index_AwardMap) } x.indexAwardMap2[indexAwardMap2Keys][key] = append(x.indexAwardMap2[indexAwardMap2Keys][key], v4) - indexAwardMap3Keys := ActivityConf_LevelIndex_protoconf_SectionKey{k1, k2, k3} - if x.indexAwardMap3[indexAwardMap3Keys] == nil { - x.indexAwardMap3[indexAwardMap3Keys] = make(ActivityConf_Index_AwardMap) - } - x.indexAwardMap3[indexAwardMap3Keys][key] = append(x.indexAwardMap3[indexAwardMap3Keys][key], v4) } } } @@ -524,28 +511,6 @@ func (x *ActivityConf) FindFirstAward2(activityId uint64, chapterId uint32, id u return nil } -// FindAwardMap3 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map -// specified by (activityId, chapterId, sectionId). -// One key may correspond to multiple values, which are contained by a slice. -func (x *ActivityConf) FindAwardMap3(activityId uint64, chapterId uint32, sectionId uint32) ActivityConf_Index_AwardMap { - return x.indexAwardMap3[ActivityConf_LevelIndex_protoconf_SectionKey{activityId, chapterId, sectionId}] -} - -// FindAward3 finds a slice of all values of the given key specified by (activityId, chapterId, sectionId). -func (x *ActivityConf) FindAward3(activityId uint64, chapterId uint32, sectionId uint32, id uint32) []*protoconf.Section_SectionItem { - return x.FindAwardMap3(activityId, chapterId, sectionId)[id] -} - -// FindFirstAward3 finds the first value of the given key specified by (activityId, chapterId, sectionId), -// or nil if no value found. -func (x *ActivityConf) FindFirstAward3(activityId uint64, chapterId uint32, sectionId uint32, id uint32) *protoconf.Section_SectionItem { - val := x.FindAward3(activityId, chapterId, sectionId, id) - if len(val) > 0 { - return val[0] - } - return nil -} - // ChapterConf is a wrapper around protobuf message: protoconf.ChapterConf. // // It is designed for three goals: diff --git a/test/proto/item_conf.proto b/test/proto/item_conf.proto index 3926834d..fef8d5cd 100644 --- a/test/proto/item_conf.proto +++ b/test/proto/item_conf.proto @@ -94,4 +94,32 @@ message FruitConf { int32 price = 2 [(tableau.field) = { name: "Price" }]; } } +} + +message Fruit2Conf { + option (tableau.worksheet) = { + name: "Fruit2Conf" + index: "CountryName" + index: "CountryItemAttrName" + ordered_index: "CountryItemPrice" + }; + + map fruit_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; + message Fruit { + protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; + repeated Country country_list = 2 [(tableau.field) = { name: "Country" layout: LAYOUT_HORIZONTAL }]; + message Country { + string name = 1 [(tableau.field) = { name: "Name" }]; + map item_map = 2 [(tableau.field) = { name: "Item" key: "ID" layout: LAYOUT_HORIZONTAL }]; + message Item { + int32 id = 1 [(tableau.field) = { name: "ID" }]; + int32 price = 2 [(tableau.field) = { name: "Price" }]; + repeated Attr attr_list = 3 [(tableau.field) = { name: "Attr" layout: LAYOUT_HORIZONTAL }]; + message Attr { + string name = 1 [(tableau.field) = { name: "Name" }]; + int32 value = 2 [(tableau.field) = { name: "Value" }]; + } + } + } + } } \ No newline at end of file diff --git a/test/testdata/conf/Fruit2Conf.json b/test/testdata/conf/Fruit2Conf.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/test/testdata/conf/Fruit2Conf.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 6c6f281e1ed70be30cd2c1002c1d3edffc332ee1 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 9 Dec 2025 17:30:15 +0800 Subject: [PATCH 09/15] feat(cpp): add MapDepth --- .../indexes/generator.go | 2 +- .../indexes/index.go | 37 ++-- .../indexes/ordered_index.go | 37 ++-- .../cpp-tableau-loader/src/protoconf/hub.pc.h | 5 + .../src/protoconf/hub_shard0.pc.cc | 7 + .../src/protoconf/item_conf.pc.cc | 193 +++++++++++++++++- .../src/protoconf/item_conf.pc.h | 84 ++++++++ .../src/protoconf/test_conf.pc.cc | 43 +--- .../src/protoconf/test_conf.pc.h | 26 --- 9 files changed, 336 insertions(+), 98 deletions(-) diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go index 93f25816..e4163b5e 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go @@ -40,7 +40,7 @@ func (x *Generator) initLevelMessage() { x.mapFds = append(x.mapFds, fd) } if len(levelMessage.Indexes) != 0 || len(levelMessage.OrderedIndexes) != 0 { - x.maxDepth = levelMessage.Depth + x.maxDepth = levelMessage.MapDepth } } } diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go index 410fff8b..b2034a28 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go @@ -103,7 +103,7 @@ func (x *Generator) genHppIndexFinders() { x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", keys.GenGetParams(), ") const;") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -121,7 +121,7 @@ func (x *Generator) genHppIndexFinders() { x.g.P(" private:") x.g.P(helper.Indent(1), mapType, " ", x.indexContainerName(index, 0), ";") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -145,7 +145,7 @@ func (x *Generator) genIndexLoader() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { x.g.P(helper.Indent(1), x.indexContainerName(index, 0), ".clear();") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -156,49 +156,50 @@ func (x *Generator) genIndexLoader() { parentDataName := "data_" for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.Indexes { - x.genOneCppIndexLoader(levelMessage.Depth, index, parentDataName) + x.genOneCppIndexLoader(levelMessage.MapDepth, levelMessage.Depth, index, parentDataName) } itemName := fmt.Sprintf("item%d", levelMessage.Depth) if levelMessage.FD == nil { break } - if !levelMessage.NextLevel.NeedGen() { + if !levelMessage.NextLevel.NeedGenIndex() { break } x.g.P(helper.Indent(levelMessage.Depth), "for (auto&& ", itemName, " : ", parentDataName, x.fieldGetter(levelMessage.FD), ") {") parentDataName = itemName if levelMessage.FD.IsMap() { + x.g.P(helper.Indent(levelMessage.Depth+1), "auto k", levelMessage.MapDepth, " = ", itemName, ".first;") parentDataName = itemName + ".second" } defer x.g.P(helper.Indent(levelMessage.Depth), "}") } } -func (x *Generator) genOneCppIndexLoader(depth int, index *index.LevelIndex, parentDataName string) { - x.g.P(helper.Indent(depth), "{") - x.g.P(helper.Indent(depth+1), "// Index: ", index.Index) +func (x *Generator) genOneCppIndexLoader(depth int, ident int, index *index.LevelIndex, parentDataName string) { + x.g.P(helper.Indent(ident), "{") + x.g.P(helper.Indent(ident+1), "// Index: ", index.Index) if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take the first field fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { itemName := fmt.Sprintf("item%d", depth) - x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") + x.g.P(helper.Indent(ident+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") key := itemName if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } - x.genLoader(depth, depth+2, index, key, parentDataName) - x.g.P(helper.Indent(depth+1), "}") + x.genLoader(depth, ident+2, index, key, parentDataName) + x.g.P(helper.Indent(ident+1), "}") } else { key := parentDataName + fieldName - x.genLoader(depth, depth+1, index, key, parentDataName) + x.genLoader(depth, ident+1, index, key, parentDataName) } } else { // multi-column index - x.generateOneCppMulticolumnIndex(depth, depth, index, parentDataName, nil) + x.generateOneCppMulticolumnIndex(depth, ident, index, parentDataName, nil) } - x.g.P(helper.Indent(depth), "}") + x.g.P(helper.Indent(ident), "}") } func (x *Generator) generateOneCppMulticolumnIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { @@ -235,11 +236,11 @@ func (x *Generator) genLoader(depth, ident int, index *index.LevelIndex, key, pa break } if i == 1 { - x.g.P(helper.Indent(ident), x.indexContainerName(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.indexContainerName(index, i), "[k1][", key, "].push_back(&", parentDataName, ");") } else { var fields []string for j := 1; j <= i; j++ { - fields = append(fields, fmt.Sprintf("item%d.first", j)) + fields = append(fields, fmt.Sprintf("k%d", j)) } x.g.P(helper.Indent(ident), x.indexContainerName(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") } @@ -271,7 +272,7 @@ func (x *Generator) genIndexSorter() { x.g.P(helper.Indent(1), "for (auto&& item : ", indexContainerName, ") {") x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(1), "}") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -326,7 +327,7 @@ func (x *Generator) genCppIndexFinders() { x.g.P("}") x.g.P() - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go index e8ce03d8..66e89e51 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go @@ -93,7 +93,7 @@ func (x *Generator) genHppOrderedIndexFinders() { x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") x.g.P(helper.Indent(1), "// Finds the first value of the given key(s).") x.g.P(helper.Indent(1), "const ", helper.ParseCppClassType(index.MD), "* FindFirst", index.Name(), "(", keys.GenGetParams(), ") const;") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -111,7 +111,7 @@ func (x *Generator) genHppOrderedIndexFinders() { x.g.P(" private:") x.g.P(helper.Indent(1), mapType, " ", x.orderedIndexContainerName(index, 0), ";") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -135,7 +135,7 @@ func (x *Generator) genOrderedIndexLoader() { for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { x.g.P(helper.Indent(1), x.orderedIndexContainerName(index, 0), ".clear();") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -146,49 +146,50 @@ func (x *Generator) genOrderedIndexLoader() { parentDataName := "data_" for levelMessage := x.descriptor.LevelMessage; levelMessage != nil; levelMessage = levelMessage.NextLevel { for _, index := range levelMessage.OrderedIndexes { - x.genOneCppOrderedIndexLoader(levelMessage.Depth, index, parentDataName) + x.genOneCppOrderedIndexLoader(levelMessage.MapDepth, levelMessage.Depth, index, parentDataName) } itemName := fmt.Sprintf("item%d", levelMessage.Depth) if levelMessage.FD == nil { break } - if !levelMessage.NextLevel.NeedGen() { + if !levelMessage.NextLevel.NeedGenOrderedIndex() { break } x.g.P(helper.Indent(levelMessage.Depth), "for (auto&& ", itemName, " : ", parentDataName, x.fieldGetter(levelMessage.FD), ") {") parentDataName = itemName if levelMessage.FD.IsMap() { + x.g.P(helper.Indent(levelMessage.Depth+1), "auto k", levelMessage.MapDepth, " = ", itemName, ".first;") parentDataName = itemName + ".second" } defer x.g.P(helper.Indent(levelMessage.Depth), "}") } } -func (x *Generator) genOneCppOrderedIndexLoader(depth int, index *index.LevelIndex, parentDataName string) { - x.g.P(helper.Indent(depth), "{") - x.g.P(helper.Indent(depth+1), "// OrderedIndex: ", index.Index) +func (x *Generator) genOneCppOrderedIndexLoader(depth int, ident int, index *index.LevelIndex, parentDataName string) { + x.g.P(helper.Indent(ident), "{") + x.g.P(helper.Indent(ident+1), "// OrderedIndex: ", index.Index) if len(index.ColFields) == 1 { // single-column index field := index.ColFields[0] // just take the first field fieldName, suffix := x.parseKeyFieldNameAndSuffix(field) if field.FD.IsList() { itemName := fmt.Sprintf("item%d", depth) - x.g.P(helper.Indent(depth+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") + x.g.P(helper.Indent(ident+1), "for (auto&& ", itemName, " : ", parentDataName, fieldName, ") {") key := itemName + suffix if field.FD.Enum() != nil { key = "static_cast<" + helper.ParseCppType(field.FD) + ">(" + key + ")" } - x.genOrderedLoader(depth, depth+2, index, key, parentDataName) - x.g.P(helper.Indent(depth+1), "}") + x.genOrderedLoader(depth, ident+2, index, key, parentDataName) + x.g.P(helper.Indent(ident+1), "}") } else { key := parentDataName + fieldName + suffix - x.genOrderedLoader(depth, depth+1, index, key, parentDataName) + x.genOrderedLoader(depth, ident+1, index, key, parentDataName) } } else { // multi-column index - x.generateOneCppMulticolumnOrderedIndex(depth, depth, index, parentDataName, nil) + x.generateOneCppMulticolumnOrderedIndex(depth, ident, index, parentDataName, nil) } - x.g.P(helper.Indent(depth), "}") + x.g.P(helper.Indent(ident), "}") } func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { @@ -225,11 +226,11 @@ func (x *Generator) genOrderedLoader(depth, ident int, index *index.LevelIndex, break } if i == 1 { - x.g.P(helper.Indent(ident), x.orderedIndexContainerName(index, i), "[item1.first][", key, "].push_back(&", parentDataName, ");") + x.g.P(helper.Indent(ident), x.orderedIndexContainerName(index, i), "[k1][", key, "].push_back(&", parentDataName, ");") } else { var fields []string for j := 1; j <= i; j++ { - fields = append(fields, fmt.Sprintf("item%d.first", j)) + fields = append(fields, fmt.Sprintf("k%d", j)) } x.g.P(helper.Indent(ident), x.orderedIndexContainerName(index, i), "[{", strings.Join(fields, ", "), "}][", key, "].push_back(&", parentDataName, ");") } @@ -261,7 +262,7 @@ func (x *Generator) genOrderedIndexSorter() { x.g.P(helper.Indent(1), "for (auto&& item : ", indexContainerName, ") {") x.g.P(helper.Indent(2), "std::sort(item.second.begin(), item.second.end(), ", indexContainerName, "sorter);") x.g.P(helper.Indent(1), "}") - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } @@ -316,7 +317,7 @@ func (x *Generator) genCppOrderedIndexFinders() { x.g.P("}") x.g.P() - for i := 1; i <= levelMessage.Depth-2; i++ { + for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } diff --git a/test/cpp-tableau-loader/src/protoconf/hub.pc.h b/test/cpp-tableau-loader/src/protoconf/hub.pc.h index 63e9a9f1..73d18977 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/hub.pc.h @@ -126,6 +126,10 @@ class HeroConf; template <> const std::shared_ptr Hub::Get() const; +class Fruit2Conf; +template <> +const std::shared_ptr Hub::Get() const; + class FruitConf; template <> const std::shared_ptr Hub::Get() const; @@ -178,6 +182,7 @@ class MessagerContainer { std::time_t last_loaded_time_; std::shared_ptr hero_base_conf_; std::shared_ptr hero_conf_; + std::shared_ptr fruit_2_conf_; std::shared_ptr fruit_conf_; std::shared_ptr item_conf_; std::shared_ptr patch_merge_conf_; diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc index c05d426f..50c66ca3 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc @@ -19,6 +19,11 @@ const std::shared_ptr Hub::Get() const { return GetMessagerContainerWithProvider()->hero_conf_; } +template <> +const std::shared_ptr Hub::Get() const { + return GetMessagerContainerWithProvider()->fruit_2_conf_; +} + template <> const std::shared_ptr Hub::Get() const { return GetMessagerContainerWithProvider()->fruit_conf_; @@ -32,6 +37,7 @@ const std::shared_ptr Hub::Get() const { void MessagerContainer::InitShard0() { hero_base_conf_ = std::dynamic_pointer_cast(GetMessager(HeroBaseConf::Name())); hero_conf_ = std::dynamic_pointer_cast(GetMessager(HeroConf::Name())); + fruit_2_conf_ = std::dynamic_pointer_cast(GetMessager(Fruit2Conf::Name())); fruit_conf_ = std::dynamic_pointer_cast(GetMessager(FruitConf::Name())); item_conf_ = std::dynamic_pointer_cast(GetMessager(ItemConf::Name())); } @@ -39,6 +45,7 @@ void MessagerContainer::InitShard0() { void Registry::InitShard0() { Register(); Register(); + Register(); Register(); Register(); } diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index b4902cc2..74f3c6ca 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -38,6 +38,7 @@ bool ItemConf::ProcessAfterLoad() { index_item_path_friend_id_map_.clear(); index_use_effect_type_map_.clear(); for (auto&& item1 : data_.item_map()) { + auto k1 = item1.first; { // Index: Type index_item_map_[item1.second.type()].push_back(&item1.second); @@ -114,6 +115,7 @@ bool ItemConf::ProcessAfterLoad() { ordered_index_ext_type_map_.clear(); ordered_index_param_ext_type_map_.clear(); for (auto&& item1 : data_.item_map()) { + auto k1 = item1.first; { // OrderedIndex: ExtType@ExtType for (auto&& item2 : item1.second.ext_type_list()) { @@ -396,11 +398,13 @@ bool FruitConf::ProcessAfterLoad() { ordered_index_item_map_.clear(); ordered_index_item_map1_.clear(); for (auto&& item1 : data_.fruit_map()) { + auto k1 = item1.first; for (auto&& item2 : item1.second.item_map()) { + auto k2 = item2.first; { // OrderedIndex: Price ordered_index_item_map_[item2.second.price()].push_back(&item2.second); - ordered_index_item_map1_[item1.first][item2.second.price()].push_back(&item2.second); + ordered_index_item_map1_[k1][item2.second.price()].push_back(&item2.second); } } } @@ -487,4 +491,191 @@ const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t fruit_ return conf->front(); } +const std::string Fruit2Conf::kProtoName = protoconf::Fruit2Conf::GetDescriptor()->name(); + +bool Fruit2Conf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessagerInDir(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool Fruit2Conf::ProcessAfterLoad() { + // Index init. + index_country_map_.clear(); + index_attr_map_.clear(); + index_attr_map1_.clear(); + for (auto&& item1 : data_.fruit_map()) { + auto k1 = item1.first; + for (auto&& item2 : item1.second.country_list()) { + { + // Index: CountryName + index_country_map_[item2.name()].push_back(&item2); + } + for (auto&& item3 : item2.item_map()) { + auto k2 = item3.first; + for (auto&& item4 : item3.second.attr_list()) { + { + // Index: CountryItemAttrName + index_attr_map_[item4.name()].push_back(&item4); + index_attr_map1_[k1][item4.name()].push_back(&item4); + } + } + } + } + } + // OrderedIndex init. + ordered_index_item_map_.clear(); + ordered_index_item_map1_.clear(); + for (auto&& item1 : data_.fruit_map()) { + auto k1 = item1.first; + for (auto&& item2 : item1.second.country_list()) { + for (auto&& item3 : item2.item_map()) { + auto k2 = item3.first; + { + // OrderedIndex: CountryItemPrice + ordered_index_item_map_[item3.second.price()].push_back(&item3.second); + ordered_index_item_map1_[k1][item3.second.price()].push_back(&item3.second); + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + auto ordered_index_item_map_sorter = [](const protoconf::Fruit2Conf::Fruit::Country::Item* a, + const protoconf::Fruit2Conf::Fruit::Country::Item* b) { + return a->id() < b->id(); + }; + for (auto&& item : ordered_index_item_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); + } + for (auto&& item : ordered_index_item_map1_) { + for (auto&& item1 : item.second) { + std::sort(item1.second.begin(), item1.second.end(), ordered_index_item_map_sorter); + } + } + return true; +} + +const protoconf::Fruit2Conf::Fruit* Fruit2Conf::Get(int32_t fruit_type) const { + auto iter = data_.fruit_map().find(fruit_type); + if (iter == data_.fruit_map().end()) { + return nullptr; + } + return &iter->second; +} + +// Index: CountryName +const Fruit2Conf::Index_CountryMap& Fruit2Conf::FindCountryMap() const { return index_country_map_ ;} + +const Fruit2Conf::Index_CountryVector* Fruit2Conf::FindCountry(const std::string& name) const { + auto iter = index_country_map_.find(name); + if (iter == index_country_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country* Fruit2Conf::FindFirstCountry(const std::string& name) const { + auto conf = FindCountry(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// Index: CountryItemAttrName +const Fruit2Conf::Index_AttrMap& Fruit2Conf::FindAttrMap() const { return index_attr_map_ ;} + +const Fruit2Conf::Index_AttrVector* Fruit2Conf::FindAttr(const std::string& name) const { + auto iter = index_attr_map_.find(name); + if (iter == index_attr_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* Fruit2Conf::FindFirstAttr(const std::string& name) const { + auto conf = FindAttr(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const Fruit2Conf::Index_AttrMap* Fruit2Conf::FindAttrMap(int32_t fruit_type) const { + auto iter = index_attr_map1_.find(fruit_type); + if (iter == index_attr_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const Fruit2Conf::Index_AttrVector* Fruit2Conf::FindAttr(int32_t fruit_type, const std::string& name) const { + auto map = FindAttrMap(fruit_type); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(name); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* Fruit2Conf::FindFirstAttr(int32_t fruit_type, const std::string& name) const { + auto conf = FindAttr(fruit_type, name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// OrderedIndex: CountryItemPrice +const Fruit2Conf::OrderedIndex_ItemMap& Fruit2Conf::FindItemMap() const { return ordered_index_item_map_ ;} + +const Fruit2Conf::OrderedIndex_ItemVector* Fruit2Conf::FindItem(int32_t price) const { + auto iter = ordered_index_item_map_.find(price); + if (iter == ordered_index_item_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int32_t price) const { + auto conf = FindItem(price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const Fruit2Conf::OrderedIndex_ItemMap* Fruit2Conf::FindItemMap(int32_t fruit_type) const { + auto iter = ordered_index_item_map1_.find(fruit_type); + if (iter == ordered_index_item_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const Fruit2Conf::OrderedIndex_ItemVector* Fruit2Conf::FindItem(int32_t fruit_type, int32_t price) const { + auto map = FindItemMap(fruit_type); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(price); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int32_t fruit_type, int32_t price) const { + auto conf = FindItem(fruit_type, price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index 24c50e94..47a003f3 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -310,10 +310,94 @@ class FruitConf : public Messager { std::unordered_map ordered_index_item_map1_; }; +class Fruit2Conf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; + const protoconf::Fruit2Conf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + public: + const protoconf::Fruit2Conf::Fruit* Get(int32_t fruit_type) const; + + private: + static const std::string kProtoName; + protoconf::Fruit2Conf data_; + + // Index accessers. + // Index: CountryName + public: + using Index_CountryVector = std::vector; + using Index_CountryMap = std::unordered_map; + // Finds the index (CountryName) to value (Index_CountryVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_CountryMap& FindCountryMap() const; + // Finds a vector of all values of the given key(s). + const Index_CountryVector* FindCountry(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit2Conf::Fruit::Country* FindFirstCountry(const std::string& name) const; + + private: + Index_CountryMap index_country_map_; + + // Index: CountryItemAttrName + public: + using Index_AttrVector = std::vector; + using Index_AttrMap = std::unordered_map; + // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_AttrMap& FindAttrMap() const; + // Finds a vector of all values of the given key(s). + const Index_AttrVector* FindAttr(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; + // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map + // specified by (fruit_type). + // One key may correspond to multiple values, which are contained by a vector. + const Index_AttrMap* FindAttrMap(int32_t fruit_type) const; + // Finds a vector of all values of the given key(s) specified by (fruit_type). + const Index_AttrVector* FindAttr(int32_t fruit_type, const std::string& name) const; + // Finds the first value of the given key(s) specified by (fruit_type). + const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(int32_t fruit_type, const std::string& name) const; + + private: + Index_AttrMap index_attr_map_; + std::unordered_map index_attr_map1_; + + // OrderedIndex accessers. + // OrderedIndex: CountryItemPrice + public: + using OrderedIndex_ItemVector = std::vector; + using OrderedIndex_ItemMap = std::map; + // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap& FindItemMap() const; + // Finds a vector of all values of the given key(s). + const OrderedIndex_ItemVector* FindItem(int32_t price) const; + // Finds the first value of the given key(s). + const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; + // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map + // specified by (fruit_type). + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; + // Finds a vector of all values of the given key(s) specified by (fruit_type). + const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; + // Finds the first value of the given key(s) specified by (fruit_type). + const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; + + private: + OrderedIndex_ItemMap ordered_index_item_map_; + std::unordered_map ordered_index_item_map1_; +}; + } // namespace tableau namespace protoconf { // Here are some type aliases for easy use. using ItemConfMgr = tableau::ItemConf; using FruitConfMgr = tableau::FruitConf; +using Fruit2ConfMgr = tableau::Fruit2Conf; } // namespace protoconf diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc index dca5989f..bcd76c15 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.cc @@ -47,31 +47,32 @@ bool ActivityConf::ProcessAfterLoad() { index_award_map_.clear(); index_award_map1_.clear(); index_award_map2_.clear(); - index_award_map3_.clear(); for (auto&& item1 : data_.activity_map()) { + auto k1 = item1.first; { // Index: ActivityName index_activity_map_[item1.second.activity_name()].push_back(&item1.second); } for (auto&& item2 : item1.second.chapter_map()) { + auto k2 = item2.first; { // Index: ChapterID index_chapter_map_[item2.second.chapter_id()].push_back(&item2.second); - index_chapter_map1_[item1.first][item2.second.chapter_id()].push_back(&item2.second); + index_chapter_map1_[k1][item2.second.chapter_id()].push_back(&item2.second); } { // Index: ChapterName@NamedChapter index_named_chapter_map_[item2.second.chapter_name()].push_back(&item2.second); - index_named_chapter_map1_[item1.first][item2.second.chapter_name()].push_back(&item2.second); + index_named_chapter_map1_[k1][item2.second.chapter_name()].push_back(&item2.second); } for (auto&& item3 : item2.second.section_map()) { + auto k3 = item3.first; for (auto&& item4 : item3.second.section_item_list()) { { // Index: SectionItemID@Award index_award_map_[item4.id()].push_back(&item4); - index_award_map1_[item1.first][item4.id()].push_back(&item4); - index_award_map2_[{item1.first, item2.first}][item4.id()].push_back(&item4); - index_award_map3_[{item1.first, item2.first, item3.first}][item4.id()].push_back(&item4); + index_award_map1_[k1][item4.id()].push_back(&item4); + index_award_map2_[{k1, k2}][item4.id()].push_back(&item4); } } } @@ -365,34 +366,6 @@ const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint64_t act return conf->front(); } -const ActivityConf::Index_AwardMap* ActivityConf::FindAwardMap(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id) const { - auto iter = index_award_map3_.find({activity_id, chapter_id, section_id}); - if (iter == index_award_map3_.end()) { - return nullptr; - } - return &iter->second; -} - -const ActivityConf::Index_AwardVector* ActivityConf::FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const { - auto map = FindAwardMap(activity_id, chapter_id, section_id); - if (map == nullptr) { - return nullptr; - } - auto iter = map->find(id); - if (iter == map->end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Section::SectionItem* ActivityConf::FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const { - auto conf = FindAward(activity_id, chapter_id, section_id, id); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - const std::string ChapterConf::kProtoName = protoconf::ChapterConf::GetDescriptor()->name(); bool ChapterConf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { @@ -455,6 +428,7 @@ bool TaskConf::ProcessAfterLoad() { // Index init. index_task_map_.clear(); for (auto&& item1 : data_.task_map()) { + auto k1 = item1.first; { // Index: ActivityID index_task_map_[item1.second.activity_id()].push_back(&item1.second); @@ -477,6 +451,7 @@ bool TaskConf::ProcessAfterLoad() { ordered_index_sorted_task_expiry_map_.clear(); ordered_index_activity_expiry_map_.clear(); for (auto&& item1 : data_.task_map()) { + auto k1 = item1.first; { // OrderedIndex: Goal@OrderedTask ordered_index_ordered_task_map_[item1.second.goal()].push_back(&item1.second); diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 46edb6ab..82847c28 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -71,23 +71,6 @@ class ActivityConf : public Messager { return util::SugaredHashCombine(key.activity_id, key.chapter_id); } }; - struct LevelIndex_protoconf_SectionKey { - uint64_t activity_id; - uint32_t chapter_id; - uint32_t section_id; -#if __cplusplus >= 202002L - bool operator==(const LevelIndex_protoconf_SectionKey& other) const = default; -#else - bool operator==(const LevelIndex_protoconf_SectionKey& other) const { - return std::tie(activity_id, chapter_id, section_id) == std::tie(other.activity_id, other.chapter_id, other.section_id); - } -#endif - }; - struct LevelIndex_protoconf_SectionKeyHasher { - std::size_t operator()(const LevelIndex_protoconf_SectionKey& key) const { - return util::SugaredHashCombine(key.activity_id, key.chapter_id, key.section_id); - } - }; // Index accessers. // Index: ActivityName @@ -180,20 +163,11 @@ class ActivityConf : public Messager { const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const; // Finds the first value of the given key(s) specified by (activity_id, chapter_id). const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const; - // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map - // specified by (activity_id, chapter_id, section_id). - // One key may correspond to multiple values, which are contained by a vector. - const Index_AwardMap* FindAwardMap(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id) const; - // Finds a vector of all values of the given key(s) specified by (activity_id, chapter_id, section_id). - const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const; - // Finds the first value of the given key(s) specified by (activity_id, chapter_id, section_id). - const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t section_id, uint32_t id) const; private: Index_AwardMap index_award_map_; std::unordered_map index_award_map1_; std::unordered_map index_award_map2_; - std::unordered_map index_award_map3_; }; class ChapterConf : public Messager { From 5d1d6cc44e898ee67606d8fef0c1bc1bbc1bc7fe Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 9 Dec 2025 21:18:42 +0800 Subject: [PATCH 10/15] feat: cr --- .../indexes/index.go | 27 +++--- .../indexes/orderedindex.go | 27 +++--- .../protoconf/loader/hero_conf.pc.go | 9 +- .../protoconf/loader/item_conf.pc.go | 83 ++++++++++--------- .../protoconf/loader/test_conf.pc.go | 82 +++++++++--------- 5 files changed, 119 insertions(+), 109 deletions(-) diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go index 4e9de2bc..c38fc7d5 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -225,30 +225,30 @@ func (x *Generator) genIndexSorter() { if len(index.SortedColFields) != 0 { x.g.P("// Index(sort): ", index.Index) indexContainerName := x.indexContainerName(index, 0) - x.g.P(indexContainerName, "Sorter := func(item []*", x.mapValueType(index), ") func(i, j int) bool {") + x.g.P(indexContainerName, "Sorter := func(itemList []*", x.mapValueType(index), ") func(i, j int) bool {") x.g.P("return func(i, j int) bool {") for i, field := range index.SortedColFields { fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if i == len(index.SortedColFields)-1 { - x.g.P("return item[i]", fieldName, " < item[j]", fieldName) + x.g.P("return itemList[i]", fieldName, " < itemList[j]", fieldName) } else { - x.g.P("if item[i]", fieldName, " != item[j]", fieldName, " {") - x.g.P("return item[i]", fieldName, " < item[j]", fieldName) + x.g.P("if itemList[i]", fieldName, " != itemList[j]", fieldName, " {") + x.g.P("return itemList[i]", fieldName, " < itemList[j]", fieldName) x.g.P("}") } } x.g.P("}") x.g.P("}") - x.g.P("for _, item := range x.", x.indexContainerName(index, 0), " {") - x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") + x.g.P("for _, itemList := range x.", x.indexContainerName(index, 0), " {") + x.g.P(helper.SortPackage.Ident("Slice"), "(itemList, ", indexContainerName, "Sorter(itemList))") x.g.P("}") for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } - x.g.P("for _, item := range x.", x.indexContainerName(index, i), " {") - x.g.P("for _, item1 := range item {") - x.g.P(helper.SortPackage.Ident("Slice"), "(item1, ", indexContainerName, "Sorter(item1))") + x.g.P("for _, itemMap := range x.", x.indexContainerName(index, i), " {") + x.g.P("for _, itemList := range itemMap {") + x.g.P(helper.SortPackage.Ident("Slice"), "(itemList, ", indexContainerName, "Sorter(itemList))") x.g.P("}") x.g.P("}") } @@ -308,7 +308,7 @@ func (x *Generator) genIndexFinders() { partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() - x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") map") + x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") ", i, "-level map") x.g.P("// specified by (", partArgs, ").") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") ", x.indexMapType(index), " {") @@ -321,7 +321,8 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key specified by (", partArgs, ").") + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", i, "-level map") + x.g.P("// specified by (", partArgs, ").") x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { x.g.P("return x.Find", index.Name(), "Map", i, "(", partArgs, ")[", args, "]") @@ -331,8 +332,8 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key specified by (", partArgs, "),") - x.g.P("// or nil if no value found.") + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", i, "-level map") + x.g.P("// specified by (", partArgs, "), or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") x.g.P("if len(val) > 0 {") diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index ade44b7e..12e6a8e7 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -254,31 +254,31 @@ func (x *Generator) genOrderedIndexSorter() { if len(index.SortedColFields) != 0 { x.g.P("// OrderedIndex(sort): ", index.Index) indexContainerName := x.orderedIndexContainerName(index, 0) - x.g.P(indexContainerName, "Sorter := func(item []*", x.mapValueType(index), ") func(i, j int) bool {") + x.g.P(indexContainerName, "Sorter := func(itemList []*", x.mapValueType(index), ") func(i, j int) bool {") x.g.P("return func(i, j int) bool {") for i, field := range index.SortedColFields { fieldName, _ := x.parseKeyFieldNameAndSuffix(field) if i == len(index.SortedColFields)-1 { - x.g.P("return item[i]", fieldName, " < item[j]", fieldName) + x.g.P("return itemList[i]", fieldName, " < itemList[j]", fieldName) } else { - x.g.P("if item[i]", fieldName, " != item[j]", fieldName, " {") - x.g.P("return item[i]", fieldName, " < item[j]", fieldName) + x.g.P("if itemList[i]", fieldName, " != itemList[j]", fieldName, " {") + x.g.P("return itemList[i]", fieldName, " < itemList[j]", fieldName) x.g.P("}") } } x.g.P("}") x.g.P("}") - x.g.P("x.", x.orderedIndexContainerName(index, 0), ".Range(func(key ", x.orderedIndexMapKeyType(index), ", item []*", x.mapValueType(index), ") bool {") - x.g.P(helper.SortPackage.Ident("Slice"), "(item, ", indexContainerName, "Sorter(item))") + x.g.P("x.", x.orderedIndexContainerName(index, 0), ".Range(func(key ", x.orderedIndexMapKeyType(index), ", itemList []*", x.mapValueType(index), ") bool {") + x.g.P(helper.SortPackage.Ident("Slice"), "(itemList, ", indexContainerName, "Sorter(itemList))") x.g.P("return true") x.g.P("})") for i := 1; i <= levelMessage.MapDepth-2; i++ { if i > len(x.keys) { break } - x.g.P("for _, item := range x.", x.orderedIndexContainerName(index, i), " {") - x.g.P("item.Range(func(key ", x.orderedIndexMapKeyType(index), ", item1 []*", x.mapValueType(index), ") bool {") - x.g.P(helper.SortPackage.Ident("Slice"), "(item1, ", indexContainerName, "Sorter(item1))") + x.g.P("for _, itemMap := range x.", x.orderedIndexContainerName(index, i), " {") + x.g.P("itemMap.Range(func(key ", x.orderedIndexMapKeyType(index), ", itemList []*", x.mapValueType(index), ") bool {") + x.g.P(helper.SortPackage.Ident("Slice"), "(itemList, ", indexContainerName, "Sorter(itemList))") x.g.P("return true") x.g.P("})") x.g.P("}") @@ -340,7 +340,7 @@ func (x *Generator) genOrderedIndexFinders() { partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() - x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") treemap") + x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") ", i, "-level treemap") x.g.P("// specified by (", partArgs, ").") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") *", x.orderedIndexMapType(index), " {") @@ -353,7 +353,8 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key specified by (", partArgs, ").") + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", i, "-level treemap") + x.g.P("// specified by (", partArgs, ").") x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { x.g.P("val, _ := x.Find", index.Name(), "Map", i, "(", partArgs, ").Get(", args, ")") @@ -364,8 +365,8 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key specified by (", partArgs, "),") - x.g.P("// or nil if no value found.") + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", i, "-level treemap") + x.g.P("// specified by (", partArgs, "), or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") x.g.P("if len(val) > 0 {") diff --git a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go index 4d764c1e..c98487a8 100644 --- a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go @@ -163,20 +163,21 @@ func (x *HeroConf) FindFirstAttr(title string) *protoconf.HeroConf_Hero_Attr { return nil } -// FindAttrMap1 finds the index (Title) to value (protoconf.HeroConf_Hero_Attr) map +// FindAttrMap1 finds the index (Title) to value (protoconf.HeroConf_Hero_Attr) 1-level map // specified by (name). // One key may correspond to multiple values, which are contained by a slice. func (x *HeroConf) FindAttrMap1(name string) HeroConf_Index_AttrMap { return x.indexAttrMap1[name] } -// FindAttr1 finds a slice of all values of the given key specified by (name). +// FindAttr1 finds a slice of all values of the given key in the 1-level map +// specified by (name). func (x *HeroConf) FindAttr1(name string, title string) []*protoconf.HeroConf_Hero_Attr { return x.FindAttrMap1(name)[title] } -// FindFirstAttr1 finds the first value of the given key specified by (name), -// or nil if no value found. +// FindFirstAttr1 finds the first value of the given key in the 1-level map +// specified by (name), or nil if no value found. func (x *HeroConf) FindFirstAttr1(name string, title string) *protoconf.HeroConf_Hero_Attr { val := x.FindAttr1(name, title) if len(val) > 0 { diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index be2eb9ee..0f99322c 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -243,25 +243,25 @@ func (x *ItemConf) processAfterLoad() error { } } // Index(sort): Param@ItemInfo - indexItemInfoMapSorter := func(item []*protoconf.ItemConf_Item) func(i, j int) bool { + indexItemInfoMapSorter := func(itemList []*protoconf.ItemConf_Item) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - for _, item := range x.indexItemInfoMap { - sort.Slice(item, indexItemInfoMapSorter(item)) + for _, itemList := range x.indexItemInfoMap { + sort.Slice(itemList, indexItemInfoMapSorter(itemList)) } // Index(sort): (ID,Name)@AwardItem - indexAwardItemMapSorter := func(item []*protoconf.ItemConf_Item) func(i, j int) bool { + indexAwardItemMapSorter := func(itemList []*protoconf.ItemConf_Item) func(i, j int) bool { return func(i, j int) bool { - if item[i].GetType() != item[j].GetType() { - return item[i].GetType() < item[j].GetType() + if itemList[i].GetType() != itemList[j].GetType() { + return itemList[i].GetType() < itemList[j].GetType() } - return item[i].GetUseEffect().GetType() < item[j].GetUseEffect().GetType() + return itemList[i].GetUseEffect().GetType() < itemList[j].GetUseEffect().GetType() } } - for _, item := range x.indexAwardItemMap { - sort.Slice(item, indexAwardItemMapSorter(item)) + for _, itemList := range x.indexAwardItemMap { + sort.Slice(itemList, indexAwardItemMapSorter(itemList)) } // OrderedIndex init. x.orderedIndexExtTypeMap = treemap.New[protoconf.FruitType, []*protoconf.ItemConf_Item]() @@ -288,13 +288,13 @@ func (x *ItemConf) processAfterLoad() error { } } // OrderedIndex(sort): (Param,ExtType)@ParamExtType - orderedIndexParamExtTypeMapSorter := func(item []*protoconf.ItemConf_Item) func(i, j int) bool { + orderedIndexParamExtTypeMapSorter := func(itemList []*protoconf.ItemConf_Item) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - x.orderedIndexParamExtTypeMap.Range(func(key ItemConf_OrderedIndex_ParamExtTypeKey, item []*protoconf.ItemConf_Item) bool { - sort.Slice(item, orderedIndexParamExtTypeMapSorter(item)) + x.orderedIndexParamExtTypeMap.Range(func(key ItemConf_OrderedIndex_ParamExtTypeKey, itemList []*protoconf.ItemConf_Item) bool { + sort.Slice(itemList, orderedIndexParamExtTypeMapSorter(itemList)) return true }) return nil @@ -689,18 +689,18 @@ func (x *FruitConf) processAfterLoad() error { } } // OrderedIndex(sort): Price - orderedIndexItemMapSorter := func(item []*protoconf.FruitConf_Fruit_Item) func(i, j int) bool { + orderedIndexItemMapSorter := func(itemList []*protoconf.FruitConf_Fruit_Item) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - x.orderedIndexItemMap.Range(func(key int32, item []*protoconf.FruitConf_Fruit_Item) bool { - sort.Slice(item, orderedIndexItemMapSorter(item)) + x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.FruitConf_Fruit_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) return true }) - for _, item := range x.orderedIndexItemMap1 { - item.Range(func(key int32, item1 []*protoconf.FruitConf_Fruit_Item) bool { - sort.Slice(item1, orderedIndexItemMapSorter(item1)) + for _, itemMap := range x.orderedIndexItemMap1 { + itemMap.Range(func(key int32, itemList []*protoconf.FruitConf_Fruit_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) return true }) } @@ -757,21 +757,22 @@ func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { return nil } -// FindItemMap1 finds the index (Price) to value (protoconf.FruitConf_Fruit_Item) treemap +// FindItemMap1 finds the index (Price) to value (protoconf.FruitConf_Fruit_Item) 1-level treemap // specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. func (x *FruitConf) FindItemMap1(fruitType int32) *FruitConf_OrderedIndex_ItemMap { return x.orderedIndexItemMap1[fruitType] } -// FindItem1 finds a slice of all values of the given key specified by (fruitType). +// FindItem1 finds a slice of all values of the given key in the 1-level treemap +// specified by (fruitType). func (x *FruitConf) FindItem1(fruitType int32, price int32) []*protoconf.FruitConf_Fruit_Item { val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstItem1 finds the first value of the given key specified by (fruitType), -// or nil if no value found. +// FindFirstItem1 finds the first value of the given key in the 1-level treemap +// specified by (fruitType), or nil if no value found. func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.FruitConf_Fruit_Item { val := x.FindItem1(fruitType, price) if len(val) > 0 { @@ -915,18 +916,18 @@ func (x *Fruit2Conf) processAfterLoad() error { } } // OrderedIndex(sort): CountryItemPrice - orderedIndexItemMapSorter := func(item []*protoconf.Fruit2Conf_Fruit_Country_Item) func(i, j int) bool { + orderedIndexItemMapSorter := func(itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - x.orderedIndexItemMap.Range(func(key int32, item []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { - sort.Slice(item, orderedIndexItemMapSorter(item)) + x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) return true }) - for _, item := range x.orderedIndexItemMap1 { - item.Range(func(key int32, item1 []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { - sort.Slice(item1, orderedIndexItemMapSorter(item1)) + for _, itemMap := range x.orderedIndexItemMap1 { + itemMap.Range(func(key int32, itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) return true }) } @@ -990,20 +991,21 @@ func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Coun return nil } -// FindAttrMap1 finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map +// FindAttrMap1 finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) 1-level map // specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindAttrMap1(fruitType int32) Fruit2Conf_Index_AttrMap { return x.indexAttrMap1[fruitType] } -// FindAttr1 finds a slice of all values of the given key specified by (fruitType). +// FindAttr1 finds a slice of all values of the given key in the 1-level map +// specified by (fruitType). func (x *Fruit2Conf) FindAttr1(fruitType int32, name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { return x.FindAttrMap1(fruitType)[name] } -// FindFirstAttr1 finds the first value of the given key specified by (fruitType), -// or nil if no value found. +// FindFirstAttr1 finds the first value of the given key in the 1-level map +// specified by (fruitType), or nil if no value found. func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { val := x.FindAttr1(fruitType, name) if len(val) > 0 { @@ -1036,21 +1038,22 @@ func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Coun return nil } -// FindItemMap1 finds the index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap +// FindItemMap1 finds the index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) 1-level treemap // specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindItemMap1(fruitType int32) *Fruit2Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap1[fruitType] } -// FindItem1 finds a slice of all values of the given key specified by (fruitType). +// FindItem1 finds a slice of all values of the given key in the 1-level treemap +// specified by (fruitType). func (x *Fruit2Conf) FindItem1(fruitType int32, price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstItem1 finds the first value of the given key specified by (fruitType), -// or nil if no value found. +// FindFirstItem1 finds the first value of the given key in the 1-level treemap +// specified by (fruitType), or nil if no value found. func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { val := x.FindItem1(fruitType, price) if len(val) > 0 { diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index 5f2d67a5..5829d06e 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -215,17 +215,17 @@ func (x *ActivityConf) processAfterLoad() error { } } // Index(sort): ChapterName@NamedChapter - indexNamedChapterMapSorter := func(item []*protoconf.ActivityConf_Activity_Chapter) func(i, j int) bool { + indexNamedChapterMapSorter := func(itemList []*protoconf.ActivityConf_Activity_Chapter) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetAwardId() < item[j].GetAwardId() + return itemList[i].GetAwardId() < itemList[j].GetAwardId() } } - for _, item := range x.indexNamedChapterMap { - sort.Slice(item, indexNamedChapterMapSorter(item)) + for _, itemList := range x.indexNamedChapterMap { + sort.Slice(itemList, indexNamedChapterMapSorter(itemList)) } - for _, item := range x.indexNamedChapterMap1 { - for _, item1 := range item { - sort.Slice(item1, indexNamedChapterMapSorter(item1)) + for _, itemMap := range x.indexNamedChapterMap1 { + for _, itemList := range itemMap { + sort.Slice(itemList, indexNamedChapterMapSorter(itemList)) } } return nil @@ -377,20 +377,21 @@ func (x *ActivityConf) FindFirstChapter(chapterId uint32) *protoconf.ActivityCon return nil } -// FindChapterMap1 finds the index (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) map +// FindChapterMap1 finds the index (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) 1-level map // specified by (activityId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindChapterMap1(activityId uint64) ActivityConf_Index_ChapterMap { return x.indexChapterMap1[activityId] } -// FindChapter1 finds a slice of all values of the given key specified by (activityId). +// FindChapter1 finds a slice of all values of the given key in the 1-level map +// specified by (activityId). func (x *ActivityConf) FindChapter1(activityId uint64, chapterId uint32) []*protoconf.ActivityConf_Activity_Chapter { return x.FindChapterMap1(activityId)[chapterId] } -// FindFirstChapter1 finds the first value of the given key specified by (activityId), -// or nil if no value found. +// FindFirstChapter1 finds the first value of the given key in the 1-level map +// specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstChapter1(activityId uint64, chapterId uint32) *protoconf.ActivityConf_Activity_Chapter { val := x.FindChapter1(activityId, chapterId) if len(val) > 0 { @@ -422,20 +423,21 @@ func (x *ActivityConf) FindFirstNamedChapter(chapterName string) *protoconf.Acti return nil } -// FindNamedChapterMap1 finds the index (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) map +// FindNamedChapterMap1 finds the index (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) 1-level map // specified by (activityId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindNamedChapterMap1(activityId uint64) ActivityConf_Index_NamedChapterMap { return x.indexNamedChapterMap1[activityId] } -// FindNamedChapter1 finds a slice of all values of the given key specified by (activityId). +// FindNamedChapter1 finds a slice of all values of the given key in the 1-level map +// specified by (activityId). func (x *ActivityConf) FindNamedChapter1(activityId uint64, chapterName string) []*protoconf.ActivityConf_Activity_Chapter { return x.FindNamedChapterMap1(activityId)[chapterName] } -// FindFirstNamedChapter1 finds the first value of the given key specified by (activityId), -// or nil if no value found. +// FindFirstNamedChapter1 finds the first value of the given key in the 1-level map +// specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstNamedChapter1(activityId uint64, chapterName string) *protoconf.ActivityConf_Activity_Chapter { val := x.FindNamedChapter1(activityId, chapterName) if len(val) > 0 { @@ -467,20 +469,21 @@ func (x *ActivityConf) FindFirstAward(id uint32) *protoconf.Section_SectionItem return nil } -// FindAwardMap1 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map +// FindAwardMap1 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) 1-level map // specified by (activityId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap1(activityId uint64) ActivityConf_Index_AwardMap { return x.indexAwardMap1[activityId] } -// FindAward1 finds a slice of all values of the given key specified by (activityId). +// FindAward1 finds a slice of all values of the given key in the 1-level map +// specified by (activityId). func (x *ActivityConf) FindAward1(activityId uint64, id uint32) []*protoconf.Section_SectionItem { return x.FindAwardMap1(activityId)[id] } -// FindFirstAward1 finds the first value of the given key specified by (activityId), -// or nil if no value found. +// FindFirstAward1 finds the first value of the given key in the 1-level map +// specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf.Section_SectionItem { val := x.FindAward1(activityId, id) if len(val) > 0 { @@ -489,20 +492,21 @@ func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf. return nil } -// FindAwardMap2 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map +// FindAwardMap2 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) 2-level map // specified by (activityId, chapterId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap2(activityId uint64, chapterId uint32) ActivityConf_Index_AwardMap { return x.indexAwardMap2[ActivityConf_LevelIndex_Activity_ChapterKey{activityId, chapterId}] } -// FindAward2 finds a slice of all values of the given key specified by (activityId, chapterId). +// FindAward2 finds a slice of all values of the given key in the 2-level map +// specified by (activityId, chapterId). func (x *ActivityConf) FindAward2(activityId uint64, chapterId uint32, id uint32) []*protoconf.Section_SectionItem { return x.FindAwardMap2(activityId, chapterId)[id] } -// FindFirstAward2 finds the first value of the given key specified by (activityId, chapterId), -// or nil if no value found. +// FindFirstAward2 finds the first value of the given key in the 2-level map +// specified by (activityId, chapterId), or nil if no value found. func (x *ActivityConf) FindFirstAward2(activityId uint64, chapterId uint32, id uint32) *protoconf.Section_SectionItem { val := x.FindAward2(activityId, chapterId, id) if len(val) > 0 { @@ -793,16 +797,16 @@ func (x *TaskConf) processAfterLoad() error { } } // Index(sort): ActivityID - indexTaskMapSorter := func(item []*protoconf.TaskConf_Task) func(i, j int) bool { + indexTaskMapSorter := func(itemList []*protoconf.TaskConf_Task) func(i, j int) bool { return func(i, j int) bool { - if item[i].GetGoal() != item[j].GetGoal() { - return item[i].GetGoal() < item[j].GetGoal() + if itemList[i].GetGoal() != itemList[j].GetGoal() { + return itemList[i].GetGoal() < itemList[j].GetGoal() } - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - for _, item := range x.indexTaskMap { - sort.Slice(item, indexTaskMapSorter(item)) + for _, itemList := range x.indexTaskMap { + sort.Slice(itemList, indexTaskMapSorter(itemList)) } // OrderedIndex init. x.orderedIndexOrderedTaskMap = treemap.New[int64, []*protoconf.TaskConf_Task]() @@ -837,26 +841,26 @@ func (x *TaskConf) processAfterLoad() error { } } // OrderedIndex(sort): Goal@OrderedTask - orderedIndexOrderedTaskMapSorter := func(item []*protoconf.TaskConf_Task) func(i, j int) bool { + orderedIndexOrderedTaskMapSorter := func(itemList []*protoconf.TaskConf_Task) func(i, j int) bool { return func(i, j int) bool { - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - x.orderedIndexOrderedTaskMap.Range(func(key int64, item []*protoconf.TaskConf_Task) bool { - sort.Slice(item, orderedIndexOrderedTaskMapSorter(item)) + x.orderedIndexOrderedTaskMap.Range(func(key int64, itemList []*protoconf.TaskConf_Task) bool { + sort.Slice(itemList, orderedIndexOrderedTaskMapSorter(itemList)) return true }) // OrderedIndex(sort): Expiry@SortedTaskExpiry - orderedIndexSortedTaskExpiryMapSorter := func(item []*protoconf.TaskConf_Task) func(i, j int) bool { + orderedIndexSortedTaskExpiryMapSorter := func(itemList []*protoconf.TaskConf_Task) func(i, j int) bool { return func(i, j int) bool { - if item[i].GetGoal() != item[j].GetGoal() { - return item[i].GetGoal() < item[j].GetGoal() + if itemList[i].GetGoal() != itemList[j].GetGoal() { + return itemList[i].GetGoal() < itemList[j].GetGoal() } - return item[i].GetId() < item[j].GetId() + return itemList[i].GetId() < itemList[j].GetId() } } - x.orderedIndexSortedTaskExpiryMap.Range(func(key int64, item []*protoconf.TaskConf_Task) bool { - sort.Slice(item, orderedIndexSortedTaskExpiryMapSorter(item)) + x.orderedIndexSortedTaskExpiryMap.Range(func(key int64, itemList []*protoconf.TaskConf_Task) bool { + sort.Slice(itemList, orderedIndexSortedTaskExpiryMapSorter(itemList)) return true }) return nil From 14c06e5c9d6511b9efb542ccc904013721a14112 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Tue, 9 Dec 2025 21:29:10 +0800 Subject: [PATCH 11/15] chore: add Fruit3Conf to show that no level index is created when outer-most level is list --- .../cpp-tableau-loader/src/protoconf/hub.pc.h | 5 + .../src/protoconf/hub_shard0.pc.cc | 7 + .../src/protoconf/item_conf.pc.cc | 112 ++++++++++ .../src/protoconf/item_conf.pc.h | 64 ++++++ .../protoconf/loader/hub.pc.go | 4 + .../protoconf/loader/item_conf.pc.go | 205 ++++++++++++++++++ .../protoconf/loader/messager_container.pc.go | 6 + test/proto/item_conf.proto | 28 +++ test/testdata/conf/Fruit3Conf.json | 1 + 9 files changed, 432 insertions(+) create mode 100644 test/testdata/conf/Fruit3Conf.json diff --git a/test/cpp-tableau-loader/src/protoconf/hub.pc.h b/test/cpp-tableau-loader/src/protoconf/hub.pc.h index 73d18977..fb85329d 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/hub.pc.h @@ -130,6 +130,10 @@ class Fruit2Conf; template <> const std::shared_ptr Hub::Get() const; +class Fruit3Conf; +template <> +const std::shared_ptr Hub::Get() const; + class FruitConf; template <> const std::shared_ptr Hub::Get() const; @@ -183,6 +187,7 @@ class MessagerContainer { std::shared_ptr hero_base_conf_; std::shared_ptr hero_conf_; std::shared_ptr fruit_2_conf_; + std::shared_ptr fruit_3_conf_; std::shared_ptr fruit_conf_; std::shared_ptr item_conf_; std::shared_ptr patch_merge_conf_; diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc index 50c66ca3..571f2436 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc @@ -24,6 +24,11 @@ const std::shared_ptr Hub::Get() const { return GetMessagerContainerWithProvider()->fruit_2_conf_; } +template <> +const std::shared_ptr Hub::Get() const { + return GetMessagerContainerWithProvider()->fruit_3_conf_; +} + template <> const std::shared_ptr Hub::Get() const { return GetMessagerContainerWithProvider()->fruit_conf_; @@ -38,6 +43,7 @@ void MessagerContainer::InitShard0() { hero_base_conf_ = std::dynamic_pointer_cast(GetMessager(HeroBaseConf::Name())); hero_conf_ = std::dynamic_pointer_cast(GetMessager(HeroConf::Name())); fruit_2_conf_ = std::dynamic_pointer_cast(GetMessager(Fruit2Conf::Name())); + fruit_3_conf_ = std::dynamic_pointer_cast(GetMessager(Fruit3Conf::Name())); fruit_conf_ = std::dynamic_pointer_cast(GetMessager(FruitConf::Name())); item_conf_ = std::dynamic_pointer_cast(GetMessager(ItemConf::Name())); } @@ -46,6 +52,7 @@ void Registry::InitShard0() { Register(); Register(); Register(); + Register(); Register(); Register(); } diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index 74f3c6ca..94bccbbc 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -678,4 +678,116 @@ const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int return conf->front(); } +const std::string Fruit3Conf::kProtoName = protoconf::Fruit3Conf::GetDescriptor()->name(); + +bool Fruit3Conf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessagerInDir(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool Fruit3Conf::ProcessAfterLoad() { + // Index init. + index_country_map_.clear(); + index_attr_map_.clear(); + for (auto&& item1 : data_.fruit_list()) { + for (auto&& item2 : item1.country_list()) { + { + // Index: CountryName + index_country_map_[item2.name()].push_back(&item2); + } + for (auto&& item3 : item2.item_map()) { + auto k1 = item3.first; + for (auto&& item4 : item3.second.attr_list()) { + { + // Index: CountryItemAttrName + index_attr_map_[item4.name()].push_back(&item4); + } + } + } + } + } + // OrderedIndex init. + ordered_index_item_map_.clear(); + for (auto&& item1 : data_.fruit_list()) { + for (auto&& item2 : item1.country_list()) { + for (auto&& item3 : item2.item_map()) { + auto k1 = item3.first; + { + // OrderedIndex: CountryItemPrice + ordered_index_item_map_[item3.second.price()].push_back(&item3.second); + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + auto ordered_index_item_map_sorter = [](const protoconf::Fruit3Conf::Fruit::Country::Item* a, + const protoconf::Fruit3Conf::Fruit::Country::Item* b) { + return a->id() < b->id(); + }; + for (auto&& item : ordered_index_item_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); + } + return true; +} + +// Index: CountryName +const Fruit3Conf::Index_CountryMap& Fruit3Conf::FindCountryMap() const { return index_country_map_ ;} + +const Fruit3Conf::Index_CountryVector* Fruit3Conf::FindCountry(const std::string& name) const { + auto iter = index_country_map_.find(name); + if (iter == index_country_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit3Conf::Fruit::Country* Fruit3Conf::FindFirstCountry(const std::string& name) const { + auto conf = FindCountry(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// Index: CountryItemAttrName +const Fruit3Conf::Index_AttrMap& Fruit3Conf::FindAttrMap() const { return index_attr_map_ ;} + +const Fruit3Conf::Index_AttrVector* Fruit3Conf::FindAttr(const std::string& name) const { + auto iter = index_attr_map_.find(name); + if (iter == index_attr_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit3Conf::Fruit::Country::Item::Attr* Fruit3Conf::FindFirstAttr(const std::string& name) const { + auto conf = FindAttr(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// OrderedIndex: CountryItemPrice +const Fruit3Conf::OrderedIndex_ItemMap& Fruit3Conf::FindItemMap() const { return ordered_index_item_map_ ;} + +const Fruit3Conf::OrderedIndex_ItemVector* Fruit3Conf::FindItem(int32_t price) const { + auto iter = ordered_index_item_map_.find(price); + if (iter == ordered_index_item_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit3Conf::Fruit::Country::Item* Fruit3Conf::FindFirstItem(int32_t price) const { + auto conf = FindItem(price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index 47a003f3..bad65b05 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -393,6 +393,69 @@ class Fruit2Conf : public Messager { std::unordered_map ordered_index_item_map1_; }; +class Fruit3Conf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; + const protoconf::Fruit3Conf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + + private: + static const std::string kProtoName; + protoconf::Fruit3Conf data_; + + // Index accessers. + // Index: CountryName + public: + using Index_CountryVector = std::vector; + using Index_CountryMap = std::unordered_map; + // Finds the index (CountryName) to value (Index_CountryVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_CountryMap& FindCountryMap() const; + // Finds a vector of all values of the given key(s). + const Index_CountryVector* FindCountry(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit3Conf::Fruit::Country* FindFirstCountry(const std::string& name) const; + + private: + Index_CountryMap index_country_map_; + + // Index: CountryItemAttrName + public: + using Index_AttrVector = std::vector; + using Index_AttrMap = std::unordered_map; + // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_AttrMap& FindAttrMap() const; + // Finds a vector of all values of the given key(s). + const Index_AttrVector* FindAttr(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit3Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; + + private: + Index_AttrMap index_attr_map_; + + // OrderedIndex accessers. + // OrderedIndex: CountryItemPrice + public: + using OrderedIndex_ItemVector = std::vector; + using OrderedIndex_ItemMap = std::map; + // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap& FindItemMap() const; + // Finds a vector of all values of the given key(s). + const OrderedIndex_ItemVector* FindItem(int32_t price) const; + // Finds the first value of the given key(s). + const protoconf::Fruit3Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; + + private: + OrderedIndex_ItemMap ordered_index_item_map_; +}; + } // namespace tableau namespace protoconf { @@ -400,4 +463,5 @@ namespace protoconf { using ItemConfMgr = tableau::ItemConf; using FruitConfMgr = tableau::FruitConf; using Fruit2ConfMgr = tableau::Fruit2Conf; +using Fruit3ConfMgr = tableau::Fruit3Conf; } // namespace protoconf diff --git a/test/go-tableau-loader/protoconf/loader/hub.pc.go b/test/go-tableau-loader/protoconf/loader/hub.pc.go index 67ece84a..4e53ea25 100644 --- a/test/go-tableau-loader/protoconf/loader/hub.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hub.pc.go @@ -232,6 +232,10 @@ func (h *Hub) GetFruit2Conf() *Fruit2Conf { return h.mc.Load().GetFruit2Conf() } +func (h *Hub) GetFruit3Conf() *Fruit3Conf { + return h.mc.Load().GetFruit3Conf() +} + func (h *Hub) GetPatchReplaceConf() *PatchReplaceConf { return h.mc.Load().GetPatchReplaceConf() } diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index 0f99322c..4cb2c180 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -1062,6 +1062,208 @@ func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fru return nil } +// Index types. +// Index: CountryName +type Fruit3Conf_Index_CountryMap = map[string][]*protoconf.Fruit3Conf_Fruit_Country + +// Index: CountryItemAttrName +type Fruit3Conf_Index_AttrMap = map[string][]*protoconf.Fruit3Conf_Fruit_Country_Item_Attr + +// OrderedIndex types. +// OrderedIndex: CountryItemPrice +type Fruit3Conf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.Fruit3Conf_Fruit_Country_Item] + +// Fruit3Conf is a wrapper around protobuf message: protoconf.Fruit3Conf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... +type Fruit3Conf struct { + UnimplementedMessager + data, originalData *protoconf.Fruit3Conf + indexCountryMap Fruit3Conf_Index_CountryMap + indexAttrMap Fruit3Conf_Index_AttrMap + orderedIndexItemMap *Fruit3Conf_OrderedIndex_ItemMap +} + +// Name returns the Fruit3Conf's message name. +func (x *Fruit3Conf) Name() string { + return string((*protoconf.Fruit3Conf)(nil).ProtoReflect().Descriptor().Name()) +} + +// Data returns the Fruit3Conf's inner message data. +func (x *Fruit3Conf) Data() *protoconf.Fruit3Conf { + if x != nil { + return x.data + } + return nil +} + +// Load fills Fruit3Conf's inner message from file in the specified directory and format. +func (x *Fruit3Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.Fruit3Conf{} + err := load.LoadMessagerInDir(x.data, dir, format, opts) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.Fruit3Conf) + } + return x.processAfterLoad() +} + +// Store writes Fruit3Conf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *Fruit3Conf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the Fruit3Conf's inner message data. +func (x *Fruit3Conf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *Fruit3Conf) Messager() Messager { + return x +} + +// originalMessage returns the Fruit3Conf's original inner message. +func (x *Fruit3Conf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *Fruit3Conf) processAfterLoad() error { + // Index init. + x.indexCountryMap = make(Fruit3Conf_Index_CountryMap) + x.indexAttrMap = make(Fruit3Conf_Index_AttrMap) + for _, v1 := range x.data.GetFruitList() { + for _, v2 := range v1.GetCountryList() { + { + // Index: CountryName + key := v2.GetName() + x.indexCountryMap[key] = append(x.indexCountryMap[key], v2) + } + for k1, v3 := range v2.GetItemMap() { + _ = k1 + for _, v4 := range v3.GetAttrList() { + { + // Index: CountryItemAttrName + key := v4.GetName() + x.indexAttrMap[key] = append(x.indexAttrMap[key], v4) + } + } + } + } + } + // OrderedIndex init. + x.orderedIndexItemMap = treemap.New[int32, []*protoconf.Fruit3Conf_Fruit_Country_Item]() + for _, v1 := range x.data.GetFruitList() { + for _, v2 := range v1.GetCountryList() { + for k1, v3 := range v2.GetItemMap() { + _ = k1 + { + // OrderedIndex: CountryItemPrice + key := v3.GetPrice() + value, _ := x.orderedIndexItemMap.Get(key) + x.orderedIndexItemMap.Put(key, append(value, v3)) + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + orderedIndexItemMapSorter := func(itemList []*protoconf.Fruit3Conf_Fruit_Country_Item) func(i, j int) bool { + return func(i, j int) bool { + return itemList[i].GetId() < itemList[j].GetId() + } + } + x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.Fruit3Conf_Fruit_Country_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) + return true + }) + return nil +} + +// Index: CountryName + +// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit3Conf_Fruit_Country) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit3Conf) FindCountryMap() Fruit3Conf_Index_CountryMap { + return x.indexCountryMap +} + +// FindCountry finds a slice of all values of the given key. +func (x *Fruit3Conf) FindCountry(name string) []*protoconf.Fruit3Conf_Fruit_Country { + return x.indexCountryMap[name] +} + +// FindFirstCountry finds the first value of the given key, +// or nil if no value found. +func (x *Fruit3Conf) FindFirstCountry(name string) *protoconf.Fruit3Conf_Fruit_Country { + val := x.FindCountry(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// Index: CountryItemAttrName + +// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit3Conf) FindAttrMap() Fruit3Conf_Index_AttrMap { + return x.indexAttrMap +} + +// FindAttr finds a slice of all values of the given key. +func (x *Fruit3Conf) FindAttr(name string) []*protoconf.Fruit3Conf_Fruit_Country_Item_Attr { + return x.indexAttrMap[name] +} + +// FindFirstAttr finds the first value of the given key, +// or nil if no value found. +func (x *Fruit3Conf) FindFirstAttr(name string) *protoconf.Fruit3Conf_Fruit_Country_Item_Attr { + val := x.FindAttr(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// OrderedIndex: CountryItemPrice + +// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit3Conf_Fruit_Country_Item) treemap. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit3Conf) FindItemMap() *Fruit3Conf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap +} + +// FindItem finds a slice of all values of the given key. +func (x *Fruit3Conf) FindItem(price int32) []*protoconf.Fruit3Conf_Fruit_Country_Item { + val, _ := x.orderedIndexItemMap.Get(price) + return val +} + +// FindFirstItem finds the first value of the given key, +// or nil if no value found. +func (x *Fruit3Conf) FindFirstItem(price int32) *protoconf.Fruit3Conf_Fruit_Country_Item { + val := x.FindItem(price) + if len(val) > 0 { + return val[0] + } + return nil +} + func init() { Register(func() Messager { return new(ItemConf) @@ -1072,4 +1274,7 @@ func init() { Register(func() Messager { return new(Fruit2Conf) }) + Register(func() Messager { + return new(Fruit3Conf) + }) } diff --git a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go index 31627cbe..7cfd2867 100644 --- a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go +++ b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go @@ -18,6 +18,7 @@ type MessagerContainer struct { itemConf *ItemConf fruitConf *FruitConf fruit2Conf *Fruit2Conf + fruit3Conf *Fruit3Conf patchReplaceConf *PatchReplaceConf patchMergeConf *PatchMergeConf recursivePatchConf *RecursivePatchConf @@ -36,6 +37,7 @@ func newMessagerContainer(messagerMap MessagerMap) *MessagerContainer { itemConf: GetMessager[*ItemConf](messagerMap), fruitConf: GetMessager[*FruitConf](messagerMap), fruit2Conf: GetMessager[*Fruit2Conf](messagerMap), + fruit3Conf: GetMessager[*Fruit3Conf](messagerMap), patchReplaceConf: GetMessager[*PatchReplaceConf](messagerMap), patchMergeConf: GetMessager[*PatchMergeConf](messagerMap), recursivePatchConf: GetMessager[*RecursivePatchConf](messagerMap), @@ -80,6 +82,10 @@ func (mc *MessagerContainer) GetFruit2Conf() *Fruit2Conf { return mc.fruit2Conf } +func (mc *MessagerContainer) GetFruit3Conf() *Fruit3Conf { + return mc.fruit3Conf +} + func (mc *MessagerContainer) GetPatchReplaceConf() *PatchReplaceConf { return mc.patchReplaceConf } diff --git a/test/proto/item_conf.proto b/test/proto/item_conf.proto index fef8d5cd..07e0c68a 100644 --- a/test/proto/item_conf.proto +++ b/test/proto/item_conf.proto @@ -122,4 +122,32 @@ message Fruit2Conf { } } } +} + +message Fruit3Conf { + option (tableau.worksheet) = { + name: "Fruit2Conf" + index: "CountryName" + index: "CountryItemAttrName" + ordered_index: "CountryItemPrice" + }; + + repeated Fruit fruit_list = 1 [(tableau.field) = { layout: LAYOUT_VERTICAL }]; + message Fruit { + protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; + repeated Country country_list = 2 [(tableau.field) = { name: "Country" layout: LAYOUT_HORIZONTAL }]; + message Country { + string name = 1 [(tableau.field) = { name: "Name" }]; + map item_map = 2 [(tableau.field) = { name: "Item" key: "ID" layout: LAYOUT_HORIZONTAL }]; + message Item { + int32 id = 1 [(tableau.field) = { name: "ID" }]; + int32 price = 2 [(tableau.field) = { name: "Price" }]; + repeated Attr attr_list = 3 [(tableau.field) = { name: "Attr" layout: LAYOUT_HORIZONTAL }]; + message Attr { + string name = 1 [(tableau.field) = { name: "Name" }]; + int32 value = 2 [(tableau.field) = { name: "Value" }]; + } + } + } + } } \ No newline at end of file diff --git a/test/testdata/conf/Fruit3Conf.json b/test/testdata/conf/Fruit3Conf.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/test/testdata/conf/Fruit3Conf.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 545396c9acbaf66c34198f8813a3d2f109abc863 Mon Sep 17 00:00:00 2001 From: wenchy Date: Thu, 11 Dec 2025 20:23:50 +0800 Subject: [PATCH 12/15] refactor: add new index_conf.proto for testing Index and OrderedIndex --- .../helper/helper.go | 24 +- .../indexes/generator.go | 2 +- .../indexes/index.go | 6 +- .../indexes/ordered_index.go | 6 +- cmd/protoc-gen-cpp-tableau-loader/messager.go | 4 +- .../orderedmap/ordered_map.go | 4 +- .../helper/helper.go | 20 +- .../indexes/generator.go | 2 +- .../indexes/index.go | 6 +- .../indexes/orderedindex.go | 6 +- cmd/protoc-gen-go-tableau-loader/messager.go | 2 +- .../orderedmap/ordered_map.go | 6 +- internal/index/descriptor.go | 16 +- .../src/protoconf/hub_shard0.pc.cc | 1 + .../src/protoconf/index_conf.pc.cc | 420 +++++++++++ .../src/protoconf/index_conf.pc.h | 213 ++++++ .../src/protoconf/item_conf.pc.cc | 407 ---------- .../src/protoconf/item_conf.pc.h | 193 ----- .../protoconf/loader/hub.pc.go | 8 +- .../protoconf/loader/index_conf.pc.go | 701 ++++++++++++++++++ .../protoconf/loader/item_conf.pc.go | 679 ----------------- .../protoconf/loader/messager_container.pc.go | 12 +- test/proto/index_conf.proto | 87 +++ test/proto/item_conf.proto | 75 +- 24 files changed, 1485 insertions(+), 1415 deletions(-) create mode 100644 test/cpp-tableau-loader/src/protoconf/index_conf.pc.cc create mode 100644 test/cpp-tableau-loader/src/protoconf/index_conf.pc.h create mode 100644 test/go-tableau-loader/protoconf/loader/index_conf.pc.go create mode 100644 test/proto/index_conf.proto diff --git a/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go b/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go index 9fc2e84c..88d98056 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go +++ b/cmd/protoc-gen-cpp-tableau-loader/helper/helper.go @@ -178,45 +178,45 @@ type MapKey struct { Name string } -type MapKeys []MapKey +type MapKeySlice []MapKey -func (keys MapKeys) AddMapKey(newKey MapKey) MapKeys { +func (s MapKeySlice) AddMapKey(newKey MapKey) MapKeySlice { if newKey.Name == "" { - newKey.Name = fmt.Sprintf("key%d", len(keys)+1) + newKey.Name = fmt.Sprintf("key%d", len(s)+1) } else { - for _, key := range keys { + for _, key := range s { if key.Name == newKey.Name { // rewrite to avoid name confict - newKey.Name = fmt.Sprintf("%s%d", newKey.Name, len(keys)+1) + newKey.Name = fmt.Sprintf("%s%d", newKey.Name, len(s)+1) break } } } - return append(keys, newKey) + return append(s, newKey) } // GenGetParams generates function parameters, which are the names listed in the function's definition. -func (keys MapKeys) GenGetParams() string { +func (s MapKeySlice) GenGetParams() string { var params []string - for _, key := range keys { + for _, key := range s { params = append(params, ToConstRefType(key.Type)+" "+key.Name) } return strings.Join(params, ", ") } // GenGetArguments generates function arguments, which are the real values passed to the function. -func (keys MapKeys) GenGetArguments() string { +func (s MapKeySlice) GenGetArguments() string { var params []string - for _, key := range keys { + for _, key := range s { params = append(params, key.Name) } return strings.Join(params, ", ") } // GenOtherArguments generates function arguments for other value of std::tie. -func (keys MapKeys) GenOtherArguments(other string) string { +func (s MapKeySlice) GenOtherArguments(other string) string { var params []string - for _, key := range keys { + for _, key := range s { params = append(params, other+"."+key.Name) } return strings.Join(params, ", ") diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go index e4163b5e..b6f821fe 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/generator.go @@ -16,7 +16,7 @@ type Generator struct { // level message maxDepth int - keys helper.MapKeys + keys helper.MapKeySlice mapFds []protoreflect.FieldDescriptor } diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go index b2034a28..5bb9dc6f 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go @@ -41,8 +41,8 @@ func (x *Generator) indexContainerName(index *index.LevelIndex, i int) string { return fmt.Sprintf("index_%s_map%d_", strcase.ToSnake(index.Name()), i) } -func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { - var keys helper.MapKeys +func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeySlice { + var keys helper.MapKeySlice for _, field := range index.ColFields { keys = keys.AddMapKey(helper.MapKey{ Type: helper.ParseCppType(field.FD), @@ -202,7 +202,7 @@ func (x *Generator) genOneCppIndexLoader(depth int, ident int, index *index.Leve x.g.P(helper.Indent(ident), "}") } -func (x *Generator) generateOneCppMulticolumnIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { +func (x *Generator) generateOneCppMulticolumnIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeySlice) { cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.indexMapKeyType(index) diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go index 66e89e51..7ecccb9d 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go @@ -41,8 +41,8 @@ func (x *Generator) orderedIndexContainerName(index *index.LevelIndex, i int) st return fmt.Sprintf("ordered_index_%s_map%d_", strcase.ToSnake(index.Name()), i) } -func (x *Generator) orderedIndexKeys(index *index.LevelIndex) helper.MapKeys { - var keys helper.MapKeys +func (x *Generator) orderedIndexKeys(index *index.LevelIndex) helper.MapKeySlice { + var keys helper.MapKeySlice for _, field := range index.ColFields { keys = keys.AddMapKey(helper.MapKey{ Type: helper.ParseOrderedIndexKeyType(field.FD), @@ -192,7 +192,7 @@ func (x *Generator) genOneCppOrderedIndexLoader(depth int, ident int, index *ind x.g.P(helper.Indent(ident), "}") } -func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { +func (x *Generator) generateOneCppMulticolumnOrderedIndex(depth, ident int, index *index.LevelIndex, parentDataName string, keys helper.MapKeySlice) { cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.orderedIndexMapKeyType(index) diff --git a/cmd/protoc-gen-cpp-tableau-loader/messager.go b/cmd/protoc-gen-cpp-tableau-loader/messager.go index 9d17157b..db1c9eaa 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/messager.go +++ b/cmd/protoc-gen-cpp-tableau-loader/messager.go @@ -112,7 +112,7 @@ func genHppMessage(g *protogen.GeneratedFile, message *protogen.Message) { g.P() } -func genHppMapGetters(depth int, keys helper.MapKeys, g *protogen.GeneratedFile, md protoreflect.MessageDescriptor) { +func genHppMapGetters(depth int, keys helper.MapKeySlice, g *protogen.GeneratedFile, md protoreflect.MessageDescriptor) { for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() { @@ -186,7 +186,7 @@ func genCppMessage(g *protogen.GeneratedFile, message *protogen.Message) { indexGenerator.GenCppIndexFinders() } -func genCppMapGetters(g *protogen.GeneratedFile, md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys, messagerName string) { +func genCppMapGetters(g *protogen.GeneratedFile, md protoreflect.MessageDescriptor, depth int, keys helper.MapKeySlice, messagerName string) { for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() { diff --git a/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go b/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go index 47ece8b6..c833ef65 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go +++ b/cmd/protoc-gen-cpp-tableau-loader/orderedmap/ordered_map.go @@ -55,7 +55,7 @@ func (x *Generator) GenHppOrderedMapGetters() { x.genHppOrderedMapGetters(x.message.Desc, 1, nil) } -func (x *Generator) genHppOrderedMapGetters(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys) { +func (x *Generator) genHppOrderedMapGetters(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeySlice) { for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() { @@ -141,7 +141,7 @@ func (x *Generator) GenOrderedMapGetters() { x.genOrderedMapGetters(x.message.Desc, 1, nil) } -func (x *Generator) genOrderedMapGetters(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys) { +func (x *Generator) genOrderedMapGetters(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeySlice) { messagerName := x.messagerName() for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) diff --git a/cmd/protoc-gen-go-tableau-loader/helper/helper.go b/cmd/protoc-gen-go-tableau-loader/helper/helper.go index 2b2818d7..79fc79ad 100644 --- a/cmd/protoc-gen-go-tableau-loader/helper/helper.go +++ b/cmd/protoc-gen-go-tableau-loader/helper/helper.go @@ -264,35 +264,35 @@ type MapKey struct { FieldName string // multi-colunm index only } -type MapKeys []MapKey +type MapKeySlice []MapKey -func (keys MapKeys) AddMapKey(newKey MapKey) MapKeys { +func (s MapKeySlice) AddMapKey(newKey MapKey) MapKeySlice { if newKey.Name == "" { - newKey.Name = fmt.Sprintf("key%d", len(keys)+1) + newKey.Name = fmt.Sprintf("key%d", len(s)+1) } - for _, key := range keys { + for _, key := range s { if key.Name == newKey.Name { // rewrite to avoid name confict - newKey.Name = fmt.Sprintf("%s%d", newKey.Name, len(keys)+1) + newKey.Name = fmt.Sprintf("%s%d", newKey.Name, len(s)+1) break } } - return append(keys, newKey) + return append(s, newKey) } // GenGetParams generates function parameters, which are the names listed in the function's definition. -func (keys MapKeys) GenGetParams() string { +func (s MapKeySlice) GenGetParams() string { var params []string - for _, key := range keys { + for _, key := range s { params = append(params, key.Name+" "+key.Type) } return strings.Join(params, ", ") } // GenGetArguments generates function arguments, which are the real values passed to the function. -func (keys MapKeys) GenGetArguments() string { +func (s MapKeySlice) GenGetArguments() string { var params []string - for _, key := range keys { + for _, key := range s { params = append(params, key.Name) } return strings.Join(params, ", ") diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/generator.go b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go index 9b830856..6ce60493 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/generator.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/generator.go @@ -17,7 +17,7 @@ type Generator struct { // level message maxDepth int - keys helper.MapKeys + keys helper.MapKeySlice mapFds []protoreflect.FieldDescriptor } diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go index c38fc7d5..1de20c14 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -36,8 +36,8 @@ func (x *Generator) indexContainerName(index *index.LevelIndex, i int) string { return fmt.Sprintf("index%sMap%d", strcase.ToCamel(index.Name()), i) } -func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeys { - var keys helper.MapKeys +func (x *Generator) indexKeys(index *index.LevelIndex) helper.MapKeySlice { + var keys helper.MapKeySlice for _, field := range index.ColFields { keys = keys.AddMapKey(helper.MapKey{ Type: helper.ParseGoType(x.gen, x.g, field.FD), @@ -167,7 +167,7 @@ func (x *Generator) genOneIndexLoader(index *index.LevelIndex, depth int, parent x.g.P("}") } -func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { +func (x *Generator) generateOneMulticolumnIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeySlice) { cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.indexMapKeyType(index) diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index 12e6a8e7..cea2d10d 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -46,8 +46,8 @@ func (x *Generator) mapCtor(index *index.LevelIndex) string { } } -func (x *Generator) orderedIndexKeys(index *index.LevelIndex) helper.MapKeys { - var keys helper.MapKeys +func (x *Generator) orderedIndexKeys(index *index.LevelIndex) helper.MapKeySlice { + var keys helper.MapKeySlice for _, field := range index.ColFields { keys = keys.AddMapKey(helper.MapKey{ Type: helper.ParseOrderedIndexKeyType(x.gen, x.g, field.FD), @@ -191,7 +191,7 @@ func (x *Generator) genOneOrderedIndexLoader(index *index.LevelIndex, depth int, x.g.P("}") } -func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeys) { +func (x *Generator) generateOneMulticolumnOrderedIndex(depth int, index *index.LevelIndex, parentDataName string, keys helper.MapKeySlice) { cursor := len(keys) if cursor >= len(index.ColFields) { keyType := x.orderedIndexMapKeyType(index) diff --git a/cmd/protoc-gen-go-tableau-loader/messager.go b/cmd/protoc-gen-go-tableau-loader/messager.go index e409faca..6dd342e3 100644 --- a/cmd/protoc-gen-go-tableau-loader/messager.go +++ b/cmd/protoc-gen-go-tableau-loader/messager.go @@ -164,7 +164,7 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog indexGenerator.GenIndexFinders() } -func genMapGetters(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protogen.Message, depth int, keys helper.MapKeys, messagerName string) { +func genMapGetters(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protogen.Message, depth int, keys helper.MapKeySlice, messagerName string) { for _, field := range message.Fields { fd := field.Desc if fd.IsMap() { diff --git a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go index d321a856..231c0d29 100644 --- a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go +++ b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go @@ -55,7 +55,7 @@ func (x *Generator) GenOrderedMapTypeDef() { x.genOrderedMapTypeDef(x.message.Desc, 1, nil) } -func (x *Generator) genOrderedMapTypeDef(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys) { +func (x *Generator) genOrderedMapTypeDef(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeySlice) { for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() { @@ -107,7 +107,7 @@ func (x *Generator) GenOrderedMapLoader() { x.genOrderedMapLoader(x.message.Desc, 1, nil, "") } -func (x *Generator) genOrderedMapLoader(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys, lastOrderedMapValue string) { +func (x *Generator) genOrderedMapLoader(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeySlice, lastOrderedMapValue string) { message := helper.FindMessage(x.gen, md) for _, field := range message.Fields { fd := field.Desc @@ -168,7 +168,7 @@ func (x *Generator) GenOrderedMapGetters() { x.genOrderedMapGetters(x.message.Desc, 1, nil) } -func (x *Generator) genOrderedMapGetters(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeys) { +func (x *Generator) genOrderedMapGetters(md protoreflect.MessageDescriptor, depth int, keys helper.MapKeySlice) { genGetterName := func(depth int) string { getter := "GetOrderedMap" if depth > 1 { diff --git a/internal/index/descriptor.go b/internal/index/descriptor.go index 5fdcdd0d..e68308ec 100644 --- a/internal/index/descriptor.go +++ b/internal/index/descriptor.go @@ -88,23 +88,23 @@ func (l *LevelIndex) Name() string { } func parseLevelMessage(md protoreflect.MessageDescriptor, depth, mapDepth int) *LevelMessage { - levelInfo := &LevelMessage{ + levelMsg := &LevelMessage{ Depth: depth, MapDepth: mapDepth, } for i := 0; i < md.Fields().Len(); i++ { fd := md.Fields().Get(i) if fd.IsMap() && fd.MapValue().Kind() == protoreflect.MessageKind { - levelInfo.NextLevel = parseLevelMessage(fd.MapValue().Message(), depth+1, mapDepth+1) - levelInfo.FD = fd - return levelInfo + levelMsg.NextLevel = parseLevelMessage(fd.MapValue().Message(), depth+1, mapDepth+1) + levelMsg.FD = fd + return levelMsg } else if fd.IsList() && fd.Kind() == protoreflect.MessageKind { - levelInfo.NextLevel = parseLevelMessage(fd.Message(), depth+1, mapDepth) - levelInfo.FD = fd - return levelInfo + levelMsg.NextLevel = parseLevelMessage(fd.Message(), depth+1, mapDepth) + levelMsg.FD = fd + return levelMsg } } - return levelInfo + return levelMsg } // parseRecursively parses multi-column index related info. diff --git a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc index 571f2436..f9c04280 100644 --- a/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/hub_shard0.pc.cc @@ -6,6 +6,7 @@ #include "hub.pc.h" #include "hero_conf.pc.h" +#include "index_conf.pc.h" #include "item_conf.pc.h" namespace tableau { diff --git a/test/cpp-tableau-loader/src/protoconf/index_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/index_conf.pc.cc new file mode 100644 index 00000000..0e703d09 --- /dev/null +++ b/test/cpp-tableau-loader/src/protoconf/index_conf.pc.cc @@ -0,0 +1,420 @@ +// Code generated by protoc-gen-cpp-tableau-loader. DO NOT EDIT. +// versions: +// - protoc-gen-cpp-tableau-loader v0.10.1 +// - protoc v3.19.3 +// source: index_conf.proto + +#include "index_conf.pc.h" + +#include "hub.pc.h" +#include "util.pc.h" + +namespace tableau { +const std::string FruitConf::kProtoName = protoconf::FruitConf::GetDescriptor()->name(); + +bool FruitConf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessagerInDir(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool FruitConf::ProcessAfterLoad() { + // OrderedIndex init. + ordered_index_item_map_.clear(); + ordered_index_item_map1_.clear(); + for (auto&& item1 : data_.fruit_map()) { + auto k1 = item1.first; + for (auto&& item2 : item1.second.item_map()) { + auto k2 = item2.first; + { + // OrderedIndex: Price + ordered_index_item_map_[item2.second.price()].push_back(&item2.second); + ordered_index_item_map1_[k1][item2.second.price()].push_back(&item2.second); + } + } + } + // OrderedIndex(sort): Price + auto ordered_index_item_map_sorter = [](const protoconf::FruitConf::Fruit::Item* a, + const protoconf::FruitConf::Fruit::Item* b) { + return a->id() < b->id(); + }; + for (auto&& item : ordered_index_item_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); + } + for (auto&& item : ordered_index_item_map1_) { + for (auto&& item1 : item.second) { + std::sort(item1.second.begin(), item1.second.end(), ordered_index_item_map_sorter); + } + } + return true; +} + +const protoconf::FruitConf::Fruit* FruitConf::Get(int32_t fruit_type) const { + auto iter = data_.fruit_map().find(fruit_type); + if (iter == data_.fruit_map().end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::FruitConf::Fruit::Item* FruitConf::Get(int32_t fruit_type, int32_t id) const { + const auto* conf = Get(fruit_type); + if (conf == nullptr) { + return nullptr; + } + auto iter = conf->item_map().find(id); + if (iter == conf->item_map().end()) { + return nullptr; + } + return &iter->second; +} + +// OrderedIndex: Price +const FruitConf::OrderedIndex_ItemMap& FruitConf::FindItemMap() const { return ordered_index_item_map_ ;} + +const FruitConf::OrderedIndex_ItemVector* FruitConf::FindItem(int32_t price) const { + auto iter = ordered_index_item_map_.find(price); + if (iter == ordered_index_item_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t price) const { + auto conf = FindItem(price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const FruitConf::OrderedIndex_ItemMap* FruitConf::FindItemMap(int32_t fruit_type) const { + auto iter = ordered_index_item_map1_.find(fruit_type); + if (iter == ordered_index_item_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const FruitConf::OrderedIndex_ItemVector* FruitConf::FindItem(int32_t fruit_type, int32_t price) const { + auto map = FindItemMap(fruit_type); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(price); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t fruit_type, int32_t price) const { + auto conf = FindItem(fruit_type, price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const std::string Fruit2Conf::kProtoName = protoconf::Fruit2Conf::GetDescriptor()->name(); + +bool Fruit2Conf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessagerInDir(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool Fruit2Conf::ProcessAfterLoad() { + // Index init. + index_country_map_.clear(); + index_attr_map_.clear(); + index_attr_map1_.clear(); + for (auto&& item1 : data_.fruit_map()) { + auto k1 = item1.first; + for (auto&& item2 : item1.second.country_list()) { + { + // Index: CountryName + index_country_map_[item2.name()].push_back(&item2); + } + for (auto&& item3 : item2.item_map()) { + auto k2 = item3.first; + for (auto&& item4 : item3.second.attr_list()) { + { + // Index: CountryItemAttrName + index_attr_map_[item4.name()].push_back(&item4); + index_attr_map1_[k1][item4.name()].push_back(&item4); + } + } + } + } + } + // OrderedIndex init. + ordered_index_item_map_.clear(); + ordered_index_item_map1_.clear(); + for (auto&& item1 : data_.fruit_map()) { + auto k1 = item1.first; + for (auto&& item2 : item1.second.country_list()) { + for (auto&& item3 : item2.item_map()) { + auto k2 = item3.first; + { + // OrderedIndex: CountryItemPrice + ordered_index_item_map_[item3.second.price()].push_back(&item3.second); + ordered_index_item_map1_[k1][item3.second.price()].push_back(&item3.second); + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + auto ordered_index_item_map_sorter = [](const protoconf::Fruit2Conf::Fruit::Country::Item* a, + const protoconf::Fruit2Conf::Fruit::Country::Item* b) { + return a->id() < b->id(); + }; + for (auto&& item : ordered_index_item_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); + } + for (auto&& item : ordered_index_item_map1_) { + for (auto&& item1 : item.second) { + std::sort(item1.second.begin(), item1.second.end(), ordered_index_item_map_sorter); + } + } + return true; +} + +const protoconf::Fruit2Conf::Fruit* Fruit2Conf::Get(int32_t fruit_type) const { + auto iter = data_.fruit_map().find(fruit_type); + if (iter == data_.fruit_map().end()) { + return nullptr; + } + return &iter->second; +} + +// Index: CountryName +const Fruit2Conf::Index_CountryMap& Fruit2Conf::FindCountryMap() const { return index_country_map_ ;} + +const Fruit2Conf::Index_CountryVector* Fruit2Conf::FindCountry(const std::string& name) const { + auto iter = index_country_map_.find(name); + if (iter == index_country_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country* Fruit2Conf::FindFirstCountry(const std::string& name) const { + auto conf = FindCountry(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// Index: CountryItemAttrName +const Fruit2Conf::Index_AttrMap& Fruit2Conf::FindAttrMap() const { return index_attr_map_ ;} + +const Fruit2Conf::Index_AttrVector* Fruit2Conf::FindAttr(const std::string& name) const { + auto iter = index_attr_map_.find(name); + if (iter == index_attr_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* Fruit2Conf::FindFirstAttr(const std::string& name) const { + auto conf = FindAttr(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const Fruit2Conf::Index_AttrMap* Fruit2Conf::FindAttrMap(int32_t fruit_type) const { + auto iter = index_attr_map1_.find(fruit_type); + if (iter == index_attr_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const Fruit2Conf::Index_AttrVector* Fruit2Conf::FindAttr(int32_t fruit_type, const std::string& name) const { + auto map = FindAttrMap(fruit_type); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(name); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* Fruit2Conf::FindFirstAttr(int32_t fruit_type, const std::string& name) const { + auto conf = FindAttr(fruit_type, name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// OrderedIndex: CountryItemPrice +const Fruit2Conf::OrderedIndex_ItemMap& Fruit2Conf::FindItemMap() const { return ordered_index_item_map_ ;} + +const Fruit2Conf::OrderedIndex_ItemVector* Fruit2Conf::FindItem(int32_t price) const { + auto iter = ordered_index_item_map_.find(price); + if (iter == ordered_index_item_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int32_t price) const { + auto conf = FindItem(price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const Fruit2Conf::OrderedIndex_ItemMap* Fruit2Conf::FindItemMap(int32_t fruit_type) const { + auto iter = ordered_index_item_map1_.find(fruit_type); + if (iter == ordered_index_item_map1_.end()) { + return nullptr; + } + return &iter->second; +} + +const Fruit2Conf::OrderedIndex_ItemVector* Fruit2Conf::FindItem(int32_t fruit_type, int32_t price) const { + auto map = FindItemMap(fruit_type); + if (map == nullptr) { + return nullptr; + } + auto iter = map->find(price); + if (iter == map->end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int32_t fruit_type, int32_t price) const { + auto conf = FindItem(fruit_type, price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +const std::string Fruit3Conf::kProtoName = protoconf::Fruit3Conf::GetDescriptor()->name(); + +bool Fruit3Conf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { + tableau::util::TimeProfiler profiler; + bool loaded = LoadMessagerInDir(data_, dir, fmt, options); + bool ok = loaded ? ProcessAfterLoad() : false; + stats_.duration = profiler.Elapse(); + return ok; +} + +bool Fruit3Conf::ProcessAfterLoad() { + // Index init. + index_country_map_.clear(); + index_attr_map_.clear(); + for (auto&& item1 : data_.fruit_list()) { + for (auto&& item2 : item1.country_list()) { + { + // Index: CountryName + index_country_map_[item2.name()].push_back(&item2); + } + for (auto&& item3 : item2.item_map()) { + auto k1 = item3.first; + for (auto&& item4 : item3.second.attr_list()) { + { + // Index: CountryItemAttrName + index_attr_map_[item4.name()].push_back(&item4); + } + } + } + } + } + // OrderedIndex init. + ordered_index_item_map_.clear(); + for (auto&& item1 : data_.fruit_list()) { + for (auto&& item2 : item1.country_list()) { + for (auto&& item3 : item2.item_map()) { + auto k1 = item3.first; + { + // OrderedIndex: CountryItemPrice + ordered_index_item_map_[item3.second.price()].push_back(&item3.second); + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + auto ordered_index_item_map_sorter = [](const protoconf::Fruit3Conf::Fruit::Country::Item* a, + const protoconf::Fruit3Conf::Fruit::Country::Item* b) { + return a->id() < b->id(); + }; + for (auto&& item : ordered_index_item_map_) { + std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); + } + return true; +} + +// Index: CountryName +const Fruit3Conf::Index_CountryMap& Fruit3Conf::FindCountryMap() const { return index_country_map_ ;} + +const Fruit3Conf::Index_CountryVector* Fruit3Conf::FindCountry(const std::string& name) const { + auto iter = index_country_map_.find(name); + if (iter == index_country_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit3Conf::Fruit::Country* Fruit3Conf::FindFirstCountry(const std::string& name) const { + auto conf = FindCountry(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// Index: CountryItemAttrName +const Fruit3Conf::Index_AttrMap& Fruit3Conf::FindAttrMap() const { return index_attr_map_ ;} + +const Fruit3Conf::Index_AttrVector* Fruit3Conf::FindAttr(const std::string& name) const { + auto iter = index_attr_map_.find(name); + if (iter == index_attr_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit3Conf::Fruit::Country::Item::Attr* Fruit3Conf::FindFirstAttr(const std::string& name) const { + auto conf = FindAttr(name); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +// OrderedIndex: CountryItemPrice +const Fruit3Conf::OrderedIndex_ItemMap& Fruit3Conf::FindItemMap() const { return ordered_index_item_map_ ;} + +const Fruit3Conf::OrderedIndex_ItemVector* Fruit3Conf::FindItem(int32_t price) const { + auto iter = ordered_index_item_map_.find(price); + if (iter == ordered_index_item_map_.end()) { + return nullptr; + } + return &iter->second; +} + +const protoconf::Fruit3Conf::Fruit::Country::Item* Fruit3Conf::FindFirstItem(int32_t price) const { + auto conf = FindItem(price); + if (conf == nullptr || conf->empty()) { + return nullptr; + } + return conf->front(); +} + +} // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h new file mode 100644 index 00000000..2aed90c4 --- /dev/null +++ b/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h @@ -0,0 +1,213 @@ +// Code generated by protoc-gen-cpp-tableau-loader. DO NOT EDIT. +// versions: +// - protoc-gen-cpp-tableau-loader v0.10.1 +// - protoc v3.19.3 +// source: index_conf.proto + +#pragma once +#include +#include + +#include "load.pc.h" +#include "util.pc.h" +#include "index_conf.pb.h" + +namespace tableau { +class FruitConf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; + const protoconf::FruitConf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + public: + const protoconf::FruitConf::Fruit* Get(int32_t fruit_type) const; + const protoconf::FruitConf::Fruit::Item* Get(int32_t fruit_type, int32_t id) const; + + private: + static const std::string kProtoName; + protoconf::FruitConf data_; + + // OrderedIndex accessers. + // OrderedIndex: Price + public: + using OrderedIndex_ItemVector = std::vector; + using OrderedIndex_ItemMap = std::map; + // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap& FindItemMap() const; + // Finds a vector of all values of the given key(s). + const OrderedIndex_ItemVector* FindItem(int32_t price) const; + // Finds the first value of the given key(s). + const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t price) const; + // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map + // specified by (fruit_type). + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; + // Finds a vector of all values of the given key(s) specified by (fruit_type). + const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; + // Finds the first value of the given key(s) specified by (fruit_type). + const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; + + private: + OrderedIndex_ItemMap ordered_index_item_map_; + std::unordered_map ordered_index_item_map1_; +}; + +class Fruit2Conf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; + const protoconf::Fruit2Conf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + public: + const protoconf::Fruit2Conf::Fruit* Get(int32_t fruit_type) const; + + private: + static const std::string kProtoName; + protoconf::Fruit2Conf data_; + + // Index accessers. + // Index: CountryName + public: + using Index_CountryVector = std::vector; + using Index_CountryMap = std::unordered_map; + // Finds the index (CountryName) to value (Index_CountryVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_CountryMap& FindCountryMap() const; + // Finds a vector of all values of the given key(s). + const Index_CountryVector* FindCountry(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit2Conf::Fruit::Country* FindFirstCountry(const std::string& name) const; + + private: + Index_CountryMap index_country_map_; + + // Index: CountryItemAttrName + public: + using Index_AttrVector = std::vector; + using Index_AttrMap = std::unordered_map; + // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_AttrMap& FindAttrMap() const; + // Finds a vector of all values of the given key(s). + const Index_AttrVector* FindAttr(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; + // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map + // specified by (fruit_type). + // One key may correspond to multiple values, which are contained by a vector. + const Index_AttrMap* FindAttrMap(int32_t fruit_type) const; + // Finds a vector of all values of the given key(s) specified by (fruit_type). + const Index_AttrVector* FindAttr(int32_t fruit_type, const std::string& name) const; + // Finds the first value of the given key(s) specified by (fruit_type). + const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(int32_t fruit_type, const std::string& name) const; + + private: + Index_AttrMap index_attr_map_; + std::unordered_map index_attr_map1_; + + // OrderedIndex accessers. + // OrderedIndex: CountryItemPrice + public: + using OrderedIndex_ItemVector = std::vector; + using OrderedIndex_ItemMap = std::map; + // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap& FindItemMap() const; + // Finds a vector of all values of the given key(s). + const OrderedIndex_ItemVector* FindItem(int32_t price) const; + // Finds the first value of the given key(s). + const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; + // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map + // specified by (fruit_type). + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; + // Finds a vector of all values of the given key(s) specified by (fruit_type). + const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; + // Finds the first value of the given key(s) specified by (fruit_type). + const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; + + private: + OrderedIndex_ItemMap ordered_index_item_map_; + std::unordered_map ordered_index_item_map1_; +}; + +class Fruit3Conf : public Messager { + public: + static const std::string& Name() { return kProtoName; } + virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; + const protoconf::Fruit3Conf& Data() const { return data_; } + const google::protobuf::Message* Message() const override { return &data_; } + + private: + virtual bool ProcessAfterLoad() override final; + + + private: + static const std::string kProtoName; + protoconf::Fruit3Conf data_; + + // Index accessers. + // Index: CountryName + public: + using Index_CountryVector = std::vector; + using Index_CountryMap = std::unordered_map; + // Finds the index (CountryName) to value (Index_CountryVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_CountryMap& FindCountryMap() const; + // Finds a vector of all values of the given key(s). + const Index_CountryVector* FindCountry(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit3Conf::Fruit::Country* FindFirstCountry(const std::string& name) const; + + private: + Index_CountryMap index_country_map_; + + // Index: CountryItemAttrName + public: + using Index_AttrVector = std::vector; + using Index_AttrMap = std::unordered_map; + // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. + // One key may correspond to multiple values, which are contained by a vector. + const Index_AttrMap& FindAttrMap() const; + // Finds a vector of all values of the given key(s). + const Index_AttrVector* FindAttr(const std::string& name) const; + // Finds the first value of the given key(s). + const protoconf::Fruit3Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; + + private: + Index_AttrMap index_attr_map_; + + // OrderedIndex accessers. + // OrderedIndex: CountryItemPrice + public: + using OrderedIndex_ItemVector = std::vector; + using OrderedIndex_ItemMap = std::map; + // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are contained by a vector. + const OrderedIndex_ItemMap& FindItemMap() const; + // Finds a vector of all values of the given key(s). + const OrderedIndex_ItemVector* FindItem(int32_t price) const; + // Finds the first value of the given key(s). + const protoconf::Fruit3Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; + + private: + OrderedIndex_ItemMap ordered_index_item_map_; +}; + +} // namespace tableau + +namespace protoconf { +// Here are some type aliases for easy use. +using FruitConfMgr = tableau::FruitConf; +using Fruit2ConfMgr = tableau::Fruit2Conf; +using Fruit3ConfMgr = tableau::Fruit3Conf; +} // namespace protoconf diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc index 94bccbbc..6216a72c 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.cc @@ -383,411 +383,4 @@ const protoconf::ItemConf::Item* ItemConf::FindFirstParamExtType(int32_t param, return conf->front(); } -const std::string FruitConf::kProtoName = protoconf::FruitConf::GetDescriptor()->name(); - -bool FruitConf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { - tableau::util::TimeProfiler profiler; - bool loaded = LoadMessagerInDir(data_, dir, fmt, options); - bool ok = loaded ? ProcessAfterLoad() : false; - stats_.duration = profiler.Elapse(); - return ok; -} - -bool FruitConf::ProcessAfterLoad() { - // OrderedIndex init. - ordered_index_item_map_.clear(); - ordered_index_item_map1_.clear(); - for (auto&& item1 : data_.fruit_map()) { - auto k1 = item1.first; - for (auto&& item2 : item1.second.item_map()) { - auto k2 = item2.first; - { - // OrderedIndex: Price - ordered_index_item_map_[item2.second.price()].push_back(&item2.second); - ordered_index_item_map1_[k1][item2.second.price()].push_back(&item2.second); - } - } - } - // OrderedIndex(sort): Price - auto ordered_index_item_map_sorter = [](const protoconf::FruitConf::Fruit::Item* a, - const protoconf::FruitConf::Fruit::Item* b) { - return a->id() < b->id(); - }; - for (auto&& item : ordered_index_item_map_) { - std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); - } - for (auto&& item : ordered_index_item_map1_) { - for (auto&& item1 : item.second) { - std::sort(item1.second.begin(), item1.second.end(), ordered_index_item_map_sorter); - } - } - return true; -} - -const protoconf::FruitConf::Fruit* FruitConf::Get(int32_t fruit_type) const { - auto iter = data_.fruit_map().find(fruit_type); - if (iter == data_.fruit_map().end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::FruitConf::Fruit::Item* FruitConf::Get(int32_t fruit_type, int32_t id) const { - const auto* conf = Get(fruit_type); - if (conf == nullptr) { - return nullptr; - } - auto iter = conf->item_map().find(id); - if (iter == conf->item_map().end()) { - return nullptr; - } - return &iter->second; -} - -// OrderedIndex: Price -const FruitConf::OrderedIndex_ItemMap& FruitConf::FindItemMap() const { return ordered_index_item_map_ ;} - -const FruitConf::OrderedIndex_ItemVector* FruitConf::FindItem(int32_t price) const { - auto iter = ordered_index_item_map_.find(price); - if (iter == ordered_index_item_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t price) const { - auto conf = FindItem(price); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -const FruitConf::OrderedIndex_ItemMap* FruitConf::FindItemMap(int32_t fruit_type) const { - auto iter = ordered_index_item_map1_.find(fruit_type); - if (iter == ordered_index_item_map1_.end()) { - return nullptr; - } - return &iter->second; -} - -const FruitConf::OrderedIndex_ItemVector* FruitConf::FindItem(int32_t fruit_type, int32_t price) const { - auto map = FindItemMap(fruit_type); - if (map == nullptr) { - return nullptr; - } - auto iter = map->find(price); - if (iter == map->end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::FruitConf::Fruit::Item* FruitConf::FindFirstItem(int32_t fruit_type, int32_t price) const { - auto conf = FindItem(fruit_type, price); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -const std::string Fruit2Conf::kProtoName = protoconf::Fruit2Conf::GetDescriptor()->name(); - -bool Fruit2Conf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { - tableau::util::TimeProfiler profiler; - bool loaded = LoadMessagerInDir(data_, dir, fmt, options); - bool ok = loaded ? ProcessAfterLoad() : false; - stats_.duration = profiler.Elapse(); - return ok; -} - -bool Fruit2Conf::ProcessAfterLoad() { - // Index init. - index_country_map_.clear(); - index_attr_map_.clear(); - index_attr_map1_.clear(); - for (auto&& item1 : data_.fruit_map()) { - auto k1 = item1.first; - for (auto&& item2 : item1.second.country_list()) { - { - // Index: CountryName - index_country_map_[item2.name()].push_back(&item2); - } - for (auto&& item3 : item2.item_map()) { - auto k2 = item3.first; - for (auto&& item4 : item3.second.attr_list()) { - { - // Index: CountryItemAttrName - index_attr_map_[item4.name()].push_back(&item4); - index_attr_map1_[k1][item4.name()].push_back(&item4); - } - } - } - } - } - // OrderedIndex init. - ordered_index_item_map_.clear(); - ordered_index_item_map1_.clear(); - for (auto&& item1 : data_.fruit_map()) { - auto k1 = item1.first; - for (auto&& item2 : item1.second.country_list()) { - for (auto&& item3 : item2.item_map()) { - auto k2 = item3.first; - { - // OrderedIndex: CountryItemPrice - ordered_index_item_map_[item3.second.price()].push_back(&item3.second); - ordered_index_item_map1_[k1][item3.second.price()].push_back(&item3.second); - } - } - } - } - // OrderedIndex(sort): CountryItemPrice - auto ordered_index_item_map_sorter = [](const protoconf::Fruit2Conf::Fruit::Country::Item* a, - const protoconf::Fruit2Conf::Fruit::Country::Item* b) { - return a->id() < b->id(); - }; - for (auto&& item : ordered_index_item_map_) { - std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); - } - for (auto&& item : ordered_index_item_map1_) { - for (auto&& item1 : item.second) { - std::sort(item1.second.begin(), item1.second.end(), ordered_index_item_map_sorter); - } - } - return true; -} - -const protoconf::Fruit2Conf::Fruit* Fruit2Conf::Get(int32_t fruit_type) const { - auto iter = data_.fruit_map().find(fruit_type); - if (iter == data_.fruit_map().end()) { - return nullptr; - } - return &iter->second; -} - -// Index: CountryName -const Fruit2Conf::Index_CountryMap& Fruit2Conf::FindCountryMap() const { return index_country_map_ ;} - -const Fruit2Conf::Index_CountryVector* Fruit2Conf::FindCountry(const std::string& name) const { - auto iter = index_country_map_.find(name); - if (iter == index_country_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit2Conf::Fruit::Country* Fruit2Conf::FindFirstCountry(const std::string& name) const { - auto conf = FindCountry(name); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -// Index: CountryItemAttrName -const Fruit2Conf::Index_AttrMap& Fruit2Conf::FindAttrMap() const { return index_attr_map_ ;} - -const Fruit2Conf::Index_AttrVector* Fruit2Conf::FindAttr(const std::string& name) const { - auto iter = index_attr_map_.find(name); - if (iter == index_attr_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* Fruit2Conf::FindFirstAttr(const std::string& name) const { - auto conf = FindAttr(name); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -const Fruit2Conf::Index_AttrMap* Fruit2Conf::FindAttrMap(int32_t fruit_type) const { - auto iter = index_attr_map1_.find(fruit_type); - if (iter == index_attr_map1_.end()) { - return nullptr; - } - return &iter->second; -} - -const Fruit2Conf::Index_AttrVector* Fruit2Conf::FindAttr(int32_t fruit_type, const std::string& name) const { - auto map = FindAttrMap(fruit_type); - if (map == nullptr) { - return nullptr; - } - auto iter = map->find(name); - if (iter == map->end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* Fruit2Conf::FindFirstAttr(int32_t fruit_type, const std::string& name) const { - auto conf = FindAttr(fruit_type, name); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -// OrderedIndex: CountryItemPrice -const Fruit2Conf::OrderedIndex_ItemMap& Fruit2Conf::FindItemMap() const { return ordered_index_item_map_ ;} - -const Fruit2Conf::OrderedIndex_ItemVector* Fruit2Conf::FindItem(int32_t price) const { - auto iter = ordered_index_item_map_.find(price); - if (iter == ordered_index_item_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int32_t price) const { - auto conf = FindItem(price); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -const Fruit2Conf::OrderedIndex_ItemMap* Fruit2Conf::FindItemMap(int32_t fruit_type) const { - auto iter = ordered_index_item_map1_.find(fruit_type); - if (iter == ordered_index_item_map1_.end()) { - return nullptr; - } - return &iter->second; -} - -const Fruit2Conf::OrderedIndex_ItemVector* Fruit2Conf::FindItem(int32_t fruit_type, int32_t price) const { - auto map = FindItemMap(fruit_type); - if (map == nullptr) { - return nullptr; - } - auto iter = map->find(price); - if (iter == map->end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit2Conf::Fruit::Country::Item* Fruit2Conf::FindFirstItem(int32_t fruit_type, int32_t price) const { - auto conf = FindItem(fruit_type, price); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -const std::string Fruit3Conf::kProtoName = protoconf::Fruit3Conf::GetDescriptor()->name(); - -bool Fruit3Conf::Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options /* = nullptr */) { - tableau::util::TimeProfiler profiler; - bool loaded = LoadMessagerInDir(data_, dir, fmt, options); - bool ok = loaded ? ProcessAfterLoad() : false; - stats_.duration = profiler.Elapse(); - return ok; -} - -bool Fruit3Conf::ProcessAfterLoad() { - // Index init. - index_country_map_.clear(); - index_attr_map_.clear(); - for (auto&& item1 : data_.fruit_list()) { - for (auto&& item2 : item1.country_list()) { - { - // Index: CountryName - index_country_map_[item2.name()].push_back(&item2); - } - for (auto&& item3 : item2.item_map()) { - auto k1 = item3.first; - for (auto&& item4 : item3.second.attr_list()) { - { - // Index: CountryItemAttrName - index_attr_map_[item4.name()].push_back(&item4); - } - } - } - } - } - // OrderedIndex init. - ordered_index_item_map_.clear(); - for (auto&& item1 : data_.fruit_list()) { - for (auto&& item2 : item1.country_list()) { - for (auto&& item3 : item2.item_map()) { - auto k1 = item3.first; - { - // OrderedIndex: CountryItemPrice - ordered_index_item_map_[item3.second.price()].push_back(&item3.second); - } - } - } - } - // OrderedIndex(sort): CountryItemPrice - auto ordered_index_item_map_sorter = [](const protoconf::Fruit3Conf::Fruit::Country::Item* a, - const protoconf::Fruit3Conf::Fruit::Country::Item* b) { - return a->id() < b->id(); - }; - for (auto&& item : ordered_index_item_map_) { - std::sort(item.second.begin(), item.second.end(), ordered_index_item_map_sorter); - } - return true; -} - -// Index: CountryName -const Fruit3Conf::Index_CountryMap& Fruit3Conf::FindCountryMap() const { return index_country_map_ ;} - -const Fruit3Conf::Index_CountryVector* Fruit3Conf::FindCountry(const std::string& name) const { - auto iter = index_country_map_.find(name); - if (iter == index_country_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit3Conf::Fruit::Country* Fruit3Conf::FindFirstCountry(const std::string& name) const { - auto conf = FindCountry(name); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -// Index: CountryItemAttrName -const Fruit3Conf::Index_AttrMap& Fruit3Conf::FindAttrMap() const { return index_attr_map_ ;} - -const Fruit3Conf::Index_AttrVector* Fruit3Conf::FindAttr(const std::string& name) const { - auto iter = index_attr_map_.find(name); - if (iter == index_attr_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit3Conf::Fruit::Country::Item::Attr* Fruit3Conf::FindFirstAttr(const std::string& name) const { - auto conf = FindAttr(name); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - -// OrderedIndex: CountryItemPrice -const Fruit3Conf::OrderedIndex_ItemMap& Fruit3Conf::FindItemMap() const { return ordered_index_item_map_ ;} - -const Fruit3Conf::OrderedIndex_ItemVector* Fruit3Conf::FindItem(int32_t price) const { - auto iter = ordered_index_item_map_.find(price); - if (iter == ordered_index_item_map_.end()) { - return nullptr; - } - return &iter->second; -} - -const protoconf::Fruit3Conf::Fruit::Country::Item* Fruit3Conf::FindFirstItem(int32_t price) const { - auto conf = FindItem(price); - if (conf == nullptr || conf->empty()) { - return nullptr; - } - return conf->front(); -} - } // namespace tableau diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index bad65b05..a7353b6d 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -266,202 +266,9 @@ class ItemConf : public Messager { OrderedIndex_ParamExtTypeMap ordered_index_param_ext_type_map_; }; -class FruitConf : public Messager { - public: - static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; - const protoconf::FruitConf& Data() const { return data_; } - const google::protobuf::Message* Message() const override { return &data_; } - - private: - virtual bool ProcessAfterLoad() override final; - - public: - const protoconf::FruitConf::Fruit* Get(int32_t fruit_type) const; - const protoconf::FruitConf::Fruit::Item* Get(int32_t fruit_type, int32_t id) const; - - private: - static const std::string kProtoName; - protoconf::FruitConf data_; - - // OrderedIndex accessers. - // OrderedIndex: Price - public: - using OrderedIndex_ItemVector = std::vector; - using OrderedIndex_ItemMap = std::map; - // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map. - // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ItemMap& FindItemMap() const; - // Finds a vector of all values of the given key(s). - const OrderedIndex_ItemVector* FindItem(int32_t price) const; - // Finds the first value of the given key(s). - const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t price) const; - // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map - // specified by (fruit_type). - // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; - // Finds a vector of all values of the given key(s) specified by (fruit_type). - const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; - // Finds the first value of the given key(s) specified by (fruit_type). - const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; - - private: - OrderedIndex_ItemMap ordered_index_item_map_; - std::unordered_map ordered_index_item_map1_; -}; - -class Fruit2Conf : public Messager { - public: - static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; - const protoconf::Fruit2Conf& Data() const { return data_; } - const google::protobuf::Message* Message() const override { return &data_; } - - private: - virtual bool ProcessAfterLoad() override final; - - public: - const protoconf::Fruit2Conf::Fruit* Get(int32_t fruit_type) const; - - private: - static const std::string kProtoName; - protoconf::Fruit2Conf data_; - - // Index accessers. - // Index: CountryName - public: - using Index_CountryVector = std::vector; - using Index_CountryMap = std::unordered_map; - // Finds the index (CountryName) to value (Index_CountryVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. - const Index_CountryMap& FindCountryMap() const; - // Finds a vector of all values of the given key(s). - const Index_CountryVector* FindCountry(const std::string& name) const; - // Finds the first value of the given key(s). - const protoconf::Fruit2Conf::Fruit::Country* FindFirstCountry(const std::string& name) const; - - private: - Index_CountryMap index_country_map_; - - // Index: CountryItemAttrName - public: - using Index_AttrVector = std::vector; - using Index_AttrMap = std::unordered_map; - // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. - const Index_AttrMap& FindAttrMap() const; - // Finds a vector of all values of the given key(s). - const Index_AttrVector* FindAttr(const std::string& name) const; - // Finds the first value of the given key(s). - const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; - // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map - // specified by (fruit_type). - // One key may correspond to multiple values, which are contained by a vector. - const Index_AttrMap* FindAttrMap(int32_t fruit_type) const; - // Finds a vector of all values of the given key(s) specified by (fruit_type). - const Index_AttrVector* FindAttr(int32_t fruit_type, const std::string& name) const; - // Finds the first value of the given key(s) specified by (fruit_type). - const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(int32_t fruit_type, const std::string& name) const; - - private: - Index_AttrMap index_attr_map_; - std::unordered_map index_attr_map1_; - - // OrderedIndex accessers. - // OrderedIndex: CountryItemPrice - public: - using OrderedIndex_ItemVector = std::vector; - using OrderedIndex_ItemMap = std::map; - // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. - // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ItemMap& FindItemMap() const; - // Finds a vector of all values of the given key(s). - const OrderedIndex_ItemVector* FindItem(int32_t price) const; - // Finds the first value of the given key(s). - const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; - // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map - // specified by (fruit_type). - // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; - // Finds a vector of all values of the given key(s) specified by (fruit_type). - const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; - // Finds the first value of the given key(s) specified by (fruit_type). - const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; - - private: - OrderedIndex_ItemMap ordered_index_item_map_; - std::unordered_map ordered_index_item_map1_; -}; - -class Fruit3Conf : public Messager { - public: - static const std::string& Name() { return kProtoName; } - virtual bool Load(const std::filesystem::path& dir, Format fmt, std::shared_ptr options = nullptr) override; - const protoconf::Fruit3Conf& Data() const { return data_; } - const google::protobuf::Message* Message() const override { return &data_; } - - private: - virtual bool ProcessAfterLoad() override final; - - - private: - static const std::string kProtoName; - protoconf::Fruit3Conf data_; - - // Index accessers. - // Index: CountryName - public: - using Index_CountryVector = std::vector; - using Index_CountryMap = std::unordered_map; - // Finds the index (CountryName) to value (Index_CountryVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. - const Index_CountryMap& FindCountryMap() const; - // Finds a vector of all values of the given key(s). - const Index_CountryVector* FindCountry(const std::string& name) const; - // Finds the first value of the given key(s). - const protoconf::Fruit3Conf::Fruit::Country* FindFirstCountry(const std::string& name) const; - - private: - Index_CountryMap index_country_map_; - - // Index: CountryItemAttrName - public: - using Index_AttrVector = std::vector; - using Index_AttrMap = std::unordered_map; - // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. - const Index_AttrMap& FindAttrMap() const; - // Finds a vector of all values of the given key(s). - const Index_AttrVector* FindAttr(const std::string& name) const; - // Finds the first value of the given key(s). - const protoconf::Fruit3Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; - - private: - Index_AttrMap index_attr_map_; - - // OrderedIndex accessers. - // OrderedIndex: CountryItemPrice - public: - using OrderedIndex_ItemVector = std::vector; - using OrderedIndex_ItemMap = std::map; - // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. - // One key may correspond to multiple values, which are contained by a vector. - const OrderedIndex_ItemMap& FindItemMap() const; - // Finds a vector of all values of the given key(s). - const OrderedIndex_ItemVector* FindItem(int32_t price) const; - // Finds the first value of the given key(s). - const protoconf::Fruit3Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; - - private: - OrderedIndex_ItemMap ordered_index_item_map_; -}; - } // namespace tableau namespace protoconf { // Here are some type aliases for easy use. using ItemConfMgr = tableau::ItemConf; -using FruitConfMgr = tableau::FruitConf; -using Fruit2ConfMgr = tableau::Fruit2Conf; -using Fruit3ConfMgr = tableau::Fruit3Conf; } // namespace protoconf diff --git a/test/go-tableau-loader/protoconf/loader/hub.pc.go b/test/go-tableau-loader/protoconf/loader/hub.pc.go index 4e53ea25..39e845f3 100644 --- a/test/go-tableau-loader/protoconf/loader/hub.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hub.pc.go @@ -220,10 +220,6 @@ func (h *Hub) GetHeroBaseConf() *HeroBaseConf { return h.mc.Load().GetHeroBaseConf() } -func (h *Hub) GetItemConf() *ItemConf { - return h.mc.Load().GetItemConf() -} - func (h *Hub) GetFruitConf() *FruitConf { return h.mc.Load().GetFruitConf() } @@ -236,6 +232,10 @@ func (h *Hub) GetFruit3Conf() *Fruit3Conf { return h.mc.Load().GetFruit3Conf() } +func (h *Hub) GetItemConf() *ItemConf { + return h.mc.Load().GetItemConf() +} + func (h *Hub) GetPatchReplaceConf() *PatchReplaceConf { return h.mc.Load().GetPatchReplaceConf() } diff --git a/test/go-tableau-loader/protoconf/loader/index_conf.pc.go b/test/go-tableau-loader/protoconf/loader/index_conf.pc.go new file mode 100644 index 00000000..85387754 --- /dev/null +++ b/test/go-tableau-loader/protoconf/loader/index_conf.pc.go @@ -0,0 +1,701 @@ +// Code generated by protoc-gen-go-tableau-loader. DO NOT EDIT. +// versions: +// - protoc-gen-go-tableau-loader v0.10.1 +// - protoc v3.19.3 +// source: index_conf.proto + +package loader + +import ( + fmt "fmt" + treemap "github.com/tableauio/loader/pkg/treemap" + protoconf "github.com/tableauio/loader/test/go-tableau-loader/protoconf" + format "github.com/tableauio/tableau/format" + load "github.com/tableauio/tableau/load" + store "github.com/tableauio/tableau/store" + proto "google.golang.org/protobuf/proto" + sort "sort" + time "time" +) + +// OrderedIndex types. +// OrderedIndex: Price +type FruitConf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.FruitConf_Fruit_Item] + +// FruitConf is a wrapper around protobuf message: protoconf.FruitConf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... +type FruitConf struct { + UnimplementedMessager + data, originalData *protoconf.FruitConf + orderedIndexItemMap *FruitConf_OrderedIndex_ItemMap + orderedIndexItemMap1 map[int32]*FruitConf_OrderedIndex_ItemMap +} + +// Name returns the FruitConf's message name. +func (x *FruitConf) Name() string { + return string((*protoconf.FruitConf)(nil).ProtoReflect().Descriptor().Name()) +} + +// Data returns the FruitConf's inner message data. +func (x *FruitConf) Data() *protoconf.FruitConf { + if x != nil { + return x.data + } + return nil +} + +// Load fills FruitConf's inner message from file in the specified directory and format. +func (x *FruitConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.FruitConf{} + err := load.LoadMessagerInDir(x.data, dir, format, opts) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.FruitConf) + } + return x.processAfterLoad() +} + +// Store writes FruitConf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *FruitConf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the FruitConf's inner message data. +func (x *FruitConf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *FruitConf) Messager() Messager { + return x +} + +// originalMessage returns the FruitConf's original inner message. +func (x *FruitConf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *FruitConf) processAfterLoad() error { + // OrderedIndex init. + x.orderedIndexItemMap = treemap.New[int32, []*protoconf.FruitConf_Fruit_Item]() + x.orderedIndexItemMap1 = make(map[int32]*FruitConf_OrderedIndex_ItemMap) + for k1, v1 := range x.data.GetFruitMap() { + _ = k1 + for k2, v2 := range v1.GetItemMap() { + _ = k2 + { + // OrderedIndex: Price + key := v2.GetPrice() + value, _ := x.orderedIndexItemMap.Get(key) + x.orderedIndexItemMap.Put(key, append(value, v2)) + if x.orderedIndexItemMap1[k1] == nil { + x.orderedIndexItemMap1[k1] = treemap.New[int32, []*protoconf.FruitConf_Fruit_Item]() + } + orderedIndexItemMap1Value, _ := x.orderedIndexItemMap1[k1].Get(key) + x.orderedIndexItemMap1[k1].Put(key, append(orderedIndexItemMap1Value, v2)) + } + } + } + // OrderedIndex(sort): Price + orderedIndexItemMapSorter := func(itemList []*protoconf.FruitConf_Fruit_Item) func(i, j int) bool { + return func(i, j int) bool { + return itemList[i].GetId() < itemList[j].GetId() + } + } + x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.FruitConf_Fruit_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) + return true + }) + for _, itemMap := range x.orderedIndexItemMap1 { + itemMap.Range(func(key int32, itemList []*protoconf.FruitConf_Fruit_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) + return true + }) + } + return nil +} + +// Get1 finds value in the 1-level map. It will return +// NotFound error if the key is not found. +func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruit, error) { + d := x.Data().GetFruitMap() + if val, ok := d[fruitType]; !ok { + return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) + } else { + return val, nil + } +} + +// Get2 finds value in the 2-level map. It will return +// NotFound error if the key is not found. +func (x *FruitConf) Get2(fruitType int32, id int32) (*protoconf.FruitConf_Fruit_Item, error) { + conf, err := x.Get1(fruitType) + if err != nil { + return nil, err + } + d := conf.GetItemMap() + if val, ok := d[id]; !ok { + return nil, fmt.Errorf("id(%v) %w", id, ErrNotFound) + } else { + return val, nil + } +} + +// OrderedIndex: Price + +// FindItemMap finds the ordered index (Price) to value (protoconf.FruitConf_Fruit_Item) treemap. +// One key may correspond to multiple values, which are contained by a slice. +func (x *FruitConf) FindItemMap() *FruitConf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap +} + +// FindItem finds a slice of all values of the given key. +func (x *FruitConf) FindItem(price int32) []*protoconf.FruitConf_Fruit_Item { + val, _ := x.orderedIndexItemMap.Get(price) + return val +} + +// FindFirstItem finds the first value of the given key, +// or nil if no value found. +func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { + val := x.FindItem(price) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindItemMap1 finds the index (Price) to value (protoconf.FruitConf_Fruit_Item) 1-level treemap +// specified by (fruitType). +// One key may correspond to multiple values, which are contained by a slice. +func (x *FruitConf) FindItemMap1(fruitType int32) *FruitConf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap1[fruitType] +} + +// FindItem1 finds a slice of all values of the given key in the 1-level treemap +// specified by (fruitType). +func (x *FruitConf) FindItem1(fruitType int32, price int32) []*protoconf.FruitConf_Fruit_Item { + val, _ := x.FindItemMap1(fruitType).Get(price) + return val +} + +// FindFirstItem1 finds the first value of the given key in the 1-level treemap +// specified by (fruitType), or nil if no value found. +func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.FruitConf_Fruit_Item { + val := x.FindItem1(fruitType, price) + if len(val) > 0 { + return val[0] + } + return nil +} + +// Index types. +// Index: CountryName +type Fruit2Conf_Index_CountryMap = map[string][]*protoconf.Fruit2Conf_Fruit_Country + +// Index: CountryItemAttrName +type Fruit2Conf_Index_AttrMap = map[string][]*protoconf.Fruit2Conf_Fruit_Country_Item_Attr + +// OrderedIndex types. +// OrderedIndex: CountryItemPrice +type Fruit2Conf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item] + +// Fruit2Conf is a wrapper around protobuf message: protoconf.Fruit2Conf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... +type Fruit2Conf struct { + UnimplementedMessager + data, originalData *protoconf.Fruit2Conf + indexCountryMap Fruit2Conf_Index_CountryMap + indexAttrMap Fruit2Conf_Index_AttrMap + indexAttrMap1 map[int32]Fruit2Conf_Index_AttrMap + orderedIndexItemMap *Fruit2Conf_OrderedIndex_ItemMap + orderedIndexItemMap1 map[int32]*Fruit2Conf_OrderedIndex_ItemMap +} + +// Name returns the Fruit2Conf's message name. +func (x *Fruit2Conf) Name() string { + return string((*protoconf.Fruit2Conf)(nil).ProtoReflect().Descriptor().Name()) +} + +// Data returns the Fruit2Conf's inner message data. +func (x *Fruit2Conf) Data() *protoconf.Fruit2Conf { + if x != nil { + return x.data + } + return nil +} + +// Load fills Fruit2Conf's inner message from file in the specified directory and format. +func (x *Fruit2Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.Fruit2Conf{} + err := load.LoadMessagerInDir(x.data, dir, format, opts) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.Fruit2Conf) + } + return x.processAfterLoad() +} + +// Store writes Fruit2Conf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *Fruit2Conf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the Fruit2Conf's inner message data. +func (x *Fruit2Conf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *Fruit2Conf) Messager() Messager { + return x +} + +// originalMessage returns the Fruit2Conf's original inner message. +func (x *Fruit2Conf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *Fruit2Conf) processAfterLoad() error { + // Index init. + x.indexCountryMap = make(Fruit2Conf_Index_CountryMap) + x.indexAttrMap = make(Fruit2Conf_Index_AttrMap) + x.indexAttrMap1 = make(map[int32]Fruit2Conf_Index_AttrMap) + for k1, v1 := range x.data.GetFruitMap() { + _ = k1 + for _, v2 := range v1.GetCountryList() { + { + // Index: CountryName + key := v2.GetName() + x.indexCountryMap[key] = append(x.indexCountryMap[key], v2) + } + for k2, v3 := range v2.GetItemMap() { + _ = k2 + for _, v4 := range v3.GetAttrList() { + { + // Index: CountryItemAttrName + key := v4.GetName() + x.indexAttrMap[key] = append(x.indexAttrMap[key], v4) + if x.indexAttrMap1[k1] == nil { + x.indexAttrMap1[k1] = make(Fruit2Conf_Index_AttrMap) + } + x.indexAttrMap1[k1][key] = append(x.indexAttrMap1[k1][key], v4) + } + } + } + } + } + // OrderedIndex init. + x.orderedIndexItemMap = treemap.New[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item]() + x.orderedIndexItemMap1 = make(map[int32]*Fruit2Conf_OrderedIndex_ItemMap) + for k1, v1 := range x.data.GetFruitMap() { + _ = k1 + for _, v2 := range v1.GetCountryList() { + for k2, v3 := range v2.GetItemMap() { + _ = k2 + { + // OrderedIndex: CountryItemPrice + key := v3.GetPrice() + value, _ := x.orderedIndexItemMap.Get(key) + x.orderedIndexItemMap.Put(key, append(value, v3)) + if x.orderedIndexItemMap1[k1] == nil { + x.orderedIndexItemMap1[k1] = treemap.New[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item]() + } + orderedIndexItemMap1Value, _ := x.orderedIndexItemMap1[k1].Get(key) + x.orderedIndexItemMap1[k1].Put(key, append(orderedIndexItemMap1Value, v3)) + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + orderedIndexItemMapSorter := func(itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) func(i, j int) bool { + return func(i, j int) bool { + return itemList[i].GetId() < itemList[j].GetId() + } + } + x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) + return true + }) + for _, itemMap := range x.orderedIndexItemMap1 { + itemMap.Range(func(key int32, itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) + return true + }) + } + return nil +} + +// Get1 finds value in the 1-level map. It will return +// NotFound error if the key is not found. +func (x *Fruit2Conf) Get1(fruitType int32) (*protoconf.Fruit2Conf_Fruit, error) { + d := x.Data().GetFruitMap() + if val, ok := d[fruitType]; !ok { + return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) + } else { + return val, nil + } +} + +// Index: CountryName + +// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit2Conf_Fruit_Country) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindCountryMap() Fruit2Conf_Index_CountryMap { + return x.indexCountryMap +} + +// FindCountry finds a slice of all values of the given key. +func (x *Fruit2Conf) FindCountry(name string) []*protoconf.Fruit2Conf_Fruit_Country { + return x.indexCountryMap[name] +} + +// FindFirstCountry finds the first value of the given key, +// or nil if no value found. +func (x *Fruit2Conf) FindFirstCountry(name string) *protoconf.Fruit2Conf_Fruit_Country { + val := x.FindCountry(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// Index: CountryItemAttrName + +// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindAttrMap() Fruit2Conf_Index_AttrMap { + return x.indexAttrMap +} + +// FindAttr finds a slice of all values of the given key. +func (x *Fruit2Conf) FindAttr(name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + return x.indexAttrMap[name] +} + +// FindFirstAttr finds the first value of the given key, +// or nil if no value found. +func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + val := x.FindAttr(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindAttrMap1 finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) 1-level map +// specified by (fruitType). +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindAttrMap1(fruitType int32) Fruit2Conf_Index_AttrMap { + return x.indexAttrMap1[fruitType] +} + +// FindAttr1 finds a slice of all values of the given key in the 1-level map +// specified by (fruitType). +func (x *Fruit2Conf) FindAttr1(fruitType int32, name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + return x.FindAttrMap1(fruitType)[name] +} + +// FindFirstAttr1 finds the first value of the given key in the 1-level map +// specified by (fruitType), or nil if no value found. +func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { + val := x.FindAttr1(fruitType, name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// OrderedIndex: CountryItemPrice + +// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindItemMap() *Fruit2Conf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap +} + +// FindItem finds a slice of all values of the given key. +func (x *Fruit2Conf) FindItem(price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { + val, _ := x.orderedIndexItemMap.Get(price) + return val +} + +// FindFirstItem finds the first value of the given key, +// or nil if no value found. +func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { + val := x.FindItem(price) + if len(val) > 0 { + return val[0] + } + return nil +} + +// FindItemMap1 finds the index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) 1-level treemap +// specified by (fruitType). +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit2Conf) FindItemMap1(fruitType int32) *Fruit2Conf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap1[fruitType] +} + +// FindItem1 finds a slice of all values of the given key in the 1-level treemap +// specified by (fruitType). +func (x *Fruit2Conf) FindItem1(fruitType int32, price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { + val, _ := x.FindItemMap1(fruitType).Get(price) + return val +} + +// FindFirstItem1 finds the first value of the given key in the 1-level treemap +// specified by (fruitType), or nil if no value found. +func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { + val := x.FindItem1(fruitType, price) + if len(val) > 0 { + return val[0] + } + return nil +} + +// Index types. +// Index: CountryName +type Fruit3Conf_Index_CountryMap = map[string][]*protoconf.Fruit3Conf_Fruit_Country + +// Index: CountryItemAttrName +type Fruit3Conf_Index_AttrMap = map[string][]*protoconf.Fruit3Conf_Fruit_Country_Item_Attr + +// OrderedIndex types. +// OrderedIndex: CountryItemPrice +type Fruit3Conf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.Fruit3Conf_Fruit_Country_Item] + +// Fruit3Conf is a wrapper around protobuf message: protoconf.Fruit3Conf. +// +// It is designed for three goals: +// +// 1. Easy use: simple yet powerful accessers. +// 2. Elegant API: concise and clean functions. +// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... +type Fruit3Conf struct { + UnimplementedMessager + data, originalData *protoconf.Fruit3Conf + indexCountryMap Fruit3Conf_Index_CountryMap + indexAttrMap Fruit3Conf_Index_AttrMap + orderedIndexItemMap *Fruit3Conf_OrderedIndex_ItemMap +} + +// Name returns the Fruit3Conf's message name. +func (x *Fruit3Conf) Name() string { + return string((*protoconf.Fruit3Conf)(nil).ProtoReflect().Descriptor().Name()) +} + +// Data returns the Fruit3Conf's inner message data. +func (x *Fruit3Conf) Data() *protoconf.Fruit3Conf { + if x != nil { + return x.data + } + return nil +} + +// Load fills Fruit3Conf's inner message from file in the specified directory and format. +func (x *Fruit3Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { + start := time.Now() + defer func() { + x.Stats.Duration = time.Since(start) + }() + x.data = &protoconf.Fruit3Conf{} + err := load.LoadMessagerInDir(x.data, dir, format, opts) + if err != nil { + return err + } + if x.backup { + x.originalData = proto.Clone(x.data).(*protoconf.Fruit3Conf) + } + return x.processAfterLoad() +} + +// Store writes Fruit3Conf's inner message to file in the specified directory and format. +// Available formats: JSON, Bin, and Text. +func (x *Fruit3Conf) Store(dir string, format format.Format, options ...store.Option) error { + return store.Store(x.Data(), dir, format, options...) +} + +// Message returns the Fruit3Conf's inner message data. +func (x *Fruit3Conf) Message() proto.Message { + return x.Data() +} + +// Messager returns the current messager. +func (x *Fruit3Conf) Messager() Messager { + return x +} + +// originalMessage returns the Fruit3Conf's original inner message. +func (x *Fruit3Conf) originalMessage() proto.Message { + if x != nil { + return x.originalData + } + return nil +} + +// processAfterLoad runs after this messager is loaded. +func (x *Fruit3Conf) processAfterLoad() error { + // Index init. + x.indexCountryMap = make(Fruit3Conf_Index_CountryMap) + x.indexAttrMap = make(Fruit3Conf_Index_AttrMap) + for _, v1 := range x.data.GetFruitList() { + for _, v2 := range v1.GetCountryList() { + { + // Index: CountryName + key := v2.GetName() + x.indexCountryMap[key] = append(x.indexCountryMap[key], v2) + } + for k1, v3 := range v2.GetItemMap() { + _ = k1 + for _, v4 := range v3.GetAttrList() { + { + // Index: CountryItemAttrName + key := v4.GetName() + x.indexAttrMap[key] = append(x.indexAttrMap[key], v4) + } + } + } + } + } + // OrderedIndex init. + x.orderedIndexItemMap = treemap.New[int32, []*protoconf.Fruit3Conf_Fruit_Country_Item]() + for _, v1 := range x.data.GetFruitList() { + for _, v2 := range v1.GetCountryList() { + for k1, v3 := range v2.GetItemMap() { + _ = k1 + { + // OrderedIndex: CountryItemPrice + key := v3.GetPrice() + value, _ := x.orderedIndexItemMap.Get(key) + x.orderedIndexItemMap.Put(key, append(value, v3)) + } + } + } + } + // OrderedIndex(sort): CountryItemPrice + orderedIndexItemMapSorter := func(itemList []*protoconf.Fruit3Conf_Fruit_Country_Item) func(i, j int) bool { + return func(i, j int) bool { + return itemList[i].GetId() < itemList[j].GetId() + } + } + x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.Fruit3Conf_Fruit_Country_Item) bool { + sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) + return true + }) + return nil +} + +// Index: CountryName + +// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit3Conf_Fruit_Country) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit3Conf) FindCountryMap() Fruit3Conf_Index_CountryMap { + return x.indexCountryMap +} + +// FindCountry finds a slice of all values of the given key. +func (x *Fruit3Conf) FindCountry(name string) []*protoconf.Fruit3Conf_Fruit_Country { + return x.indexCountryMap[name] +} + +// FindFirstCountry finds the first value of the given key, +// or nil if no value found. +func (x *Fruit3Conf) FindFirstCountry(name string) *protoconf.Fruit3Conf_Fruit_Country { + val := x.FindCountry(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// Index: CountryItemAttrName + +// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit3Conf) FindAttrMap() Fruit3Conf_Index_AttrMap { + return x.indexAttrMap +} + +// FindAttr finds a slice of all values of the given key. +func (x *Fruit3Conf) FindAttr(name string) []*protoconf.Fruit3Conf_Fruit_Country_Item_Attr { + return x.indexAttrMap[name] +} + +// FindFirstAttr finds the first value of the given key, +// or nil if no value found. +func (x *Fruit3Conf) FindFirstAttr(name string) *protoconf.Fruit3Conf_Fruit_Country_Item_Attr { + val := x.FindAttr(name) + if len(val) > 0 { + return val[0] + } + return nil +} + +// OrderedIndex: CountryItemPrice + +// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit3Conf_Fruit_Country_Item) treemap. +// One key may correspond to multiple values, which are contained by a slice. +func (x *Fruit3Conf) FindItemMap() *Fruit3Conf_OrderedIndex_ItemMap { + return x.orderedIndexItemMap +} + +// FindItem finds a slice of all values of the given key. +func (x *Fruit3Conf) FindItem(price int32) []*protoconf.Fruit3Conf_Fruit_Country_Item { + val, _ := x.orderedIndexItemMap.Get(price) + return val +} + +// FindFirstItem finds the first value of the given key, +// or nil if no value found. +func (x *Fruit3Conf) FindFirstItem(price int32) *protoconf.Fruit3Conf_Fruit_Country_Item { + val := x.FindItem(price) + if len(val) > 0 { + return val[0] + } + return nil +} + +func init() { + Register(func() Messager { + return new(FruitConf) + }) + Register(func() Messager { + return new(Fruit2Conf) + }) + Register(func() Messager { + return new(Fruit3Conf) + }) +} diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index 4cb2c180..ab50b2c2 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -594,687 +594,8 @@ func (x *ItemConf) FindFirstParamExtType(param int32, extType protoconf.FruitTyp return nil } -// OrderedIndex types. -// OrderedIndex: Price -type FruitConf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.FruitConf_Fruit_Item] - -// FruitConf is a wrapper around protobuf message: protoconf.FruitConf. -// -// It is designed for three goals: -// -// 1. Easy use: simple yet powerful accessers. -// 2. Elegant API: concise and clean functions. -// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... -type FruitConf struct { - UnimplementedMessager - data, originalData *protoconf.FruitConf - orderedIndexItemMap *FruitConf_OrderedIndex_ItemMap - orderedIndexItemMap1 map[int32]*FruitConf_OrderedIndex_ItemMap -} - -// Name returns the FruitConf's message name. -func (x *FruitConf) Name() string { - return string((*protoconf.FruitConf)(nil).ProtoReflect().Descriptor().Name()) -} - -// Data returns the FruitConf's inner message data. -func (x *FruitConf) Data() *protoconf.FruitConf { - if x != nil { - return x.data - } - return nil -} - -// Load fills FruitConf's inner message from file in the specified directory and format. -func (x *FruitConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { - start := time.Now() - defer func() { - x.Stats.Duration = time.Since(start) - }() - x.data = &protoconf.FruitConf{} - err := load.LoadMessagerInDir(x.data, dir, format, opts) - if err != nil { - return err - } - if x.backup { - x.originalData = proto.Clone(x.data).(*protoconf.FruitConf) - } - return x.processAfterLoad() -} - -// Store writes FruitConf's inner message to file in the specified directory and format. -// Available formats: JSON, Bin, and Text. -func (x *FruitConf) Store(dir string, format format.Format, options ...store.Option) error { - return store.Store(x.Data(), dir, format, options...) -} - -// Message returns the FruitConf's inner message data. -func (x *FruitConf) Message() proto.Message { - return x.Data() -} - -// Messager returns the current messager. -func (x *FruitConf) Messager() Messager { - return x -} - -// originalMessage returns the FruitConf's original inner message. -func (x *FruitConf) originalMessage() proto.Message { - if x != nil { - return x.originalData - } - return nil -} - -// processAfterLoad runs after this messager is loaded. -func (x *FruitConf) processAfterLoad() error { - // OrderedIndex init. - x.orderedIndexItemMap = treemap.New[int32, []*protoconf.FruitConf_Fruit_Item]() - x.orderedIndexItemMap1 = make(map[int32]*FruitConf_OrderedIndex_ItemMap) - for k1, v1 := range x.data.GetFruitMap() { - _ = k1 - for k2, v2 := range v1.GetItemMap() { - _ = k2 - { - // OrderedIndex: Price - key := v2.GetPrice() - value, _ := x.orderedIndexItemMap.Get(key) - x.orderedIndexItemMap.Put(key, append(value, v2)) - if x.orderedIndexItemMap1[k1] == nil { - x.orderedIndexItemMap1[k1] = treemap.New[int32, []*protoconf.FruitConf_Fruit_Item]() - } - orderedIndexItemMap1Value, _ := x.orderedIndexItemMap1[k1].Get(key) - x.orderedIndexItemMap1[k1].Put(key, append(orderedIndexItemMap1Value, v2)) - } - } - } - // OrderedIndex(sort): Price - orderedIndexItemMapSorter := func(itemList []*protoconf.FruitConf_Fruit_Item) func(i, j int) bool { - return func(i, j int) bool { - return itemList[i].GetId() < itemList[j].GetId() - } - } - x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.FruitConf_Fruit_Item) bool { - sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) - return true - }) - for _, itemMap := range x.orderedIndexItemMap1 { - itemMap.Range(func(key int32, itemList []*protoconf.FruitConf_Fruit_Item) bool { - sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) - return true - }) - } - return nil -} - -// Get1 finds value in the 1-level map. It will return -// NotFound error if the key is not found. -func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruit, error) { - d := x.Data().GetFruitMap() - if val, ok := d[fruitType]; !ok { - return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) - } else { - return val, nil - } -} - -// Get2 finds value in the 2-level map. It will return -// NotFound error if the key is not found. -func (x *FruitConf) Get2(fruitType int32, id int32) (*protoconf.FruitConf_Fruit_Item, error) { - conf, err := x.Get1(fruitType) - if err != nil { - return nil, err - } - d := conf.GetItemMap() - if val, ok := d[id]; !ok { - return nil, fmt.Errorf("id(%v) %w", id, ErrNotFound) - } else { - return val, nil - } -} - -// OrderedIndex: Price - -// FindItemMap finds the ordered index (Price) to value (protoconf.FruitConf_Fruit_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. -func (x *FruitConf) FindItemMap() *FruitConf_OrderedIndex_ItemMap { - return x.orderedIndexItemMap -} - -// FindItem finds a slice of all values of the given key. -func (x *FruitConf) FindItem(price int32) []*protoconf.FruitConf_Fruit_Item { - val, _ := x.orderedIndexItemMap.Get(price) - return val -} - -// FindFirstItem finds the first value of the given key, -// or nil if no value found. -func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { - val := x.FindItem(price) - if len(val) > 0 { - return val[0] - } - return nil -} - -// FindItemMap1 finds the index (Price) to value (protoconf.FruitConf_Fruit_Item) 1-level treemap -// specified by (fruitType). -// One key may correspond to multiple values, which are contained by a slice. -func (x *FruitConf) FindItemMap1(fruitType int32) *FruitConf_OrderedIndex_ItemMap { - return x.orderedIndexItemMap1[fruitType] -} - -// FindItem1 finds a slice of all values of the given key in the 1-level treemap -// specified by (fruitType). -func (x *FruitConf) FindItem1(fruitType int32, price int32) []*protoconf.FruitConf_Fruit_Item { - val, _ := x.FindItemMap1(fruitType).Get(price) - return val -} - -// FindFirstItem1 finds the first value of the given key in the 1-level treemap -// specified by (fruitType), or nil if no value found. -func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.FruitConf_Fruit_Item { - val := x.FindItem1(fruitType, price) - if len(val) > 0 { - return val[0] - } - return nil -} - -// Index types. -// Index: CountryName -type Fruit2Conf_Index_CountryMap = map[string][]*protoconf.Fruit2Conf_Fruit_Country - -// Index: CountryItemAttrName -type Fruit2Conf_Index_AttrMap = map[string][]*protoconf.Fruit2Conf_Fruit_Country_Item_Attr - -// OrderedIndex types. -// OrderedIndex: CountryItemPrice -type Fruit2Conf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item] - -// Fruit2Conf is a wrapper around protobuf message: protoconf.Fruit2Conf. -// -// It is designed for three goals: -// -// 1. Easy use: simple yet powerful accessers. -// 2. Elegant API: concise and clean functions. -// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... -type Fruit2Conf struct { - UnimplementedMessager - data, originalData *protoconf.Fruit2Conf - indexCountryMap Fruit2Conf_Index_CountryMap - indexAttrMap Fruit2Conf_Index_AttrMap - indexAttrMap1 map[int32]Fruit2Conf_Index_AttrMap - orderedIndexItemMap *Fruit2Conf_OrderedIndex_ItemMap - orderedIndexItemMap1 map[int32]*Fruit2Conf_OrderedIndex_ItemMap -} - -// Name returns the Fruit2Conf's message name. -func (x *Fruit2Conf) Name() string { - return string((*protoconf.Fruit2Conf)(nil).ProtoReflect().Descriptor().Name()) -} - -// Data returns the Fruit2Conf's inner message data. -func (x *Fruit2Conf) Data() *protoconf.Fruit2Conf { - if x != nil { - return x.data - } - return nil -} - -// Load fills Fruit2Conf's inner message from file in the specified directory and format. -func (x *Fruit2Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { - start := time.Now() - defer func() { - x.Stats.Duration = time.Since(start) - }() - x.data = &protoconf.Fruit2Conf{} - err := load.LoadMessagerInDir(x.data, dir, format, opts) - if err != nil { - return err - } - if x.backup { - x.originalData = proto.Clone(x.data).(*protoconf.Fruit2Conf) - } - return x.processAfterLoad() -} - -// Store writes Fruit2Conf's inner message to file in the specified directory and format. -// Available formats: JSON, Bin, and Text. -func (x *Fruit2Conf) Store(dir string, format format.Format, options ...store.Option) error { - return store.Store(x.Data(), dir, format, options...) -} - -// Message returns the Fruit2Conf's inner message data. -func (x *Fruit2Conf) Message() proto.Message { - return x.Data() -} - -// Messager returns the current messager. -func (x *Fruit2Conf) Messager() Messager { - return x -} - -// originalMessage returns the Fruit2Conf's original inner message. -func (x *Fruit2Conf) originalMessage() proto.Message { - if x != nil { - return x.originalData - } - return nil -} - -// processAfterLoad runs after this messager is loaded. -func (x *Fruit2Conf) processAfterLoad() error { - // Index init. - x.indexCountryMap = make(Fruit2Conf_Index_CountryMap) - x.indexAttrMap = make(Fruit2Conf_Index_AttrMap) - x.indexAttrMap1 = make(map[int32]Fruit2Conf_Index_AttrMap) - for k1, v1 := range x.data.GetFruitMap() { - _ = k1 - for _, v2 := range v1.GetCountryList() { - { - // Index: CountryName - key := v2.GetName() - x.indexCountryMap[key] = append(x.indexCountryMap[key], v2) - } - for k2, v3 := range v2.GetItemMap() { - _ = k2 - for _, v4 := range v3.GetAttrList() { - { - // Index: CountryItemAttrName - key := v4.GetName() - x.indexAttrMap[key] = append(x.indexAttrMap[key], v4) - if x.indexAttrMap1[k1] == nil { - x.indexAttrMap1[k1] = make(Fruit2Conf_Index_AttrMap) - } - x.indexAttrMap1[k1][key] = append(x.indexAttrMap1[k1][key], v4) - } - } - } - } - } - // OrderedIndex init. - x.orderedIndexItemMap = treemap.New[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item]() - x.orderedIndexItemMap1 = make(map[int32]*Fruit2Conf_OrderedIndex_ItemMap) - for k1, v1 := range x.data.GetFruitMap() { - _ = k1 - for _, v2 := range v1.GetCountryList() { - for k2, v3 := range v2.GetItemMap() { - _ = k2 - { - // OrderedIndex: CountryItemPrice - key := v3.GetPrice() - value, _ := x.orderedIndexItemMap.Get(key) - x.orderedIndexItemMap.Put(key, append(value, v3)) - if x.orderedIndexItemMap1[k1] == nil { - x.orderedIndexItemMap1[k1] = treemap.New[int32, []*protoconf.Fruit2Conf_Fruit_Country_Item]() - } - orderedIndexItemMap1Value, _ := x.orderedIndexItemMap1[k1].Get(key) - x.orderedIndexItemMap1[k1].Put(key, append(orderedIndexItemMap1Value, v3)) - } - } - } - } - // OrderedIndex(sort): CountryItemPrice - orderedIndexItemMapSorter := func(itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) func(i, j int) bool { - return func(i, j int) bool { - return itemList[i].GetId() < itemList[j].GetId() - } - } - x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { - sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) - return true - }) - for _, itemMap := range x.orderedIndexItemMap1 { - itemMap.Range(func(key int32, itemList []*protoconf.Fruit2Conf_Fruit_Country_Item) bool { - sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) - return true - }) - } - return nil -} - -// Get1 finds value in the 1-level map. It will return -// NotFound error if the key is not found. -func (x *Fruit2Conf) Get1(fruitType int32) (*protoconf.Fruit2Conf_Fruit, error) { - d := x.Data().GetFruitMap() - if val, ok := d[fruitType]; !ok { - return nil, fmt.Errorf("fruitType(%v) %w", fruitType, ErrNotFound) - } else { - return val, nil - } -} - -// Index: CountryName - -// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit2Conf_Fruit_Country) map. -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit2Conf) FindCountryMap() Fruit2Conf_Index_CountryMap { - return x.indexCountryMap -} - -// FindCountry finds a slice of all values of the given key. -func (x *Fruit2Conf) FindCountry(name string) []*protoconf.Fruit2Conf_Fruit_Country { - return x.indexCountryMap[name] -} - -// FindFirstCountry finds the first value of the given key, -// or nil if no value found. -func (x *Fruit2Conf) FindFirstCountry(name string) *protoconf.Fruit2Conf_Fruit_Country { - val := x.FindCountry(name) - if len(val) > 0 { - return val[0] - } - return nil -} - -// Index: CountryItemAttrName - -// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit2Conf) FindAttrMap() Fruit2Conf_Index_AttrMap { - return x.indexAttrMap -} - -// FindAttr finds a slice of all values of the given key. -func (x *Fruit2Conf) FindAttr(name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { - return x.indexAttrMap[name] -} - -// FindFirstAttr finds the first value of the given key, -// or nil if no value found. -func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { - val := x.FindAttr(name) - if len(val) > 0 { - return val[0] - } - return nil -} - -// FindAttrMap1 finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) 1-level map -// specified by (fruitType). -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit2Conf) FindAttrMap1(fruitType int32) Fruit2Conf_Index_AttrMap { - return x.indexAttrMap1[fruitType] -} - -// FindAttr1 finds a slice of all values of the given key in the 1-level map -// specified by (fruitType). -func (x *Fruit2Conf) FindAttr1(fruitType int32, name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { - return x.FindAttrMap1(fruitType)[name] -} - -// FindFirstAttr1 finds the first value of the given key in the 1-level map -// specified by (fruitType), or nil if no value found. -func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { - val := x.FindAttr1(fruitType, name) - if len(val) > 0 { - return val[0] - } - return nil -} - -// OrderedIndex: CountryItemPrice - -// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit2Conf) FindItemMap() *Fruit2Conf_OrderedIndex_ItemMap { - return x.orderedIndexItemMap -} - -// FindItem finds a slice of all values of the given key. -func (x *Fruit2Conf) FindItem(price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { - val, _ := x.orderedIndexItemMap.Get(price) - return val -} - -// FindFirstItem finds the first value of the given key, -// or nil if no value found. -func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { - val := x.FindItem(price) - if len(val) > 0 { - return val[0] - } - return nil -} - -// FindItemMap1 finds the index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) 1-level treemap -// specified by (fruitType). -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit2Conf) FindItemMap1(fruitType int32) *Fruit2Conf_OrderedIndex_ItemMap { - return x.orderedIndexItemMap1[fruitType] -} - -// FindItem1 finds a slice of all values of the given key in the 1-level treemap -// specified by (fruitType). -func (x *Fruit2Conf) FindItem1(fruitType int32, price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { - val, _ := x.FindItemMap1(fruitType).Get(price) - return val -} - -// FindFirstItem1 finds the first value of the given key in the 1-level treemap -// specified by (fruitType), or nil if no value found. -func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { - val := x.FindItem1(fruitType, price) - if len(val) > 0 { - return val[0] - } - return nil -} - -// Index types. -// Index: CountryName -type Fruit3Conf_Index_CountryMap = map[string][]*protoconf.Fruit3Conf_Fruit_Country - -// Index: CountryItemAttrName -type Fruit3Conf_Index_AttrMap = map[string][]*protoconf.Fruit3Conf_Fruit_Country_Item_Attr - -// OrderedIndex types. -// OrderedIndex: CountryItemPrice -type Fruit3Conf_OrderedIndex_ItemMap = treemap.TreeMap[int32, []*protoconf.Fruit3Conf_Fruit_Country_Item] - -// Fruit3Conf is a wrapper around protobuf message: protoconf.Fruit3Conf. -// -// It is designed for three goals: -// -// 1. Easy use: simple yet powerful accessers. -// 2. Elegant API: concise and clean functions. -// 3. Extensibility: Map, OrdererdMap, Index, OrderedIndex... -type Fruit3Conf struct { - UnimplementedMessager - data, originalData *protoconf.Fruit3Conf - indexCountryMap Fruit3Conf_Index_CountryMap - indexAttrMap Fruit3Conf_Index_AttrMap - orderedIndexItemMap *Fruit3Conf_OrderedIndex_ItemMap -} - -// Name returns the Fruit3Conf's message name. -func (x *Fruit3Conf) Name() string { - return string((*protoconf.Fruit3Conf)(nil).ProtoReflect().Descriptor().Name()) -} - -// Data returns the Fruit3Conf's inner message data. -func (x *Fruit3Conf) Data() *protoconf.Fruit3Conf { - if x != nil { - return x.data - } - return nil -} - -// Load fills Fruit3Conf's inner message from file in the specified directory and format. -func (x *Fruit3Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { - start := time.Now() - defer func() { - x.Stats.Duration = time.Since(start) - }() - x.data = &protoconf.Fruit3Conf{} - err := load.LoadMessagerInDir(x.data, dir, format, opts) - if err != nil { - return err - } - if x.backup { - x.originalData = proto.Clone(x.data).(*protoconf.Fruit3Conf) - } - return x.processAfterLoad() -} - -// Store writes Fruit3Conf's inner message to file in the specified directory and format. -// Available formats: JSON, Bin, and Text. -func (x *Fruit3Conf) Store(dir string, format format.Format, options ...store.Option) error { - return store.Store(x.Data(), dir, format, options...) -} - -// Message returns the Fruit3Conf's inner message data. -func (x *Fruit3Conf) Message() proto.Message { - return x.Data() -} - -// Messager returns the current messager. -func (x *Fruit3Conf) Messager() Messager { - return x -} - -// originalMessage returns the Fruit3Conf's original inner message. -func (x *Fruit3Conf) originalMessage() proto.Message { - if x != nil { - return x.originalData - } - return nil -} - -// processAfterLoad runs after this messager is loaded. -func (x *Fruit3Conf) processAfterLoad() error { - // Index init. - x.indexCountryMap = make(Fruit3Conf_Index_CountryMap) - x.indexAttrMap = make(Fruit3Conf_Index_AttrMap) - for _, v1 := range x.data.GetFruitList() { - for _, v2 := range v1.GetCountryList() { - { - // Index: CountryName - key := v2.GetName() - x.indexCountryMap[key] = append(x.indexCountryMap[key], v2) - } - for k1, v3 := range v2.GetItemMap() { - _ = k1 - for _, v4 := range v3.GetAttrList() { - { - // Index: CountryItemAttrName - key := v4.GetName() - x.indexAttrMap[key] = append(x.indexAttrMap[key], v4) - } - } - } - } - } - // OrderedIndex init. - x.orderedIndexItemMap = treemap.New[int32, []*protoconf.Fruit3Conf_Fruit_Country_Item]() - for _, v1 := range x.data.GetFruitList() { - for _, v2 := range v1.GetCountryList() { - for k1, v3 := range v2.GetItemMap() { - _ = k1 - { - // OrderedIndex: CountryItemPrice - key := v3.GetPrice() - value, _ := x.orderedIndexItemMap.Get(key) - x.orderedIndexItemMap.Put(key, append(value, v3)) - } - } - } - } - // OrderedIndex(sort): CountryItemPrice - orderedIndexItemMapSorter := func(itemList []*protoconf.Fruit3Conf_Fruit_Country_Item) func(i, j int) bool { - return func(i, j int) bool { - return itemList[i].GetId() < itemList[j].GetId() - } - } - x.orderedIndexItemMap.Range(func(key int32, itemList []*protoconf.Fruit3Conf_Fruit_Country_Item) bool { - sort.Slice(itemList, orderedIndexItemMapSorter(itemList)) - return true - }) - return nil -} - -// Index: CountryName - -// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit3Conf_Fruit_Country) map. -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit3Conf) FindCountryMap() Fruit3Conf_Index_CountryMap { - return x.indexCountryMap -} - -// FindCountry finds a slice of all values of the given key. -func (x *Fruit3Conf) FindCountry(name string) []*protoconf.Fruit3Conf_Fruit_Country { - return x.indexCountryMap[name] -} - -// FindFirstCountry finds the first value of the given key, -// or nil if no value found. -func (x *Fruit3Conf) FindFirstCountry(name string) *protoconf.Fruit3Conf_Fruit_Country { - val := x.FindCountry(name) - if len(val) > 0 { - return val[0] - } - return nil -} - -// Index: CountryItemAttrName - -// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit3Conf) FindAttrMap() Fruit3Conf_Index_AttrMap { - return x.indexAttrMap -} - -// FindAttr finds a slice of all values of the given key. -func (x *Fruit3Conf) FindAttr(name string) []*protoconf.Fruit3Conf_Fruit_Country_Item_Attr { - return x.indexAttrMap[name] -} - -// FindFirstAttr finds the first value of the given key, -// or nil if no value found. -func (x *Fruit3Conf) FindFirstAttr(name string) *protoconf.Fruit3Conf_Fruit_Country_Item_Attr { - val := x.FindAttr(name) - if len(val) > 0 { - return val[0] - } - return nil -} - -// OrderedIndex: CountryItemPrice - -// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit3Conf_Fruit_Country_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. -func (x *Fruit3Conf) FindItemMap() *Fruit3Conf_OrderedIndex_ItemMap { - return x.orderedIndexItemMap -} - -// FindItem finds a slice of all values of the given key. -func (x *Fruit3Conf) FindItem(price int32) []*protoconf.Fruit3Conf_Fruit_Country_Item { - val, _ := x.orderedIndexItemMap.Get(price) - return val -} - -// FindFirstItem finds the first value of the given key, -// or nil if no value found. -func (x *Fruit3Conf) FindFirstItem(price int32) *protoconf.Fruit3Conf_Fruit_Country_Item { - val := x.FindItem(price) - if len(val) > 0 { - return val[0] - } - return nil -} - func init() { Register(func() Messager { return new(ItemConf) }) - Register(func() Messager { - return new(FruitConf) - }) - Register(func() Messager { - return new(Fruit2Conf) - }) - Register(func() Messager { - return new(Fruit3Conf) - }) } diff --git a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go index 7cfd2867..e95289d3 100644 --- a/test/go-tableau-loader/protoconf/loader/messager_container.pc.go +++ b/test/go-tableau-loader/protoconf/loader/messager_container.pc.go @@ -15,10 +15,10 @@ type MessagerContainer struct { // all messagers as fields for fast access heroConf *HeroConf heroBaseConf *HeroBaseConf - itemConf *ItemConf fruitConf *FruitConf fruit2Conf *Fruit2Conf fruit3Conf *Fruit3Conf + itemConf *ItemConf patchReplaceConf *PatchReplaceConf patchMergeConf *PatchMergeConf recursivePatchConf *RecursivePatchConf @@ -34,10 +34,10 @@ func newMessagerContainer(messagerMap MessagerMap) *MessagerContainer { loadedTime: time.Now(), heroConf: GetMessager[*HeroConf](messagerMap), heroBaseConf: GetMessager[*HeroBaseConf](messagerMap), - itemConf: GetMessager[*ItemConf](messagerMap), fruitConf: GetMessager[*FruitConf](messagerMap), fruit2Conf: GetMessager[*Fruit2Conf](messagerMap), fruit3Conf: GetMessager[*Fruit3Conf](messagerMap), + itemConf: GetMessager[*ItemConf](messagerMap), patchReplaceConf: GetMessager[*PatchReplaceConf](messagerMap), patchMergeConf: GetMessager[*PatchMergeConf](messagerMap), recursivePatchConf: GetMessager[*RecursivePatchConf](messagerMap), @@ -70,10 +70,6 @@ func (mc *MessagerContainer) GetHeroBaseConf() *HeroBaseConf { return mc.heroBaseConf } -func (mc *MessagerContainer) GetItemConf() *ItemConf { - return mc.itemConf -} - func (mc *MessagerContainer) GetFruitConf() *FruitConf { return mc.fruitConf } @@ -86,6 +82,10 @@ func (mc *MessagerContainer) GetFruit3Conf() *Fruit3Conf { return mc.fruit3Conf } +func (mc *MessagerContainer) GetItemConf() *ItemConf { + return mc.itemConf +} + func (mc *MessagerContainer) GetPatchReplaceConf() *PatchReplaceConf { return mc.patchReplaceConf } diff --git a/test/proto/index_conf.proto b/test/proto/index_conf.proto new file mode 100644 index 00000000..f990160f --- /dev/null +++ b/test/proto/index_conf.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; + +package protoconf; + +import "tableau/protobuf/tableau.proto"; +import "common_conf.proto"; + +option go_package = "github.com/tableauio/loader/test/go-tableau-loader/protoconf"; +option (tableau.workbook) = { + name: "Index.xlsx" +}; + +// Nesting: map -> map +message FruitConf { + option (tableau.worksheet) = { + name: "FruitConf" + ordered_index: "Price" + }; + + map fruit_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; + message Fruit { + protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; + map item_map = 2 [(tableau.field) = { key: "ID" layout: LAYOUT_VERTICAL }]; + message Item { + int32 id = 1 [(tableau.field) = { name: "ID" }]; + int32 price = 2 [(tableau.field) = { name: "Price" }]; + } + } +} + +// Nesting: map -> list -> map -> list +message Fruit2Conf { + option (tableau.worksheet) = { + name: "Fruit2Conf" + index: "CountryName" + index: "CountryItemAttrName" + ordered_index: "CountryItemPrice" + }; + + map fruit_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; + message Fruit { + protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; + repeated Country country_list = 2 [(tableau.field) = { name: "Country" layout: LAYOUT_HORIZONTAL }]; + message Country { + string name = 1 [(tableau.field) = { name: "Name" }]; + map item_map = 2 [(tableau.field) = { name: "Item" key: "ID" layout: LAYOUT_HORIZONTAL }]; + message Item { + int32 id = 1 [(tableau.field) = { name: "ID" }]; + int32 price = 2 [(tableau.field) = { name: "Price" }]; + repeated Attr attr_list = 3 [(tableau.field) = { name: "Attr" layout: LAYOUT_HORIZONTAL }]; + message Attr { + string name = 1 [(tableau.field) = { name: "Name" }]; + int32 value = 2 [(tableau.field) = { name: "Value" }]; + } + } + } + } +} + +// Nesting: list -> list -> map -> list +message Fruit3Conf { + option (tableau.worksheet) = { + name: "Fruit2Conf" + index: "CountryName" + index: "CountryItemAttrName" + ordered_index: "CountryItemPrice" + }; + + repeated Fruit fruit_list = 1 [(tableau.field) = { layout: LAYOUT_VERTICAL }]; + message Fruit { + protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; + repeated Country country_list = 2 [(tableau.field) = { name: "Country" layout: LAYOUT_HORIZONTAL }]; + message Country { + string name = 1 [(tableau.field) = { name: "Name" }]; + map item_map = 2 [(tableau.field) = { name: "Item" key: "ID" layout: LAYOUT_HORIZONTAL }]; + message Item { + int32 id = 1 [(tableau.field) = { name: "ID" }]; + int32 price = 2 [(tableau.field) = { name: "Price" }]; + repeated Attr attr_list = 3 [(tableau.field) = { name: "Attr" layout: LAYOUT_HORIZONTAL }]; + message Attr { + string name = 1 [(tableau.field) = { name: "Name" }]; + int32 value = 2 [(tableau.field) = { name: "Value" }]; + } + } + } + } +} \ No newline at end of file diff --git a/test/proto/item_conf.proto b/test/proto/item_conf.proto index 07e0c68a..ed873b91 100644 --- a/test/proto/item_conf.proto +++ b/test/proto/item_conf.proto @@ -9,7 +9,7 @@ import "common_conf.proto"; option go_package = "github.com/tableauio/loader/test/go-tableau-loader/protoconf"; option (tableau.workbook) = { - name: "Test.xlsx" + name: "Item.xlsx" }; message ItemConf { @@ -78,76 +78,3 @@ message UseEffect { } message AccountLevel {} } - -message FruitConf { - option (tableau.worksheet) = { - name: "FruitConf" - ordered_index: "Price" - }; - - map fruit_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; - message Fruit { - protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; - map item_map = 2 [(tableau.field) = { key: "ID" layout: LAYOUT_VERTICAL }]; - message Item { - int32 id = 1 [(tableau.field) = { name: "ID" }]; - int32 price = 2 [(tableau.field) = { name: "Price" }]; - } - } -} - -message Fruit2Conf { - option (tableau.worksheet) = { - name: "Fruit2Conf" - index: "CountryName" - index: "CountryItemAttrName" - ordered_index: "CountryItemPrice" - }; - - map fruit_map = 1 [(tableau.field) = { key: "FruitType" layout: LAYOUT_VERTICAL }]; - message Fruit { - protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; - repeated Country country_list = 2 [(tableau.field) = { name: "Country" layout: LAYOUT_HORIZONTAL }]; - message Country { - string name = 1 [(tableau.field) = { name: "Name" }]; - map item_map = 2 [(tableau.field) = { name: "Item" key: "ID" layout: LAYOUT_HORIZONTAL }]; - message Item { - int32 id = 1 [(tableau.field) = { name: "ID" }]; - int32 price = 2 [(tableau.field) = { name: "Price" }]; - repeated Attr attr_list = 3 [(tableau.field) = { name: "Attr" layout: LAYOUT_HORIZONTAL }]; - message Attr { - string name = 1 [(tableau.field) = { name: "Name" }]; - int32 value = 2 [(tableau.field) = { name: "Value" }]; - } - } - } - } -} - -message Fruit3Conf { - option (tableau.worksheet) = { - name: "Fruit2Conf" - index: "CountryName" - index: "CountryItemAttrName" - ordered_index: "CountryItemPrice" - }; - - repeated Fruit fruit_list = 1 [(tableau.field) = { layout: LAYOUT_VERTICAL }]; - message Fruit { - protoconf.FruitType fruit_type = 1 [(tableau.field) = { name: "FruitType" }]; - repeated Country country_list = 2 [(tableau.field) = { name: "Country" layout: LAYOUT_HORIZONTAL }]; - message Country { - string name = 1 [(tableau.field) = { name: "Name" }]; - map item_map = 2 [(tableau.field) = { name: "Item" key: "ID" layout: LAYOUT_HORIZONTAL }]; - message Item { - int32 id = 1 [(tableau.field) = { name: "ID" }]; - int32 price = 2 [(tableau.field) = { name: "Price" }]; - repeated Attr attr_list = 3 [(tableau.field) = { name: "Attr" layout: LAYOUT_HORIZONTAL }]; - message Attr { - string name = 1 [(tableau.field) = { name: "Name" }]; - int32 value = 2 [(tableau.field) = { name: "Value" }]; - } - } - } - } -} \ No newline at end of file From 46e5b24c32c57a864244a26b047e96113ae3e2f2 Mon Sep 17 00:00:00 2001 From: wenchy Date: Thu, 11 Dec 2025 21:08:07 +0800 Subject: [PATCH 13/15] feat: support ordinal of numeral for concise comments --- .../indexes/index.go | 11 +-- .../indexes/orderedindex.go | 11 +-- cmd/protoc-gen-go-tableau-loader/messager.go | 7 +- .../orderedmap/ordered_map.go | 5 +- internal/loadutil/ordinal.go | 27 ++++++ internal/loadutil/ordinal_test.go | 45 ++++++++++ .../protoconf/loader/hero_conf.pc.go | 30 +++---- .../protoconf/loader/index_conf.pc.go | 56 ++++++------ .../protoconf/loader/item_conf.pc.go | 32 +++---- .../protoconf/loader/patch_conf.pc.go | 22 ++--- .../protoconf/loader/test_conf.pc.go | 90 +++++++++---------- 11 files changed, 206 insertions(+), 130 deletions(-) create mode 100644 internal/loadutil/ordinal.go create mode 100644 internal/loadutil/ordinal_test.go diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go index 1de20c14..3f02acff 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -7,6 +7,7 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/loadutil" "github.com/tableauio/loader/internal/options" ) @@ -268,7 +269,7 @@ func (x *Generator) genIndexFinders() { x.g.P("// Index: ", index.Index) x.g.P() - x.g.P("// Find", index.Name(), "Map finds the index (", index.Index, ") to value (", x.mapValueType(index), ") map.") + x.g.P("// Find", index.Name(), "Map finds the index key (", index.Index, ") to value (", x.mapValueType(index), ") map.") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() ", x.indexMapType(index), " {") x.g.P("return x.", indexContainerName) @@ -308,8 +309,8 @@ func (x *Generator) genIndexFinders() { partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() - x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") ", i, "-level map") - x.g.P("// specified by (", partArgs, ").") + x.g.P("// Find", index.Name(), "Map", i, " finds the index key (", index.Index, ") to value (", x.mapValueType(index), "),") + x.g.P("// which is the ", loadutil.Ordinal(i), "-level map specified by (", partArgs, ").") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") ", x.indexMapType(index), " {") if len(partKeys) == 1 { @@ -321,7 +322,7 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", i, "-level map") + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", loadutil.Ordinal(i), "-level map") x.g.P("// specified by (", partArgs, ").") x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { @@ -332,7 +333,7 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", i, "-level map") + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", loadutil.Ordinal(i), "-level map") x.g.P("// specified by (", partArgs, "), or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index cea2d10d..9d015a11 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -7,6 +7,7 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/loadutil" "github.com/tableauio/loader/internal/options" ) @@ -299,7 +300,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("// OrderedIndex: ", index.Index) x.g.P() - x.g.P("// Find", index.Name(), "Map finds the ordered index (", index.Index, ") to value (", x.mapValueType(index), ") treemap.") + x.g.P("// Find", index.Name(), "Map finds the ordered index key (", index.Index, ") to value (", x.mapValueType(index), ") treemap.") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() *", x.orderedIndexMapType(index), " {") x.g.P("return x.", indexContainerName) @@ -340,8 +341,8 @@ func (x *Generator) genOrderedIndexFinders() { partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() - x.g.P("// Find", index.Name(), "Map", i, " finds the index (", index.Index, ") to value (", x.mapValueType(index), ") ", i, "-level treemap") - x.g.P("// specified by (", partArgs, ").") + x.g.P("// Find", index.Name(), "Map", i, " finds the index key (", index.Index, ") to value (", x.mapValueType(index), "),") + x.g.P("// which is the ", loadutil.Ordinal(i), "-level treemap specified by (", partArgs, ").") x.g.P("// One key may correspond to multiple values, which are contained by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") *", x.orderedIndexMapType(index), " {") if len(partKeys) == 1 { @@ -353,7 +354,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", i, "-level treemap") + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", loadutil.Ordinal(i), "-level treemap") x.g.P("// specified by (", partArgs, ").") x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { @@ -365,7 +366,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", i, "-level treemap") + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", loadutil.Ordinal(i), "-level treemap") x.g.P("// specified by (", partArgs, "), or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") diff --git a/cmd/protoc-gen-go-tableau-loader/messager.go b/cmd/protoc-gen-go-tableau-loader/messager.go index 6dd342e3..eab4859c 100644 --- a/cmd/protoc-gen-go-tableau-loader/messager.go +++ b/cmd/protoc-gen-go-tableau-loader/messager.go @@ -8,6 +8,7 @@ import ( "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/orderedmap" "github.com/tableauio/loader/internal/extensions" "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/loadutil" "github.com/tableauio/tableau/proto/tableaupb" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" @@ -102,7 +103,7 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog g.P("}") g.P() - g.P("// Load fills ", messagerName, "'s inner message from file in the specified directory and format.") + g.P("// Load loads ", messagerName, "'s content in the given dir, based on format and messager options.") g.P("func (x *", messagerName, ") Load(dir string, format ", helper.FormatPackage.Ident("Format"), " , opts *", helper.LoadPackage.Ident("MessagerOptions"), ") error {") g.P("start := ", helper.TimePackage.Ident("Now"), "()") g.P("defer func () {") @@ -120,7 +121,7 @@ func genMessage(gen *protogen.Plugin, g *protogen.GeneratedFile, message *protog g.P("}") g.P() - g.P("// Store writes ", messagerName, "'s inner message to file in the specified directory and format.") + g.P("// Store stores ", messagerName, "'s content to file in the specified directory and format.") g.P("// Available formats: JSON, Bin, and Text.") g.P("func (x *", messagerName, ") Store(dir string, format ", helper.FormatPackage.Ident("Format"), " , options ...", helper.StorePackage.Ident("Option"), ") error {") g.P("return ", helper.StorePackage.Ident("Store"), "(x.Data(), dir, format, options...)") @@ -173,7 +174,7 @@ func genMapGetters(gen *protogen.Plugin, g *protogen.GeneratedFile, message *pro Name: helper.ParseMapFieldNameAsFuncParam(fd), }) getter := fmt.Sprintf("Get%v", depth) - g.P("// ", getter, " finds value in the ", depth, "-level map. It will return") + g.P("// ", getter, " finds value in the ", loadutil.Ordinal(depth), "-level map. It will return") g.P("// NotFound error if the key is not found.") g.P("func (x *", messagerName, ") ", getter, "(", keys.GenGetParams(), ") (", helper.ParseMapValueType(gen, g, fd), ", error) {") diff --git a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go index 231c0d29..39430d7c 100644 --- a/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go +++ b/cmd/protoc-gen-go-tableau-loader/orderedmap/ordered_map.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/tableauio/loader/cmd/protoc-gen-go-tableau-loader/helper" + "github.com/tableauio/loader/internal/loadutil" "github.com/tableauio/loader/internal/options" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/reflect/protoreflect" @@ -182,11 +183,11 @@ func (x *Generator) genOrderedMapGetters(md protoreflect.MessageDescriptor, dept getter := genGetterName(depth) orderedMap := x.mapType(fd) if depth == 1 { - x.g.P("// ", getter, " returns the 1-level ordered map.") + x.g.P("// ", getter, " returns the ", loadutil.Ordinal(depth), "-level ordered map.") x.g.P("func (x *", x.messagerName(), ") ", getter, "(", keys.GenGetParams(), ") *", orderedMap, "{") x.g.P("return x.orderedMap ") } else { - x.g.P("// ", getter, " finds value in the ", depth-1, "-level ordered map. It will return") + x.g.P("// ", getter, " finds value in the ", loadutil.Ordinal(depth-1), "-level ordered map. It will return") x.g.P("// NotFound error if the key is not found.") x.g.P("func (x *", x.messagerName(), ") ", getter, "(", keys.GenGetParams(), ") (*", orderedMap, ", error) {") if depth == 2 { diff --git a/internal/loadutil/ordinal.go b/internal/loadutil/ordinal.go new file mode 100644 index 00000000..3e004e58 --- /dev/null +++ b/internal/loadutil/ordinal.go @@ -0,0 +1,27 @@ +package loadutil + +import "fmt" + +// Ordinal returns the ordinal representation of a number. +func Ordinal(n int) string { + abs := n + if abs < 0 { + abs = -abs + } + + // handle 11, 12, 13 etc. + if abs%100 >= 11 && abs%100 <= 13 { + return fmt.Sprintf("%dth", n) + } + + switch abs % 10 { + case 1: + return fmt.Sprintf("%dst", n) + case 2: + return fmt.Sprintf("%dnd", n) + case 3: + return fmt.Sprintf("%drd", n) + default: + return fmt.Sprintf("%dth", n) + } +} diff --git a/internal/loadutil/ordinal_test.go b/internal/loadutil/ordinal_test.go new file mode 100644 index 00000000..2831e0bd --- /dev/null +++ b/internal/loadutil/ordinal_test.go @@ -0,0 +1,45 @@ +package loadutil + +import ( + "fmt" + "testing" +) + +func TestOrdinal(t *testing.T) { + tests := []struct { + in int + want string + }{ + {0, "0th"}, + {1, "1st"}, + {2, "2nd"}, + {3, "3rd"}, + {4, "4th"}, + {10, "10th"}, + {11, "11th"}, + {12, "12th"}, + {13, "13th"}, + {21, "21st"}, + {22, "22nd"}, + {23, "23rd"}, + {101, "101st"}, + {111, "111th"}, + {-1, "-1st"}, + {-12, "-12th"}, + {1001, "1001st"}, + {1112, "1112th"}, // 12 -> th + {1123, "1123rd"}, + {214, "214th"}, // 14 -> th + } + + for _, tc := range tests { + tc := tc // capture + t.Run(fmt.Sprintf("%d", tc.in), func(t *testing.T) { + t.Parallel() + got := Ordinal(tc.in) + if got != tc.want { + t.Fatalf("ordinal(%d) = %q; want %q", tc.in, got, tc.want) + } + }) + } +} diff --git a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go index c98487a8..39b12f6d 100644 --- a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go @@ -50,7 +50,7 @@ func (x *HeroConf) Data() *protoconf.HeroConf { return nil } -// Load fills HeroConf's inner message from file in the specified directory and format. +// Load loads HeroConf's content in the given dir, based on format and messager options. func (x *HeroConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -67,7 +67,7 @@ func (x *HeroConf) Load(dir string, format format.Format, opts *load.MessagerOpt return x.processAfterLoad() } -// Store writes HeroConf's inner message to file in the specified directory and format. +// Store stores HeroConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *HeroConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -114,7 +114,7 @@ func (x *HeroConf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *HeroConf) Get1(name string) (*protoconf.HeroConf_Hero, error) { d := x.Data().GetHeroMap() @@ -125,7 +125,7 @@ func (x *HeroConf) Get1(name string) (*protoconf.HeroConf_Hero, error) { } } -// Get2 finds value in the 2-level map. It will return +// Get2 finds value in the 2nd-level map. It will return // NotFound error if the key is not found. func (x *HeroConf) Get2(name string, title string) (*protoconf.HeroConf_Hero_Attr, error) { conf, err := x.Get1(name) @@ -142,7 +142,7 @@ func (x *HeroConf) Get2(name string, title string) (*protoconf.HeroConf_Hero_Att // Index: Title -// FindAttrMap finds the index (Title) to value (protoconf.HeroConf_Hero_Attr) map. +// FindAttrMap finds the index key (Title) to value (protoconf.HeroConf_Hero_Attr) map. // One key may correspond to multiple values, which are contained by a slice. func (x *HeroConf) FindAttrMap() HeroConf_Index_AttrMap { return x.indexAttrMap @@ -163,20 +163,20 @@ func (x *HeroConf) FindFirstAttr(title string) *protoconf.HeroConf_Hero_Attr { return nil } -// FindAttrMap1 finds the index (Title) to value (protoconf.HeroConf_Hero_Attr) 1-level map -// specified by (name). +// FindAttrMap1 finds the index key (Title) to value (protoconf.HeroConf_Hero_Attr), +// which is the 1st-level map specified by (name). // One key may correspond to multiple values, which are contained by a slice. func (x *HeroConf) FindAttrMap1(name string) HeroConf_Index_AttrMap { return x.indexAttrMap1[name] } -// FindAttr1 finds a slice of all values of the given key in the 1-level map +// FindAttr1 finds a slice of all values of the given key in the 1st-level map // specified by (name). func (x *HeroConf) FindAttr1(name string, title string) []*protoconf.HeroConf_Hero_Attr { return x.FindAttrMap1(name)[title] } -// FindFirstAttr1 finds the first value of the given key in the 1-level map +// FindFirstAttr1 finds the first value of the given key in the 1st-level map // specified by (name), or nil if no value found. func (x *HeroConf) FindFirstAttr1(name string, title string) *protoconf.HeroConf_Hero_Attr { val := x.FindAttr1(name, title) @@ -218,7 +218,7 @@ func (x *HeroBaseConf) Data() *protoconf.HeroBaseConf { return nil } -// Load fills HeroBaseConf's inner message from file in the specified directory and format. +// Load loads HeroBaseConf's content in the given dir, based on format and messager options. func (x *HeroBaseConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -235,7 +235,7 @@ func (x *HeroBaseConf) Load(dir string, format format.Format, opts *load.Message return x.processAfterLoad() } -// Store writes HeroBaseConf's inner message to file in the specified directory and format. +// Store stores HeroBaseConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *HeroBaseConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -278,7 +278,7 @@ func (x *HeroBaseConf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *HeroBaseConf) Get1(name string) (*base.Hero, error) { d := x.Data().GetHeroMap() @@ -289,7 +289,7 @@ func (x *HeroBaseConf) Get1(name string) (*base.Hero, error) { } } -// Get2 finds value in the 2-level map. It will return +// Get2 finds value in the 2nd-level map. It will return // NotFound error if the key is not found. func (x *HeroBaseConf) Get2(name string, id string) (*base.Item, error) { conf, err := x.Get1(name) @@ -304,12 +304,12 @@ func (x *HeroBaseConf) Get2(name string, id string) (*base.Item, error) { } } -// GetOrderedMap returns the 1-level ordered map. +// GetOrderedMap returns the 1st-level ordered map. func (x *HeroBaseConf) GetOrderedMap() *HeroBaseConf_OrderedMap_base_HeroMap { return x.orderedMap } -// GetOrderedMap1 finds value in the 1-level ordered map. It will return +// GetOrderedMap1 finds value in the 1st-level ordered map. It will return // NotFound error if the key is not found. func (x *HeroBaseConf) GetOrderedMap1(name string) (*HeroBaseConf_OrderedMap_base_ItemMap, error) { conf := x.orderedMap diff --git a/test/go-tableau-loader/protoconf/loader/index_conf.pc.go b/test/go-tableau-loader/protoconf/loader/index_conf.pc.go index 85387754..f86fa45f 100644 --- a/test/go-tableau-loader/protoconf/loader/index_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/index_conf.pc.go @@ -49,7 +49,7 @@ func (x *FruitConf) Data() *protoconf.FruitConf { return nil } -// Load fills FruitConf's inner message from file in the specified directory and format. +// Load loads FruitConf's content in the given dir, based on format and messager options. func (x *FruitConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -66,7 +66,7 @@ func (x *FruitConf) Load(dir string, format format.Format, opts *load.MessagerOp return x.processAfterLoad() } -// Store writes FruitConf's inner message to file in the specified directory and format. +// Store stores FruitConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *FruitConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -131,7 +131,7 @@ func (x *FruitConf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruit, error) { d := x.Data().GetFruitMap() @@ -142,7 +142,7 @@ func (x *FruitConf) Get1(fruitType int32) (*protoconf.FruitConf_Fruit, error) { } } -// Get2 finds value in the 2-level map. It will return +// Get2 finds value in the 2nd-level map. It will return // NotFound error if the key is not found. func (x *FruitConf) Get2(fruitType int32, id int32) (*protoconf.FruitConf_Fruit_Item, error) { conf, err := x.Get1(fruitType) @@ -159,7 +159,7 @@ func (x *FruitConf) Get2(fruitType int32, id int32) (*protoconf.FruitConf_Fruit_ // OrderedIndex: Price -// FindItemMap finds the ordered index (Price) to value (protoconf.FruitConf_Fruit_Item) treemap. +// FindItemMap finds the ordered index key (Price) to value (protoconf.FruitConf_Fruit_Item) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *FruitConf) FindItemMap() *FruitConf_OrderedIndex_ItemMap { return x.orderedIndexItemMap @@ -181,21 +181,21 @@ func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { return nil } -// FindItemMap1 finds the index (Price) to value (protoconf.FruitConf_Fruit_Item) 1-level treemap -// specified by (fruitType). +// FindItemMap1 finds the index key (Price) to value (protoconf.FruitConf_Fruit_Item), +// which is the 1st-level treemap specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. func (x *FruitConf) FindItemMap1(fruitType int32) *FruitConf_OrderedIndex_ItemMap { return x.orderedIndexItemMap1[fruitType] } -// FindItem1 finds a slice of all values of the given key in the 1-level treemap +// FindItem1 finds a slice of all values of the given key in the 1st-level treemap // specified by (fruitType). func (x *FruitConf) FindItem1(fruitType int32, price int32) []*protoconf.FruitConf_Fruit_Item { val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstItem1 finds the first value of the given key in the 1-level treemap +// FindFirstItem1 finds the first value of the given key in the 1st-level treemap // specified by (fruitType), or nil if no value found. func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.FruitConf_Fruit_Item { val := x.FindItem1(fruitType, price) @@ -246,7 +246,7 @@ func (x *Fruit2Conf) Data() *protoconf.Fruit2Conf { return nil } -// Load fills Fruit2Conf's inner message from file in the specified directory and format. +// Load loads Fruit2Conf's content in the given dir, based on format and messager options. func (x *Fruit2Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -263,7 +263,7 @@ func (x *Fruit2Conf) Load(dir string, format format.Format, opts *load.MessagerO return x.processAfterLoad() } -// Store writes Fruit2Conf's inner message to file in the specified directory and format. +// Store stores Fruit2Conf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *Fruit2Conf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -358,7 +358,7 @@ func (x *Fruit2Conf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *Fruit2Conf) Get1(fruitType int32) (*protoconf.Fruit2Conf_Fruit, error) { d := x.Data().GetFruitMap() @@ -371,7 +371,7 @@ func (x *Fruit2Conf) Get1(fruitType int32) (*protoconf.Fruit2Conf_Fruit, error) // Index: CountryName -// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit2Conf_Fruit_Country) map. +// FindCountryMap finds the index key (CountryName) to value (protoconf.Fruit2Conf_Fruit_Country) map. // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindCountryMap() Fruit2Conf_Index_CountryMap { return x.indexCountryMap @@ -394,7 +394,7 @@ func (x *Fruit2Conf) FindFirstCountry(name string) *protoconf.Fruit2Conf_Fruit_C // Index: CountryItemAttrName -// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. +// FindAttrMap finds the index key (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindAttrMap() Fruit2Conf_Index_AttrMap { return x.indexAttrMap @@ -415,20 +415,20 @@ func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Coun return nil } -// FindAttrMap1 finds the index (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) 1-level map -// specified by (fruitType). +// FindAttrMap1 finds the index key (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr), +// which is the 1st-level map specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindAttrMap1(fruitType int32) Fruit2Conf_Index_AttrMap { return x.indexAttrMap1[fruitType] } -// FindAttr1 finds a slice of all values of the given key in the 1-level map +// FindAttr1 finds a slice of all values of the given key in the 1st-level map // specified by (fruitType). func (x *Fruit2Conf) FindAttr1(fruitType int32, name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { return x.FindAttrMap1(fruitType)[name] } -// FindFirstAttr1 finds the first value of the given key in the 1-level map +// FindFirstAttr1 finds the first value of the given key in the 1st-level map // specified by (fruitType), or nil if no value found. func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { val := x.FindAttr1(fruitType, name) @@ -440,7 +440,7 @@ func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fru // OrderedIndex: CountryItemPrice -// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap. +// FindItemMap finds the ordered index key (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindItemMap() *Fruit2Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap @@ -462,21 +462,21 @@ func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Coun return nil } -// FindItemMap1 finds the index (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) 1-level treemap -// specified by (fruitType). +// FindItemMap1 finds the index key (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item), +// which is the 1st-level treemap specified by (fruitType). // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit2Conf) FindItemMap1(fruitType int32) *Fruit2Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap1[fruitType] } -// FindItem1 finds a slice of all values of the given key in the 1-level treemap +// FindItem1 finds a slice of all values of the given key in the 1st-level treemap // specified by (fruitType). func (x *Fruit2Conf) FindItem1(fruitType int32, price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstItem1 finds the first value of the given key in the 1-level treemap +// FindFirstItem1 finds the first value of the given key in the 1st-level treemap // specified by (fruitType), or nil if no value found. func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { val := x.FindItem1(fruitType, price) @@ -525,7 +525,7 @@ func (x *Fruit3Conf) Data() *protoconf.Fruit3Conf { return nil } -// Load fills Fruit3Conf's inner message from file in the specified directory and format. +// Load loads Fruit3Conf's content in the given dir, based on format and messager options. func (x *Fruit3Conf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -542,7 +542,7 @@ func (x *Fruit3Conf) Load(dir string, format format.Format, opts *load.MessagerO return x.processAfterLoad() } -// Store writes Fruit3Conf's inner message to file in the specified directory and format. +// Store stores Fruit3Conf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *Fruit3Conf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -620,7 +620,7 @@ func (x *Fruit3Conf) processAfterLoad() error { // Index: CountryName -// FindCountryMap finds the index (CountryName) to value (protoconf.Fruit3Conf_Fruit_Country) map. +// FindCountryMap finds the index key (CountryName) to value (protoconf.Fruit3Conf_Fruit_Country) map. // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit3Conf) FindCountryMap() Fruit3Conf_Index_CountryMap { return x.indexCountryMap @@ -643,7 +643,7 @@ func (x *Fruit3Conf) FindFirstCountry(name string) *protoconf.Fruit3Conf_Fruit_C // Index: CountryItemAttrName -// FindAttrMap finds the index (CountryItemAttrName) to value (protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. +// FindAttrMap finds the index key (CountryItemAttrName) to value (protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit3Conf) FindAttrMap() Fruit3Conf_Index_AttrMap { return x.indexAttrMap @@ -666,7 +666,7 @@ func (x *Fruit3Conf) FindFirstAttr(name string) *protoconf.Fruit3Conf_Fruit_Coun // OrderedIndex: CountryItemPrice -// FindItemMap finds the ordered index (CountryItemPrice) to value (protoconf.Fruit3Conf_Fruit_Country_Item) treemap. +// FindItemMap finds the ordered index key (CountryItemPrice) to value (protoconf.Fruit3Conf_Fruit_Country_Item) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *Fruit3Conf) FindItemMap() *Fruit3Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index ab50b2c2..89121cef 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -119,7 +119,7 @@ func (x *ItemConf) Data() *protoconf.ItemConf { return nil } -// Load fills ItemConf's inner message from file in the specified directory and format. +// Load loads ItemConf's content in the given dir, based on format and messager options. func (x *ItemConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -136,7 +136,7 @@ func (x *ItemConf) Load(dir string, format format.Format, opts *load.MessagerOpt return x.processAfterLoad() } -// Store writes ItemConf's inner message to file in the specified directory and format. +// Store stores ItemConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *ItemConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -300,7 +300,7 @@ func (x *ItemConf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *ItemConf) Get1(id uint32) (*protoconf.ItemConf_Item, error) { d := x.Data().GetItemMap() @@ -311,14 +311,14 @@ func (x *ItemConf) Get1(id uint32) (*protoconf.ItemConf_Item, error) { } } -// GetOrderedMap returns the 1-level ordered map. +// GetOrderedMap returns the 1st-level ordered map. func (x *ItemConf) GetOrderedMap() *ItemConf_OrderedMap_ItemMap { return x.orderedMap } // Index: Type -// FindItemMap finds the index (Type) to value (protoconf.ItemConf_Item) map. +// FindItemMap finds the index key (Type) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemMap() ItemConf_Index_ItemMap { return x.indexItemMap @@ -341,7 +341,7 @@ func (x *ItemConf) FindFirstItem(type_ protoconf.FruitType) *protoconf.ItemConf_ // Index: Param@ItemInfo -// FindItemInfoMap finds the index (Param@ItemInfo) to value (protoconf.ItemConf_Item) map. +// FindItemInfoMap finds the index key (Param@ItemInfo) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemInfoMap() ItemConf_Index_ItemInfoMap { return x.indexItemInfoMap @@ -364,7 +364,7 @@ func (x *ItemConf) FindFirstItemInfo(param int32) *protoconf.ItemConf_Item { // Index: Default@ItemDefaultInfo -// FindItemDefaultInfoMap finds the index (Default@ItemDefaultInfo) to value (protoconf.ItemConf_Item) map. +// FindItemDefaultInfoMap finds the index key (Default@ItemDefaultInfo) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemDefaultInfoMap() ItemConf_Index_ItemDefaultInfoMap { return x.indexItemDefaultInfoMap @@ -387,7 +387,7 @@ func (x *ItemConf) FindFirstItemDefaultInfo(default_ string) *protoconf.ItemConf // Index: ExtType@ItemExtInfo -// FindItemExtInfoMap finds the index (ExtType@ItemExtInfo) to value (protoconf.ItemConf_Item) map. +// FindItemExtInfoMap finds the index key (ExtType@ItemExtInfo) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemExtInfoMap() ItemConf_Index_ItemExtInfoMap { return x.indexItemExtInfoMap @@ -410,7 +410,7 @@ func (x *ItemConf) FindFirstItemExtInfo(extType protoconf.FruitType) *protoconf. // Index: (ID,Name)@AwardItem -// FindAwardItemMap finds the index ((ID,Name)@AwardItem) to value (protoconf.ItemConf_Item) map. +// FindAwardItemMap finds the index key ((ID,Name)@AwardItem) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindAwardItemMap() ItemConf_Index_AwardItemMap { return x.indexAwardItemMap @@ -433,7 +433,7 @@ func (x *ItemConf) FindFirstAwardItem(id uint32, name string) *protoconf.ItemCon // Index: (ID,Type,Param,ExtType)@SpecialItem -// FindSpecialItemMap finds the index ((ID,Type,Param,ExtType)@SpecialItem) to value (protoconf.ItemConf_Item) map. +// FindSpecialItemMap finds the index key ((ID,Type,Param,ExtType)@SpecialItem) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindSpecialItemMap() ItemConf_Index_SpecialItemMap { return x.indexSpecialItemMap @@ -456,7 +456,7 @@ func (x *ItemConf) FindFirstSpecialItem(id uint32, type_ protoconf.FruitType, pa // Index: PathDir@ItemPathDir -// FindItemPathDirMap finds the index (PathDir@ItemPathDir) to value (protoconf.ItemConf_Item) map. +// FindItemPathDirMap finds the index key (PathDir@ItemPathDir) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemPathDirMap() ItemConf_Index_ItemPathDirMap { return x.indexItemPathDirMap @@ -479,7 +479,7 @@ func (x *ItemConf) FindFirstItemPathDir(dir string) *protoconf.ItemConf_Item { // Index: PathName@ItemPathName -// FindItemPathNameMap finds the index (PathName@ItemPathName) to value (protoconf.ItemConf_Item) map. +// FindItemPathNameMap finds the index key (PathName@ItemPathName) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemPathNameMap() ItemConf_Index_ItemPathNameMap { return x.indexItemPathNameMap @@ -502,7 +502,7 @@ func (x *ItemConf) FindFirstItemPathName(name string) *protoconf.ItemConf_Item { // Index: PathFriendID@ItemPathFriendID -// FindItemPathFriendIDMap finds the index (PathFriendID@ItemPathFriendID) to value (protoconf.ItemConf_Item) map. +// FindItemPathFriendIDMap finds the index key (PathFriendID@ItemPathFriendID) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindItemPathFriendIDMap() ItemConf_Index_ItemPathFriendIDMap { return x.indexItemPathFriendIdMap @@ -525,7 +525,7 @@ func (x *ItemConf) FindFirstItemPathFriendID(id uint32) *protoconf.ItemConf_Item // Index: UseEffectType@UseEffectType -// FindUseEffectTypeMap finds the index (UseEffectType@UseEffectType) to value (protoconf.ItemConf_Item) map. +// FindUseEffectTypeMap finds the index key (UseEffectType@UseEffectType) to value (protoconf.ItemConf_Item) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindUseEffectTypeMap() ItemConf_Index_UseEffectTypeMap { return x.indexUseEffectTypeMap @@ -548,7 +548,7 @@ func (x *ItemConf) FindFirstUseEffectType(type_ protoconf.UseEffect_Type) *proto // OrderedIndex: ExtType@ExtType -// FindExtTypeMap finds the ordered index (ExtType@ExtType) to value (protoconf.ItemConf_Item) treemap. +// FindExtTypeMap finds the ordered index key (ExtType@ExtType) to value (protoconf.ItemConf_Item) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindExtTypeMap() *ItemConf_OrderedIndex_ExtTypeMap { return x.orderedIndexExtTypeMap @@ -572,7 +572,7 @@ func (x *ItemConf) FindFirstExtType(extType protoconf.FruitType) *protoconf.Item // OrderedIndex: (Param,ExtType)@ParamExtType -// FindParamExtTypeMap finds the ordered index ((Param,ExtType)@ParamExtType) to value (protoconf.ItemConf_Item) treemap. +// FindParamExtTypeMap finds the ordered index key ((Param,ExtType)@ParamExtType) to value (protoconf.ItemConf_Item) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *ItemConf) FindParamExtTypeMap() *ItemConf_OrderedIndex_ParamExtTypeMap { return x.orderedIndexParamExtTypeMap diff --git a/test/go-tableau-loader/protoconf/loader/patch_conf.pc.go b/test/go-tableau-loader/protoconf/loader/patch_conf.pc.go index 9b1d4c4f..b4a5a278 100644 --- a/test/go-tableau-loader/protoconf/loader/patch_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/patch_conf.pc.go @@ -41,7 +41,7 @@ func (x *PatchReplaceConf) Data() *protoconf.PatchReplaceConf { return nil } -// Load fills PatchReplaceConf's inner message from file in the specified directory and format. +// Load loads PatchReplaceConf's content in the given dir, based on format and messager options. func (x *PatchReplaceConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -58,7 +58,7 @@ func (x *PatchReplaceConf) Load(dir string, format format.Format, opts *load.Mes return x.processAfterLoad() } -// Store writes PatchReplaceConf's inner message to file in the specified directory and format. +// Store stores PatchReplaceConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *PatchReplaceConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -107,7 +107,7 @@ func (x *PatchMergeConf) Data() *protoconf.PatchMergeConf { return nil } -// Load fills PatchMergeConf's inner message from file in the specified directory and format. +// Load loads PatchMergeConf's content in the given dir, based on format and messager options. func (x *PatchMergeConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -124,7 +124,7 @@ func (x *PatchMergeConf) Load(dir string, format format.Format, opts *load.Messa return x.processAfterLoad() } -// Store writes PatchMergeConf's inner message to file in the specified directory and format. +// Store stores PatchMergeConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *PatchMergeConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -148,7 +148,7 @@ func (x *PatchMergeConf) originalMessage() proto.Message { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *PatchMergeConf) Get1(id uint32) (*protoconf.Item, error) { d := x.Data().GetItemMap() @@ -184,7 +184,7 @@ func (x *RecursivePatchConf) Data() *protoconf.RecursivePatchConf { return nil } -// Load fills RecursivePatchConf's inner message from file in the specified directory and format. +// Load loads RecursivePatchConf's content in the given dir, based on format and messager options. func (x *RecursivePatchConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -201,7 +201,7 @@ func (x *RecursivePatchConf) Load(dir string, format format.Format, opts *load.M return x.processAfterLoad() } -// Store writes RecursivePatchConf's inner message to file in the specified directory and format. +// Store stores RecursivePatchConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *RecursivePatchConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -225,7 +225,7 @@ func (x *RecursivePatchConf) originalMessage() proto.Message { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *RecursivePatchConf) Get1(shopId uint32) (*protoconf.RecursivePatchConf_Shop, error) { d := x.Data().GetShopMap() @@ -236,7 +236,7 @@ func (x *RecursivePatchConf) Get1(shopId uint32) (*protoconf.RecursivePatchConf_ } } -// Get2 finds value in the 2-level map. It will return +// Get2 finds value in the 2nd-level map. It will return // NotFound error if the key is not found. func (x *RecursivePatchConf) Get2(shopId uint32, goodsId uint32) (*protoconf.RecursivePatchConf_Shop_Goods, error) { conf, err := x.Get1(shopId) @@ -251,7 +251,7 @@ func (x *RecursivePatchConf) Get2(shopId uint32, goodsId uint32) (*protoconf.Rec } } -// Get3 finds value in the 3-level map. It will return +// Get3 finds value in the 3rd-level map. It will return // NotFound error if the key is not found. func (x *RecursivePatchConf) Get3(shopId uint32, goodsId uint32, type_ uint32) (*protoconf.RecursivePatchConf_Shop_Goods_Currency, error) { conf, err := x.Get2(shopId, goodsId) @@ -266,7 +266,7 @@ func (x *RecursivePatchConf) Get3(shopId uint32, goodsId uint32, type_ uint32) ( } } -// Get4 finds value in the 4-level map. It will return +// Get4 finds value in the 4th-level map. It will return // NotFound error if the key is not found. func (x *RecursivePatchConf) Get4(shopId uint32, goodsId uint32, type_ uint32, key4 int32) (int32, error) { conf, err := x.Get3(shopId, goodsId, type_) diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index 5829d06e..fa2c50a7 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -84,7 +84,7 @@ func (x *ActivityConf) Data() *protoconf.ActivityConf { return nil } -// Load fills ActivityConf's inner message from file in the specified directory and format. +// Load loads ActivityConf's content in the given dir, based on format and messager options. func (x *ActivityConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -101,7 +101,7 @@ func (x *ActivityConf) Load(dir string, format format.Format, opts *load.Message return x.processAfterLoad() } -// Store writes ActivityConf's inner message to file in the specified directory and format. +// Store stores ActivityConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *ActivityConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -231,7 +231,7 @@ func (x *ActivityConf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *ActivityConf) Get1(activityId uint64) (*protoconf.ActivityConf_Activity, error) { d := x.Data().GetActivityMap() @@ -242,7 +242,7 @@ func (x *ActivityConf) Get1(activityId uint64) (*protoconf.ActivityConf_Activity } } -// Get2 finds value in the 2-level map. It will return +// Get2 finds value in the 2nd-level map. It will return // NotFound error if the key is not found. func (x *ActivityConf) Get2(activityId uint64, chapterId uint32) (*protoconf.ActivityConf_Activity_Chapter, error) { conf, err := x.Get1(activityId) @@ -257,7 +257,7 @@ func (x *ActivityConf) Get2(activityId uint64, chapterId uint32) (*protoconf.Act } } -// Get3 finds value in the 3-level map. It will return +// Get3 finds value in the 3rd-level map. It will return // NotFound error if the key is not found. func (x *ActivityConf) Get3(activityId uint64, chapterId uint32, sectionId uint32) (*protoconf.Section, error) { conf, err := x.Get2(activityId, chapterId) @@ -272,7 +272,7 @@ func (x *ActivityConf) Get3(activityId uint64, chapterId uint32, sectionId uint3 } } -// Get4 finds value in the 4-level map. It will return +// Get4 finds value in the 4th-level map. It will return // NotFound error if the key is not found. func (x *ActivityConf) Get4(activityId uint64, chapterId uint32, sectionId uint32, key4 uint32) (int32, error) { conf, err := x.Get3(activityId, chapterId, sectionId) @@ -287,12 +287,12 @@ func (x *ActivityConf) Get4(activityId uint64, chapterId uint32, sectionId uint3 } } -// GetOrderedMap returns the 1-level ordered map. +// GetOrderedMap returns the 1st-level ordered map. func (x *ActivityConf) GetOrderedMap() *ActivityConf_OrderedMap_ActivityMap { return x.orderedMap } -// GetOrderedMap1 finds value in the 1-level ordered map. It will return +// GetOrderedMap1 finds value in the 1st-level ordered map. It will return // NotFound error if the key is not found. func (x *ActivityConf) GetOrderedMap1(activityId uint64) (*ActivityConf_OrderedMap_Activity_ChapterMap, error) { conf := x.orderedMap @@ -303,7 +303,7 @@ func (x *ActivityConf) GetOrderedMap1(activityId uint64) (*ActivityConf_OrderedM } } -// GetOrderedMap2 finds value in the 2-level ordered map. It will return +// GetOrderedMap2 finds value in the 2nd-level ordered map. It will return // NotFound error if the key is not found. func (x *ActivityConf) GetOrderedMap2(activityId uint64, chapterId uint32) (*ActivityConf_OrderedMap_protoconf_SectionMap, error) { conf, err := x.GetOrderedMap1(activityId) @@ -317,7 +317,7 @@ func (x *ActivityConf) GetOrderedMap2(activityId uint64, chapterId uint32) (*Act } } -// GetOrderedMap3 finds value in the 3-level ordered map. It will return +// GetOrderedMap3 finds value in the 3rd-level ordered map. It will return // NotFound error if the key is not found. func (x *ActivityConf) GetOrderedMap3(activityId uint64, chapterId uint32, sectionId uint32) (*ActivityConf_OrderedMap_int32Map, error) { conf, err := x.GetOrderedMap2(activityId, chapterId) @@ -333,7 +333,7 @@ func (x *ActivityConf) GetOrderedMap3(activityId uint64, chapterId uint32, secti // Index: ActivityName -// FindActivityMap finds the index (ActivityName) to value (protoconf.ActivityConf_Activity) map. +// FindActivityMap finds the index key (ActivityName) to value (protoconf.ActivityConf_Activity) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindActivityMap() ActivityConf_Index_ActivityMap { return x.indexActivityMap @@ -356,7 +356,7 @@ func (x *ActivityConf) FindFirstActivity(activityName string) *protoconf.Activit // Index: ChapterID -// FindChapterMap finds the index (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) map. +// FindChapterMap finds the index key (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindChapterMap() ActivityConf_Index_ChapterMap { return x.indexChapterMap @@ -377,20 +377,20 @@ func (x *ActivityConf) FindFirstChapter(chapterId uint32) *protoconf.ActivityCon return nil } -// FindChapterMap1 finds the index (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) 1-level map -// specified by (activityId). +// FindChapterMap1 finds the index key (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter), +// which is the 1st-level map specified by (activityId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindChapterMap1(activityId uint64) ActivityConf_Index_ChapterMap { return x.indexChapterMap1[activityId] } -// FindChapter1 finds a slice of all values of the given key in the 1-level map +// FindChapter1 finds a slice of all values of the given key in the 1st-level map // specified by (activityId). func (x *ActivityConf) FindChapter1(activityId uint64, chapterId uint32) []*protoconf.ActivityConf_Activity_Chapter { return x.FindChapterMap1(activityId)[chapterId] } -// FindFirstChapter1 finds the first value of the given key in the 1-level map +// FindFirstChapter1 finds the first value of the given key in the 1st-level map // specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstChapter1(activityId uint64, chapterId uint32) *protoconf.ActivityConf_Activity_Chapter { val := x.FindChapter1(activityId, chapterId) @@ -402,7 +402,7 @@ func (x *ActivityConf) FindFirstChapter1(activityId uint64, chapterId uint32) *p // Index: ChapterName@NamedChapter -// FindNamedChapterMap finds the index (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) map. +// FindNamedChapterMap finds the index key (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindNamedChapterMap() ActivityConf_Index_NamedChapterMap { return x.indexNamedChapterMap @@ -423,20 +423,20 @@ func (x *ActivityConf) FindFirstNamedChapter(chapterName string) *protoconf.Acti return nil } -// FindNamedChapterMap1 finds the index (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) 1-level map -// specified by (activityId). +// FindNamedChapterMap1 finds the index key (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter), +// which is the 1st-level map specified by (activityId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindNamedChapterMap1(activityId uint64) ActivityConf_Index_NamedChapterMap { return x.indexNamedChapterMap1[activityId] } -// FindNamedChapter1 finds a slice of all values of the given key in the 1-level map +// FindNamedChapter1 finds a slice of all values of the given key in the 1st-level map // specified by (activityId). func (x *ActivityConf) FindNamedChapter1(activityId uint64, chapterName string) []*protoconf.ActivityConf_Activity_Chapter { return x.FindNamedChapterMap1(activityId)[chapterName] } -// FindFirstNamedChapter1 finds the first value of the given key in the 1-level map +// FindFirstNamedChapter1 finds the first value of the given key in the 1st-level map // specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstNamedChapter1(activityId uint64, chapterName string) *protoconf.ActivityConf_Activity_Chapter { val := x.FindNamedChapter1(activityId, chapterName) @@ -448,7 +448,7 @@ func (x *ActivityConf) FindFirstNamedChapter1(activityId uint64, chapterName str // Index: SectionItemID@Award -// FindAwardMap finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) map. +// FindAwardMap finds the index key (SectionItemID@Award) to value (protoconf.Section_SectionItem) map. // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap() ActivityConf_Index_AwardMap { return x.indexAwardMap @@ -469,20 +469,20 @@ func (x *ActivityConf) FindFirstAward(id uint32) *protoconf.Section_SectionItem return nil } -// FindAwardMap1 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) 1-level map -// specified by (activityId). +// FindAwardMap1 finds the index key (SectionItemID@Award) to value (protoconf.Section_SectionItem), +// which is the 1st-level map specified by (activityId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap1(activityId uint64) ActivityConf_Index_AwardMap { return x.indexAwardMap1[activityId] } -// FindAward1 finds a slice of all values of the given key in the 1-level map +// FindAward1 finds a slice of all values of the given key in the 1st-level map // specified by (activityId). func (x *ActivityConf) FindAward1(activityId uint64, id uint32) []*protoconf.Section_SectionItem { return x.FindAwardMap1(activityId)[id] } -// FindFirstAward1 finds the first value of the given key in the 1-level map +// FindFirstAward1 finds the first value of the given key in the 1st-level map // specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf.Section_SectionItem { val := x.FindAward1(activityId, id) @@ -492,20 +492,20 @@ func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf. return nil } -// FindAwardMap2 finds the index (SectionItemID@Award) to value (protoconf.Section_SectionItem) 2-level map -// specified by (activityId, chapterId). +// FindAwardMap2 finds the index key (SectionItemID@Award) to value (protoconf.Section_SectionItem), +// which is the 2nd-level map specified by (activityId, chapterId). // One key may correspond to multiple values, which are contained by a slice. func (x *ActivityConf) FindAwardMap2(activityId uint64, chapterId uint32) ActivityConf_Index_AwardMap { return x.indexAwardMap2[ActivityConf_LevelIndex_Activity_ChapterKey{activityId, chapterId}] } -// FindAward2 finds a slice of all values of the given key in the 2-level map +// FindAward2 finds a slice of all values of the given key in the 2nd-level map // specified by (activityId, chapterId). func (x *ActivityConf) FindAward2(activityId uint64, chapterId uint32, id uint32) []*protoconf.Section_SectionItem { return x.FindAwardMap2(activityId, chapterId)[id] } -// FindFirstAward2 finds the first value of the given key in the 2-level map +// FindFirstAward2 finds the first value of the given key in the 2nd-level map // specified by (activityId, chapterId), or nil if no value found. func (x *ActivityConf) FindFirstAward2(activityId uint64, chapterId uint32, id uint32) *protoconf.Section_SectionItem { val := x.FindAward2(activityId, chapterId, id) @@ -540,7 +540,7 @@ func (x *ChapterConf) Data() *protoconf.ChapterConf { return nil } -// Load fills ChapterConf's inner message from file in the specified directory and format. +// Load loads ChapterConf's content in the given dir, based on format and messager options. func (x *ChapterConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -557,7 +557,7 @@ func (x *ChapterConf) Load(dir string, format format.Format, opts *load.Messager return x.processAfterLoad() } -// Store writes ChapterConf's inner message to file in the specified directory and format. +// Store stores ChapterConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *ChapterConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -581,7 +581,7 @@ func (x *ChapterConf) originalMessage() proto.Message { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *ChapterConf) Get1(id uint64) (*protoconf.ChapterConf_Chapter, error) { d := x.Data().GetChapterMap() @@ -617,7 +617,7 @@ func (x *ThemeConf) Data() *protoconf.ThemeConf { return nil } -// Load fills ThemeConf's inner message from file in the specified directory and format. +// Load loads ThemeConf's content in the given dir, based on format and messager options. func (x *ThemeConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -634,7 +634,7 @@ func (x *ThemeConf) Load(dir string, format format.Format, opts *load.MessagerOp return x.processAfterLoad() } -// Store writes ThemeConf's inner message to file in the specified directory and format. +// Store stores ThemeConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *ThemeConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -658,7 +658,7 @@ func (x *ThemeConf) originalMessage() proto.Message { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *ThemeConf) Get1(name string) (*protoconf.ThemeConf_Theme, error) { d := x.Data().GetThemeMap() @@ -669,7 +669,7 @@ func (x *ThemeConf) Get1(name string) (*protoconf.ThemeConf_Theme, error) { } } -// Get2 finds value in the 2-level map. It will return +// Get2 finds value in the 2nd-level map. It will return // NotFound error if the key is not found. func (x *ThemeConf) Get2(name string, param string) (string, error) { conf, err := x.Get1(name) @@ -743,7 +743,7 @@ func (x *TaskConf) Data() *protoconf.TaskConf { return nil } -// Load fills TaskConf's inner message from file in the specified directory and format. +// Load loads TaskConf's content in the given dir, based on format and messager options. func (x *TaskConf) Load(dir string, format format.Format, opts *load.MessagerOptions) error { start := time.Now() defer func() { @@ -760,7 +760,7 @@ func (x *TaskConf) Load(dir string, format format.Format, opts *load.MessagerOpt return x.processAfterLoad() } -// Store writes TaskConf's inner message to file in the specified directory and format. +// Store stores TaskConf's content to file in the specified directory and format. // Available formats: JSON, Bin, and Text. func (x *TaskConf) Store(dir string, format format.Format, options ...store.Option) error { return store.Store(x.Data(), dir, format, options...) @@ -866,7 +866,7 @@ func (x *TaskConf) processAfterLoad() error { return nil } -// Get1 finds value in the 1-level map. It will return +// Get1 finds value in the 1st-level map. It will return // NotFound error if the key is not found. func (x *TaskConf) Get1(id int64) (*protoconf.TaskConf_Task, error) { d := x.Data().GetTaskMap() @@ -879,7 +879,7 @@ func (x *TaskConf) Get1(id int64) (*protoconf.TaskConf_Task, error) { // Index: ActivityID -// FindTaskMap finds the index (ActivityID) to value (protoconf.TaskConf_Task) map. +// FindTaskMap finds the index key (ActivityID) to value (protoconf.TaskConf_Task) map. // One key may correspond to multiple values, which are contained by a slice. func (x *TaskConf) FindTaskMap() TaskConf_Index_TaskMap { return x.indexTaskMap @@ -902,7 +902,7 @@ func (x *TaskConf) FindFirstTask(activityId int64) *protoconf.TaskConf_Task { // OrderedIndex: Goal@OrderedTask -// FindOrderedTaskMap finds the ordered index (Goal@OrderedTask) to value (protoconf.TaskConf_Task) treemap. +// FindOrderedTaskMap finds the ordered index key (Goal@OrderedTask) to value (protoconf.TaskConf_Task) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *TaskConf) FindOrderedTaskMap() *TaskConf_OrderedIndex_OrderedTaskMap { return x.orderedIndexOrderedTaskMap @@ -926,7 +926,7 @@ func (x *TaskConf) FindFirstOrderedTask(goal int64) *protoconf.TaskConf_Task { // OrderedIndex: Expiry@TaskExpiry -// FindTaskExpiryMap finds the ordered index (Expiry@TaskExpiry) to value (protoconf.TaskConf_Task) treemap. +// FindTaskExpiryMap finds the ordered index key (Expiry@TaskExpiry) to value (protoconf.TaskConf_Task) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *TaskConf) FindTaskExpiryMap() *TaskConf_OrderedIndex_TaskExpiryMap { return x.orderedIndexTaskExpiryMap @@ -950,7 +950,7 @@ func (x *TaskConf) FindFirstTaskExpiry(expiry int64) *protoconf.TaskConf_Task { // OrderedIndex: Expiry@SortedTaskExpiry -// FindSortedTaskExpiryMap finds the ordered index (Expiry@SortedTaskExpiry) to value (protoconf.TaskConf_Task) treemap. +// FindSortedTaskExpiryMap finds the ordered index key (Expiry@SortedTaskExpiry) to value (protoconf.TaskConf_Task) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *TaskConf) FindSortedTaskExpiryMap() *TaskConf_OrderedIndex_SortedTaskExpiryMap { return x.orderedIndexSortedTaskExpiryMap @@ -974,7 +974,7 @@ func (x *TaskConf) FindFirstSortedTaskExpiry(expiry int64) *protoconf.TaskConf_T // OrderedIndex: (Expiry,ActivityID)@ActivityExpiry -// FindActivityExpiryMap finds the ordered index ((Expiry,ActivityID)@ActivityExpiry) to value (protoconf.TaskConf_Task) treemap. +// FindActivityExpiryMap finds the ordered index key ((Expiry,ActivityID)@ActivityExpiry) to value (protoconf.TaskConf_Task) treemap. // One key may correspond to multiple values, which are contained by a slice. func (x *TaskConf) FindActivityExpiryMap() *TaskConf_OrderedIndex_ActivityExpiryMap { return x.orderedIndexActivityExpiryMap From 29df30e80be3a4b99abd181d6019a80f865218a3 Mon Sep 17 00:00:00 2001 From: wenchy Date: Thu, 11 Dec 2025 21:36:41 +0800 Subject: [PATCH 14/15] feat: improve index comments --- .../indexes/index.go | 15 +-- .../indexes/ordered_index.go | 15 +-- .../indexes/index.go | 18 +-- .../indexes/orderedindex.go | 18 +-- .../src/protoconf/index_conf.pc.h | 58 ++++----- .../src/protoconf/item_conf.pc.h | 48 ++++---- .../src/protoconf/test_conf.pc.h | 76 ++++++------ .../protoconf/loader/hero_conf.pc.go | 18 +-- .../protoconf/loader/index_conf.pc.go | 86 +++++++------- .../protoconf/loader/item_conf.pc.go | 96 +++++++-------- .../protoconf/loader/test_conf.pc.go | 112 +++++++++--------- 11 files changed, 281 insertions(+), 279 deletions(-) diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go index 5bb9dc6f..689f1ab8 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/index.go @@ -8,6 +8,7 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/loadutil" "github.com/tableauio/loader/internal/options" ) @@ -96,8 +97,8 @@ func (x *Generator) genHppIndexFinders() { } x.g.P(helper.Indent(1), "using ", vectorType, " = std::vector;") x.g.P(helper.Indent(1), "using ", mapType, " = std::unordered_map<", keyType, ", ", vectorType, hasher, ">;") - x.g.P(helper.Indent(1), "// Finds the index (", index.Index, ") to value (", vectorType, ") hash map.") - x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") + x.g.P(helper.Indent(1), "// Finds the index: key(", index.Index, ") to value(", vectorType, ") hashmap.") + x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are represented by a vector.") x.g.P(helper.Indent(1), "const ", mapType, "& Find", index.Name(), "Map() const;") x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s).") x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") @@ -108,13 +109,13 @@ func (x *Generator) genHppIndexFinders() { break } partKeys := x.keys[:i] - x.g.P(helper.Indent(1), "// Finds the index (", index.Index, ") to value (", vectorType, ") hash map") - x.g.P(helper.Indent(1), "// specified by (", partKeys.GenGetArguments(), ").") - x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") + x.g.P(helper.Indent(1), "// Finds the index: key(", index.Index, ") to value(", vectorType, "),") + x.g.P(helper.Indent(1), "// which is the upper ", loadutil.Ordinal(i), "-level hashmap specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are represented by a vector.") x.g.P(helper.Indent(1), "const ", mapType, "* Find", index.Name(), "Map(", partKeys.GenGetParams(), ") const;") - x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s) in the upper ", loadutil.Ordinal(i), "-level hashmap specified by (", partKeys.GenGetArguments(), ").") x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") - x.g.P(helper.Indent(1), "// Finds the first value of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// Finds the first value of the given key(s) in the upper ", loadutil.Ordinal(i), "-level hashmap specified by (", partKeys.GenGetArguments(), ").") x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") } x.g.P() diff --git a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go index 7ecccb9d..365482fb 100644 --- a/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go +++ b/cmd/protoc-gen-cpp-tableau-loader/indexes/ordered_index.go @@ -8,6 +8,7 @@ import ( "github.com/iancoleman/strcase" "github.com/tableauio/loader/cmd/protoc-gen-cpp-tableau-loader/helper" "github.com/tableauio/loader/internal/index" + "github.com/tableauio/loader/internal/loadutil" "github.com/tableauio/loader/internal/options" ) @@ -86,8 +87,8 @@ func (x *Generator) genHppOrderedIndexFinders() { } x.g.P(helper.Indent(1), "using ", vectorType, " = std::vector;") x.g.P(helper.Indent(1), "using ", mapType, " = std::map<", keyType, ", ", vectorType, ">;") - x.g.P(helper.Indent(1), "// Finds the ordered index (", index.Index, ") to value (", vectorType, ") map.") - x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") + x.g.P(helper.Indent(1), "// Finds the ordered index: key(", index.Index, ") to value(", vectorType, ") map.") + x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are represented by a vector.") x.g.P(helper.Indent(1), "const ", mapType, "& Find", index.Name(), "Map() const;") x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s).") x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", keys.GenGetParams(), ") const;") @@ -98,13 +99,13 @@ func (x *Generator) genHppOrderedIndexFinders() { break } partKeys := x.keys[:i] - x.g.P(helper.Indent(1), "// Finds the ordered index (", index.Index, ") to value (", vectorType, ") map") - x.g.P(helper.Indent(1), "// specified by (", partKeys.GenGetArguments(), ").") - x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are contained by a vector.") + x.g.P(helper.Indent(1), "// Finds the ordered index: key(", index.Index, ") to value(", vectorType, "),") + x.g.P(helper.Indent(1), "// which is the upper ", loadutil.Ordinal(i), "-level map specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// One key may correspond to multiple values, which are represented by a vector.") x.g.P(helper.Indent(1), "const ", mapType, "* Find", index.Name(), "Map(", partKeys.GenGetParams(), ") const;") - x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// Finds a vector of all values of the given key(s) in the upper ", loadutil.Ordinal(i), "-level map specified by (", partKeys.GenGetArguments(), ").") x.g.P(helper.Indent(1), "const ", vectorType, "* Find", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") - x.g.P(helper.Indent(1), "// Finds the first value of the given key(s) specified by (", partKeys.GenGetArguments(), ").") + x.g.P(helper.Indent(1), "// Finds the first value of the given key(s) in the upper ", loadutil.Ordinal(i), "-level map specified by (", partKeys.GenGetArguments(), ").") x.g.P(helper.Indent(1), "const ", valueType, "* FindFirst", index.Name(), "(", partKeys.GenGetParams(), ", ", keys.GenGetParams(), ") const;") } x.g.P() diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/index.go b/cmd/protoc-gen-go-tableau-loader/indexes/index.go index 3f02acff..c464ff60 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/index.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/index.go @@ -269,8 +269,8 @@ func (x *Generator) genIndexFinders() { x.g.P("// Index: ", index.Index) x.g.P() - x.g.P("// Find", index.Name(), "Map finds the index key (", index.Index, ") to value (", x.mapValueType(index), ") map.") - x.g.P("// One key may correspond to multiple values, which are contained by a slice.") + x.g.P("// Find", index.Name(), "Map finds the index: key(", index.Index, ") to value(", x.mapValueType(index), ") map.") + x.g.P("// One key may correspond to multiple values, which are represented by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() ", x.indexMapType(index), " {") x.g.P("return x.", indexContainerName) x.g.P("}") @@ -279,7 +279,7 @@ func (x *Generator) genIndexFinders() { keys := x.indexKeys(index) params := keys.GenGetParams() args := keys.GenGetArguments() - x.g.P("// Find", index.Name(), " finds a slice of all values of the given key.") + x.g.P("// Find", index.Name(), " finds a slice of all values of the given key(s).") x.g.P("func (x *", messagerName, ") Find", index.Name(), "(", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { x.g.P("return x.", indexContainerName, "[", args, "]") @@ -289,7 +289,7 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), " finds the first value of the given key,") + x.g.P("// FindFirst", index.Name(), " finds the first value of the given key(s),") x.g.P("// or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), "(", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), "(", args, ")") @@ -309,9 +309,9 @@ func (x *Generator) genIndexFinders() { partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() - x.g.P("// Find", index.Name(), "Map", i, " finds the index key (", index.Index, ") to value (", x.mapValueType(index), "),") - x.g.P("// which is the ", loadutil.Ordinal(i), "-level map specified by (", partArgs, ").") - x.g.P("// One key may correspond to multiple values, which are contained by a slice.") + x.g.P("// Find", index.Name(), "Map", i, " finds the index: key(", index.Index, ") to value(", x.mapValueType(index), "),") + x.g.P("// which is the upper ", loadutil.Ordinal(i), "-level map specified by (", partArgs, ").") + x.g.P("// One key may correspond to multiple values, which are represented by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") ", x.indexMapType(index), " {") if len(partKeys) == 1 { x.g.P("return x.", indexContainerName, "[", partArgs, "]") @@ -322,7 +322,7 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", loadutil.Ordinal(i), "-level map") + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key(s) in the upper ", loadutil.Ordinal(i), "-level map") x.g.P("// specified by (", partArgs, ").") x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { @@ -333,7 +333,7 @@ func (x *Generator) genIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", loadutil.Ordinal(i), "-level map") + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key(s) in the upper ", loadutil.Ordinal(i), "-level map") x.g.P("// specified by (", partArgs, "), or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") diff --git a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go index 9d015a11..b11fc1d8 100644 --- a/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go +++ b/cmd/protoc-gen-go-tableau-loader/indexes/orderedindex.go @@ -300,8 +300,8 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("// OrderedIndex: ", index.Index) x.g.P() - x.g.P("// Find", index.Name(), "Map finds the ordered index key (", index.Index, ") to value (", x.mapValueType(index), ") treemap.") - x.g.P("// One key may correspond to multiple values, which are contained by a slice.") + x.g.P("// Find", index.Name(), "Map finds the ordered index: key(", index.Index, ") to value(", x.mapValueType(index), ") treemap.") + x.g.P("// One key may correspond to multiple values, which are represented by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map() *", x.orderedIndexMapType(index), " {") x.g.P("return x.", indexContainerName) x.g.P("}") @@ -310,7 +310,7 @@ func (x *Generator) genOrderedIndexFinders() { keys := x.orderedIndexKeys(index) params := keys.GenGetParams() args := keys.GenGetArguments() - x.g.P("// Find", index.Name(), " finds a slice of all values of the given key.") + x.g.P("// Find", index.Name(), " finds a slice of all values of the given key(s).") x.g.P("func (x *", messagerName, ") Find", index.Name(), "(", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { x.g.P("val, _ := x.", indexContainerName, ".Get(", args, ")") @@ -321,7 +321,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), " finds the first value of the given key,") + x.g.P("// FindFirst", index.Name(), " finds the first value of the given key(s),") x.g.P("// or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), "(", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), "(", args, ")") @@ -341,9 +341,9 @@ func (x *Generator) genOrderedIndexFinders() { partParams := partKeys.GenGetParams() partArgs := partKeys.GenGetArguments() - x.g.P("// Find", index.Name(), "Map", i, " finds the index key (", index.Index, ") to value (", x.mapValueType(index), "),") - x.g.P("// which is the ", loadutil.Ordinal(i), "-level treemap specified by (", partArgs, ").") - x.g.P("// One key may correspond to multiple values, which are contained by a slice.") + x.g.P("// Find", index.Name(), "Map", i, " finds the index: key(", index.Index, ") to value(", x.mapValueType(index), "),") + x.g.P("// which is the upper ", loadutil.Ordinal(i), "-level treemap specified by (", partArgs, ").") + x.g.P("// One key may correspond to multiple values, which are represented by a slice.") x.g.P("func (x *", messagerName, ") Find", index.Name(), "Map", i, "(", partParams, ") *", x.orderedIndexMapType(index), " {") if len(partKeys) == 1 { x.g.P("return x.", orderedIndexContainerName, "[", partArgs, "]") @@ -354,7 +354,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key in the ", loadutil.Ordinal(i), "-level treemap") + x.g.P("// Find", index.Name(), i, " finds a slice of all values of the given key(s) in the upper ", loadutil.Ordinal(i), "-level treemap") x.g.P("// specified by (", partArgs, ").") x.g.P("func (x *", messagerName, ") Find", index.Name(), i, "(", partParams, ", ", params, ") []*", x.mapValueType(index), " {") if len(index.ColFields) == 1 { @@ -366,7 +366,7 @@ func (x *Generator) genOrderedIndexFinders() { x.g.P("}") x.g.P() - x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key in the ", loadutil.Ordinal(i), "-level treemap") + x.g.P("// FindFirst", index.Name(), i, " finds the first value of the given key(s) in the upper ", loadutil.Ordinal(i), "-level treemap") x.g.P("// specified by (", partArgs, "), or nil if no value found.") x.g.P("func (x *", messagerName, ") FindFirst", index.Name(), i, "(", partParams, ", ", params, ") *", x.mapValueType(index), " {") x.g.P("val := x.Find", index.Name(), i, "(", partArgs, ", ", args, ")") diff --git a/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h index 2aed90c4..230d03d3 100644 --- a/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/index_conf.pc.h @@ -36,20 +36,20 @@ class FruitConf : public Messager { public: using OrderedIndex_ItemVector = std::vector; using OrderedIndex_ItemMap = std::map; - // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(Price) to value(OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ItemMap& FindItemMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ItemVector* FindItem(int32_t price) const; // Finds the first value of the given key(s). const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t price) const; - // Finds the ordered index (Price) to value (OrderedIndex_ItemVector) map - // specified by (fruit_type). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(Price) to value(OrderedIndex_ItemVector), + // which is the upper 1st-level map specified by (fruit_type). + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; - // Finds a vector of all values of the given key(s) specified by (fruit_type). + // Finds a vector of all values of the given key(s) in the upper 1st-level map specified by (fruit_type). const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; - // Finds the first value of the given key(s) specified by (fruit_type). + // Finds the first value of the given key(s) in the upper 1st-level map specified by (fruit_type). const protoconf::FruitConf::Fruit::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; private: @@ -79,8 +79,8 @@ class Fruit2Conf : public Messager { public: using Index_CountryVector = std::vector; using Index_CountryMap = std::unordered_map; - // Finds the index (CountryName) to value (Index_CountryVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(CountryName) to value(Index_CountryVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_CountryMap& FindCountryMap() const; // Finds a vector of all values of the given key(s). const Index_CountryVector* FindCountry(const std::string& name) const; @@ -94,20 +94,20 @@ class Fruit2Conf : public Messager { public: using Index_AttrVector = std::vector; using Index_AttrMap = std::unordered_map; - // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(CountryItemAttrName) to value(Index_AttrVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_AttrMap& FindAttrMap() const; // Finds a vector of all values of the given key(s). const Index_AttrVector* FindAttr(const std::string& name) const; // Finds the first value of the given key(s). const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(const std::string& name) const; - // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map - // specified by (fruit_type). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(CountryItemAttrName) to value(Index_AttrVector), + // which is the upper 1st-level hashmap specified by (fruit_type). + // One key may correspond to multiple values, which are represented by a vector. const Index_AttrMap* FindAttrMap(int32_t fruit_type) const; - // Finds a vector of all values of the given key(s) specified by (fruit_type). + // Finds a vector of all values of the given key(s) in the upper 1st-level hashmap specified by (fruit_type). const Index_AttrVector* FindAttr(int32_t fruit_type, const std::string& name) const; - // Finds the first value of the given key(s) specified by (fruit_type). + // Finds the first value of the given key(s) in the upper 1st-level hashmap specified by (fruit_type). const protoconf::Fruit2Conf::Fruit::Country::Item::Attr* FindFirstAttr(int32_t fruit_type, const std::string& name) const; private: @@ -119,20 +119,20 @@ class Fruit2Conf : public Messager { public: using OrderedIndex_ItemVector = std::vector; using OrderedIndex_ItemMap = std::map; - // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(CountryItemPrice) to value(OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ItemMap& FindItemMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ItemVector* FindItem(int32_t price) const; // Finds the first value of the given key(s). const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t price) const; - // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map - // specified by (fruit_type). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(CountryItemPrice) to value(OrderedIndex_ItemVector), + // which is the upper 1st-level map specified by (fruit_type). + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ItemMap* FindItemMap(int32_t fruit_type) const; - // Finds a vector of all values of the given key(s) specified by (fruit_type). + // Finds a vector of all values of the given key(s) in the upper 1st-level map specified by (fruit_type). const OrderedIndex_ItemVector* FindItem(int32_t fruit_type, int32_t price) const; - // Finds the first value of the given key(s) specified by (fruit_type). + // Finds the first value of the given key(s) in the upper 1st-level map specified by (fruit_type). const protoconf::Fruit2Conf::Fruit::Country::Item* FindFirstItem(int32_t fruit_type, int32_t price) const; private: @@ -160,8 +160,8 @@ class Fruit3Conf : public Messager { public: using Index_CountryVector = std::vector; using Index_CountryMap = std::unordered_map; - // Finds the index (CountryName) to value (Index_CountryVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(CountryName) to value(Index_CountryVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_CountryMap& FindCountryMap() const; // Finds a vector of all values of the given key(s). const Index_CountryVector* FindCountry(const std::string& name) const; @@ -175,8 +175,8 @@ class Fruit3Conf : public Messager { public: using Index_AttrVector = std::vector; using Index_AttrMap = std::unordered_map; - // Finds the index (CountryItemAttrName) to value (Index_AttrVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(CountryItemAttrName) to value(Index_AttrVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_AttrMap& FindAttrMap() const; // Finds a vector of all values of the given key(s). const Index_AttrVector* FindAttr(const std::string& name) const; @@ -191,8 +191,8 @@ class Fruit3Conf : public Messager { public: using OrderedIndex_ItemVector = std::vector; using OrderedIndex_ItemMap = std::map; - // Finds the ordered index (CountryItemPrice) to value (OrderedIndex_ItemVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(CountryItemPrice) to value(OrderedIndex_ItemVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ItemMap& FindItemMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ItemVector* FindItem(int32_t price) const; diff --git a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h index a7353b6d..543816b2 100644 --- a/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/item_conf.pc.h @@ -43,8 +43,8 @@ class ItemConf : public Messager { public: using Index_ItemVector = std::vector; using Index_ItemMap = std::unordered_map; - // Finds the index (Type) to value (Index_ItemVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(Type) to value(Index_ItemVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemMap& FindItemMap() const; // Finds a vector of all values of the given key(s). const Index_ItemVector* FindItem(protoconf::FruitType type) const; @@ -58,8 +58,8 @@ class ItemConf : public Messager { public: using Index_ItemInfoVector = std::vector; using Index_ItemInfoMap = std::unordered_map; - // Finds the index (Param@ItemInfo) to value (Index_ItemInfoVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(Param@ItemInfo) to value(Index_ItemInfoVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemInfoMap& FindItemInfoMap() const; // Finds a vector of all values of the given key(s). const Index_ItemInfoVector* FindItemInfo(int32_t param) const; @@ -73,8 +73,8 @@ class ItemConf : public Messager { public: using Index_ItemDefaultInfoVector = std::vector; using Index_ItemDefaultInfoMap = std::unordered_map; - // Finds the index (Default@ItemDefaultInfo) to value (Index_ItemDefaultInfoVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(Default@ItemDefaultInfo) to value(Index_ItemDefaultInfoVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemDefaultInfoMap& FindItemDefaultInfoMap() const; // Finds a vector of all values of the given key(s). const Index_ItemDefaultInfoVector* FindItemDefaultInfo(const std::string& default_) const; @@ -88,8 +88,8 @@ class ItemConf : public Messager { public: using Index_ItemExtInfoVector = std::vector; using Index_ItemExtInfoMap = std::unordered_map; - // Finds the index (ExtType@ItemExtInfo) to value (Index_ItemExtInfoVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ExtType@ItemExtInfo) to value(Index_ItemExtInfoVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemExtInfoMap& FindItemExtInfoMap() const; // Finds a vector of all values of the given key(s). const Index_ItemExtInfoVector* FindItemExtInfo(protoconf::FruitType ext_type) const; @@ -119,8 +119,8 @@ class ItemConf : public Messager { }; using Index_AwardItemVector = std::vector; using Index_AwardItemMap = std::unordered_map; - // Finds the index ((ID,Name)@AwardItem) to value (Index_AwardItemVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key((ID,Name)@AwardItem) to value(Index_AwardItemVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_AwardItemMap& FindAwardItemMap() const; // Finds a vector of all values of the given key(s). const Index_AwardItemVector* FindAwardItem(uint32_t id, const std::string& name) const; @@ -152,8 +152,8 @@ class ItemConf : public Messager { }; using Index_SpecialItemVector = std::vector; using Index_SpecialItemMap = std::unordered_map; - // Finds the index ((ID,Type,Param,ExtType)@SpecialItem) to value (Index_SpecialItemVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key((ID,Type,Param,ExtType)@SpecialItem) to value(Index_SpecialItemVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_SpecialItemMap& FindSpecialItemMap() const; // Finds a vector of all values of the given key(s). const Index_SpecialItemVector* FindSpecialItem(uint32_t id, protoconf::FruitType type, int32_t param, protoconf::FruitType ext_type) const; @@ -167,8 +167,8 @@ class ItemConf : public Messager { public: using Index_ItemPathDirVector = std::vector; using Index_ItemPathDirMap = std::unordered_map; - // Finds the index (PathDir@ItemPathDir) to value (Index_ItemPathDirVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(PathDir@ItemPathDir) to value(Index_ItemPathDirVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemPathDirMap& FindItemPathDirMap() const; // Finds a vector of all values of the given key(s). const Index_ItemPathDirVector* FindItemPathDir(const std::string& dir) const; @@ -182,8 +182,8 @@ class ItemConf : public Messager { public: using Index_ItemPathNameVector = std::vector; using Index_ItemPathNameMap = std::unordered_map; - // Finds the index (PathName@ItemPathName) to value (Index_ItemPathNameVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(PathName@ItemPathName) to value(Index_ItemPathNameVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemPathNameMap& FindItemPathNameMap() const; // Finds a vector of all values of the given key(s). const Index_ItemPathNameVector* FindItemPathName(const std::string& name) const; @@ -197,8 +197,8 @@ class ItemConf : public Messager { public: using Index_ItemPathFriendIDVector = std::vector; using Index_ItemPathFriendIDMap = std::unordered_map; - // Finds the index (PathFriendID@ItemPathFriendID) to value (Index_ItemPathFriendIDVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(PathFriendID@ItemPathFriendID) to value(Index_ItemPathFriendIDVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ItemPathFriendIDMap& FindItemPathFriendIDMap() const; // Finds a vector of all values of the given key(s). const Index_ItemPathFriendIDVector* FindItemPathFriendID(uint32_t id) const; @@ -212,8 +212,8 @@ class ItemConf : public Messager { public: using Index_UseEffectTypeVector = std::vector; using Index_UseEffectTypeMap = std::unordered_map; - // Finds the index (UseEffectType@UseEffectType) to value (Index_UseEffectTypeVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(UseEffectType@UseEffectType) to value(Index_UseEffectTypeVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_UseEffectTypeMap& FindUseEffectTypeMap() const; // Finds a vector of all values of the given key(s). const Index_UseEffectTypeVector* FindUseEffectType(protoconf::UseEffect::Type type) const; @@ -228,8 +228,8 @@ class ItemConf : public Messager { public: using OrderedIndex_ExtTypeVector = std::vector; using OrderedIndex_ExtTypeMap = std::map; - // Finds the ordered index (ExtType@ExtType) to value (OrderedIndex_ExtTypeVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(ExtType@ExtType) to value(OrderedIndex_ExtTypeVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ExtTypeMap& FindExtTypeMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ExtTypeVector* FindExtType(protoconf::FruitType ext_type) const; @@ -254,8 +254,8 @@ class ItemConf : public Messager { }; using OrderedIndex_ParamExtTypeVector = std::vector; using OrderedIndex_ParamExtTypeMap = std::map; - // Finds the ordered index ((Param,ExtType)@ParamExtType) to value (OrderedIndex_ParamExtTypeVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key((Param,ExtType)@ParamExtType) to value(OrderedIndex_ParamExtTypeVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ParamExtTypeMap& FindParamExtTypeMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ParamExtTypeVector* FindParamExtType(int32_t param, protoconf::FruitType ext_type) const; diff --git a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h index 82847c28..c6b68a68 100644 --- a/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h +++ b/test/cpp-tableau-loader/src/protoconf/test_conf.pc.h @@ -77,8 +77,8 @@ class ActivityConf : public Messager { public: using Index_ActivityVector = std::vector; using Index_ActivityMap = std::unordered_map; - // Finds the index (ActivityName) to value (Index_ActivityVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ActivityName) to value(Index_ActivityVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ActivityMap& FindActivityMap() const; // Finds a vector of all values of the given key(s). const Index_ActivityVector* FindActivity(const std::string& activity_name) const; @@ -92,20 +92,20 @@ class ActivityConf : public Messager { public: using Index_ChapterVector = std::vector; using Index_ChapterMap = std::unordered_map; - // Finds the index (ChapterID) to value (Index_ChapterVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ChapterID) to value(Index_ChapterVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_ChapterMap& FindChapterMap() const; // Finds a vector of all values of the given key(s). const Index_ChapterVector* FindChapter(uint32_t chapter_id) const; // Finds the first value of the given key(s). const protoconf::ActivityConf::Activity::Chapter* FindFirstChapter(uint32_t chapter_id) const; - // Finds the index (ChapterID) to value (Index_ChapterVector) hash map - // specified by (activity_id). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ChapterID) to value(Index_ChapterVector), + // which is the upper 1st-level hashmap specified by (activity_id). + // One key may correspond to multiple values, which are represented by a vector. const Index_ChapterMap* FindChapterMap(uint64_t activity_id) const; - // Finds a vector of all values of the given key(s) specified by (activity_id). + // Finds a vector of all values of the given key(s) in the upper 1st-level hashmap specified by (activity_id). const Index_ChapterVector* FindChapter(uint64_t activity_id, uint32_t chapter_id) const; - // Finds the first value of the given key(s) specified by (activity_id). + // Finds the first value of the given key(s) in the upper 1st-level hashmap specified by (activity_id). const protoconf::ActivityConf::Activity::Chapter* FindFirstChapter(uint64_t activity_id, uint32_t chapter_id) const; private: @@ -116,20 +116,20 @@ class ActivityConf : public Messager { public: using Index_NamedChapterVector = std::vector; using Index_NamedChapterMap = std::unordered_map; - // Finds the index (ChapterName@NamedChapter) to value (Index_NamedChapterVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ChapterName@NamedChapter) to value(Index_NamedChapterVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_NamedChapterMap& FindNamedChapterMap() const; // Finds a vector of all values of the given key(s). const Index_NamedChapterVector* FindNamedChapter(const std::string& chapter_name) const; // Finds the first value of the given key(s). const protoconf::ActivityConf::Activity::Chapter* FindFirstNamedChapter(const std::string& chapter_name) const; - // Finds the index (ChapterName@NamedChapter) to value (Index_NamedChapterVector) hash map - // specified by (activity_id). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ChapterName@NamedChapter) to value(Index_NamedChapterVector), + // which is the upper 1st-level hashmap specified by (activity_id). + // One key may correspond to multiple values, which are represented by a vector. const Index_NamedChapterMap* FindNamedChapterMap(uint64_t activity_id) const; - // Finds a vector of all values of the given key(s) specified by (activity_id). + // Finds a vector of all values of the given key(s) in the upper 1st-level hashmap specified by (activity_id). const Index_NamedChapterVector* FindNamedChapter(uint64_t activity_id, const std::string& chapter_name) const; - // Finds the first value of the given key(s) specified by (activity_id). + // Finds the first value of the given key(s) in the upper 1st-level hashmap specified by (activity_id). const protoconf::ActivityConf::Activity::Chapter* FindFirstNamedChapter(uint64_t activity_id, const std::string& chapter_name) const; private: @@ -140,28 +140,28 @@ class ActivityConf : public Messager { public: using Index_AwardVector = std::vector; using Index_AwardMap = std::unordered_map; - // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(SectionItemID@Award) to value(Index_AwardVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_AwardMap& FindAwardMap() const; // Finds a vector of all values of the given key(s). const Index_AwardVector* FindAward(uint32_t id) const; // Finds the first value of the given key(s). const protoconf::Section::SectionItem* FindFirstAward(uint32_t id) const; - // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map - // specified by (activity_id). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(SectionItemID@Award) to value(Index_AwardVector), + // which is the upper 1st-level hashmap specified by (activity_id). + // One key may correspond to multiple values, which are represented by a vector. const Index_AwardMap* FindAwardMap(uint64_t activity_id) const; - // Finds a vector of all values of the given key(s) specified by (activity_id). + // Finds a vector of all values of the given key(s) in the upper 1st-level hashmap specified by (activity_id). const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t id) const; - // Finds the first value of the given key(s) specified by (activity_id). + // Finds the first value of the given key(s) in the upper 1st-level hashmap specified by (activity_id). const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t id) const; - // Finds the index (SectionItemID@Award) to value (Index_AwardVector) hash map - // specified by (activity_id, chapter_id). - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(SectionItemID@Award) to value(Index_AwardVector), + // which is the upper 2nd-level hashmap specified by (activity_id, chapter_id). + // One key may correspond to multiple values, which are represented by a vector. const Index_AwardMap* FindAwardMap(uint64_t activity_id, uint32_t chapter_id) const; - // Finds a vector of all values of the given key(s) specified by (activity_id, chapter_id). + // Finds a vector of all values of the given key(s) in the upper 2nd-level hashmap specified by (activity_id, chapter_id). const Index_AwardVector* FindAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const; - // Finds the first value of the given key(s) specified by (activity_id, chapter_id). + // Finds the first value of the given key(s) in the upper 2nd-level hashmap specified by (activity_id, chapter_id). const protoconf::Section::SectionItem* FindFirstAward(uint64_t activity_id, uint32_t chapter_id, uint32_t id) const; private: @@ -223,8 +223,8 @@ class TaskConf : public Messager { public: using Index_TaskVector = std::vector; using Index_TaskMap = std::unordered_map; - // Finds the index (ActivityID) to value (Index_TaskVector) hash map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the index: key(ActivityID) to value(Index_TaskVector) hashmap. + // One key may correspond to multiple values, which are represented by a vector. const Index_TaskMap& FindTaskMap() const; // Finds a vector of all values of the given key(s). const Index_TaskVector* FindTask(int64_t activity_id) const; @@ -239,8 +239,8 @@ class TaskConf : public Messager { public: using OrderedIndex_OrderedTaskVector = std::vector; using OrderedIndex_OrderedTaskMap = std::map; - // Finds the ordered index (Goal@OrderedTask) to value (OrderedIndex_OrderedTaskVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(Goal@OrderedTask) to value(OrderedIndex_OrderedTaskVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_OrderedTaskMap& FindOrderedTaskMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_OrderedTaskVector* FindOrderedTask(int64_t goal) const; @@ -254,8 +254,8 @@ class TaskConf : public Messager { public: using OrderedIndex_TaskExpiryVector = std::vector; using OrderedIndex_TaskExpiryMap = std::map; - // Finds the ordered index (Expiry@TaskExpiry) to value (OrderedIndex_TaskExpiryVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(Expiry@TaskExpiry) to value(OrderedIndex_TaskExpiryVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_TaskExpiryMap& FindTaskExpiryMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_TaskExpiryVector* FindTaskExpiry(int64_t expiry) const; @@ -269,8 +269,8 @@ class TaskConf : public Messager { public: using OrderedIndex_SortedTaskExpiryVector = std::vector; using OrderedIndex_SortedTaskExpiryMap = std::map; - // Finds the ordered index (Expiry@SortedTaskExpiry) to value (OrderedIndex_SortedTaskExpiryVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key(Expiry@SortedTaskExpiry) to value(OrderedIndex_SortedTaskExpiryVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_SortedTaskExpiryMap& FindSortedTaskExpiryMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_SortedTaskExpiryVector* FindSortedTaskExpiry(int64_t expiry) const; @@ -295,8 +295,8 @@ class TaskConf : public Messager { }; using OrderedIndex_ActivityExpiryVector = std::vector; using OrderedIndex_ActivityExpiryMap = std::map; - // Finds the ordered index ((Expiry,ActivityID)@ActivityExpiry) to value (OrderedIndex_ActivityExpiryVector) map. - // One key may correspond to multiple values, which are contained by a vector. + // Finds the ordered index: key((Expiry,ActivityID)@ActivityExpiry) to value(OrderedIndex_ActivityExpiryVector) map. + // One key may correspond to multiple values, which are represented by a vector. const OrderedIndex_ActivityExpiryMap& FindActivityExpiryMap() const; // Finds a vector of all values of the given key(s). const OrderedIndex_ActivityExpiryVector* FindActivityExpiry(int64_t expiry, int64_t activity_id) const; diff --git a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go index 39b12f6d..3697f0b4 100644 --- a/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/hero_conf.pc.go @@ -142,18 +142,18 @@ func (x *HeroConf) Get2(name string, title string) (*protoconf.HeroConf_Hero_Att // Index: Title -// FindAttrMap finds the index key (Title) to value (protoconf.HeroConf_Hero_Attr) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindAttrMap finds the index: key(Title) to value(protoconf.HeroConf_Hero_Attr) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *HeroConf) FindAttrMap() HeroConf_Index_AttrMap { return x.indexAttrMap } -// FindAttr finds a slice of all values of the given key. +// FindAttr finds a slice of all values of the given key(s). func (x *HeroConf) FindAttr(title string) []*protoconf.HeroConf_Hero_Attr { return x.indexAttrMap[title] } -// FindFirstAttr finds the first value of the given key, +// FindFirstAttr finds the first value of the given key(s), // or nil if no value found. func (x *HeroConf) FindFirstAttr(title string) *protoconf.HeroConf_Hero_Attr { val := x.FindAttr(title) @@ -163,20 +163,20 @@ func (x *HeroConf) FindFirstAttr(title string) *protoconf.HeroConf_Hero_Attr { return nil } -// FindAttrMap1 finds the index key (Title) to value (protoconf.HeroConf_Hero_Attr), -// which is the 1st-level map specified by (name). -// One key may correspond to multiple values, which are contained by a slice. +// FindAttrMap1 finds the index: key(Title) to value(protoconf.HeroConf_Hero_Attr), +// which is the upper 1st-level map specified by (name). +// One key may correspond to multiple values, which are represented by a slice. func (x *HeroConf) FindAttrMap1(name string) HeroConf_Index_AttrMap { return x.indexAttrMap1[name] } -// FindAttr1 finds a slice of all values of the given key in the 1st-level map +// FindAttr1 finds a slice of all values of the given key(s) in the upper 1st-level map // specified by (name). func (x *HeroConf) FindAttr1(name string, title string) []*protoconf.HeroConf_Hero_Attr { return x.FindAttrMap1(name)[title] } -// FindFirstAttr1 finds the first value of the given key in the 1st-level map +// FindFirstAttr1 finds the first value of the given key(s) in the upper 1st-level map // specified by (name), or nil if no value found. func (x *HeroConf) FindFirstAttr1(name string, title string) *protoconf.HeroConf_Hero_Attr { val := x.FindAttr1(name, title) diff --git a/test/go-tableau-loader/protoconf/loader/index_conf.pc.go b/test/go-tableau-loader/protoconf/loader/index_conf.pc.go index f86fa45f..b645bc1d 100644 --- a/test/go-tableau-loader/protoconf/loader/index_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/index_conf.pc.go @@ -159,19 +159,19 @@ func (x *FruitConf) Get2(fruitType int32, id int32) (*protoconf.FruitConf_Fruit_ // OrderedIndex: Price -// FindItemMap finds the ordered index key (Price) to value (protoconf.FruitConf_Fruit_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemMap finds the ordered index: key(Price) to value(protoconf.FruitConf_Fruit_Item) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *FruitConf) FindItemMap() *FruitConf_OrderedIndex_ItemMap { return x.orderedIndexItemMap } -// FindItem finds a slice of all values of the given key. +// FindItem finds a slice of all values of the given key(s). func (x *FruitConf) FindItem(price int32) []*protoconf.FruitConf_Fruit_Item { val, _ := x.orderedIndexItemMap.Get(price) return val } -// FindFirstItem finds the first value of the given key, +// FindFirstItem finds the first value of the given key(s), // or nil if no value found. func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { val := x.FindItem(price) @@ -181,21 +181,21 @@ func (x *FruitConf) FindFirstItem(price int32) *protoconf.FruitConf_Fruit_Item { return nil } -// FindItemMap1 finds the index key (Price) to value (protoconf.FruitConf_Fruit_Item), -// which is the 1st-level treemap specified by (fruitType). -// One key may correspond to multiple values, which are contained by a slice. +// FindItemMap1 finds the index: key(Price) to value(protoconf.FruitConf_Fruit_Item), +// which is the upper 1st-level treemap specified by (fruitType). +// One key may correspond to multiple values, which are represented by a slice. func (x *FruitConf) FindItemMap1(fruitType int32) *FruitConf_OrderedIndex_ItemMap { return x.orderedIndexItemMap1[fruitType] } -// FindItem1 finds a slice of all values of the given key in the 1st-level treemap +// FindItem1 finds a slice of all values of the given key(s) in the upper 1st-level treemap // specified by (fruitType). func (x *FruitConf) FindItem1(fruitType int32, price int32) []*protoconf.FruitConf_Fruit_Item { val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstItem1 finds the first value of the given key in the 1st-level treemap +// FindFirstItem1 finds the first value of the given key(s) in the upper 1st-level treemap // specified by (fruitType), or nil if no value found. func (x *FruitConf) FindFirstItem1(fruitType int32, price int32) *protoconf.FruitConf_Fruit_Item { val := x.FindItem1(fruitType, price) @@ -371,18 +371,18 @@ func (x *Fruit2Conf) Get1(fruitType int32) (*protoconf.Fruit2Conf_Fruit, error) // Index: CountryName -// FindCountryMap finds the index key (CountryName) to value (protoconf.Fruit2Conf_Fruit_Country) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindCountryMap finds the index: key(CountryName) to value(protoconf.Fruit2Conf_Fruit_Country) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit2Conf) FindCountryMap() Fruit2Conf_Index_CountryMap { return x.indexCountryMap } -// FindCountry finds a slice of all values of the given key. +// FindCountry finds a slice of all values of the given key(s). func (x *Fruit2Conf) FindCountry(name string) []*protoconf.Fruit2Conf_Fruit_Country { return x.indexCountryMap[name] } -// FindFirstCountry finds the first value of the given key, +// FindFirstCountry finds the first value of the given key(s), // or nil if no value found. func (x *Fruit2Conf) FindFirstCountry(name string) *protoconf.Fruit2Conf_Fruit_Country { val := x.FindCountry(name) @@ -394,18 +394,18 @@ func (x *Fruit2Conf) FindFirstCountry(name string) *protoconf.Fruit2Conf_Fruit_C // Index: CountryItemAttrName -// FindAttrMap finds the index key (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindAttrMap finds the index: key(CountryItemAttrName) to value(protoconf.Fruit2Conf_Fruit_Country_Item_Attr) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit2Conf) FindAttrMap() Fruit2Conf_Index_AttrMap { return x.indexAttrMap } -// FindAttr finds a slice of all values of the given key. +// FindAttr finds a slice of all values of the given key(s). func (x *Fruit2Conf) FindAttr(name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { return x.indexAttrMap[name] } -// FindFirstAttr finds the first value of the given key, +// FindFirstAttr finds the first value of the given key(s), // or nil if no value found. func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { val := x.FindAttr(name) @@ -415,20 +415,20 @@ func (x *Fruit2Conf) FindFirstAttr(name string) *protoconf.Fruit2Conf_Fruit_Coun return nil } -// FindAttrMap1 finds the index key (CountryItemAttrName) to value (protoconf.Fruit2Conf_Fruit_Country_Item_Attr), -// which is the 1st-level map specified by (fruitType). -// One key may correspond to multiple values, which are contained by a slice. +// FindAttrMap1 finds the index: key(CountryItemAttrName) to value(protoconf.Fruit2Conf_Fruit_Country_Item_Attr), +// which is the upper 1st-level map specified by (fruitType). +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit2Conf) FindAttrMap1(fruitType int32) Fruit2Conf_Index_AttrMap { return x.indexAttrMap1[fruitType] } -// FindAttr1 finds a slice of all values of the given key in the 1st-level map +// FindAttr1 finds a slice of all values of the given key(s) in the upper 1st-level map // specified by (fruitType). func (x *Fruit2Conf) FindAttr1(fruitType int32, name string) []*protoconf.Fruit2Conf_Fruit_Country_Item_Attr { return x.FindAttrMap1(fruitType)[name] } -// FindFirstAttr1 finds the first value of the given key in the 1st-level map +// FindFirstAttr1 finds the first value of the given key(s) in the upper 1st-level map // specified by (fruitType), or nil if no value found. func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fruit2Conf_Fruit_Country_Item_Attr { val := x.FindAttr1(fruitType, name) @@ -440,19 +440,19 @@ func (x *Fruit2Conf) FindFirstAttr1(fruitType int32, name string) *protoconf.Fru // OrderedIndex: CountryItemPrice -// FindItemMap finds the ordered index key (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemMap finds the ordered index: key(CountryItemPrice) to value(protoconf.Fruit2Conf_Fruit_Country_Item) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit2Conf) FindItemMap() *Fruit2Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap } -// FindItem finds a slice of all values of the given key. +// FindItem finds a slice of all values of the given key(s). func (x *Fruit2Conf) FindItem(price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { val, _ := x.orderedIndexItemMap.Get(price) return val } -// FindFirstItem finds the first value of the given key, +// FindFirstItem finds the first value of the given key(s), // or nil if no value found. func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { val := x.FindItem(price) @@ -462,21 +462,21 @@ func (x *Fruit2Conf) FindFirstItem(price int32) *protoconf.Fruit2Conf_Fruit_Coun return nil } -// FindItemMap1 finds the index key (CountryItemPrice) to value (protoconf.Fruit2Conf_Fruit_Country_Item), -// which is the 1st-level treemap specified by (fruitType). -// One key may correspond to multiple values, which are contained by a slice. +// FindItemMap1 finds the index: key(CountryItemPrice) to value(protoconf.Fruit2Conf_Fruit_Country_Item), +// which is the upper 1st-level treemap specified by (fruitType). +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit2Conf) FindItemMap1(fruitType int32) *Fruit2Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap1[fruitType] } -// FindItem1 finds a slice of all values of the given key in the 1st-level treemap +// FindItem1 finds a slice of all values of the given key(s) in the upper 1st-level treemap // specified by (fruitType). func (x *Fruit2Conf) FindItem1(fruitType int32, price int32) []*protoconf.Fruit2Conf_Fruit_Country_Item { val, _ := x.FindItemMap1(fruitType).Get(price) return val } -// FindFirstItem1 finds the first value of the given key in the 1st-level treemap +// FindFirstItem1 finds the first value of the given key(s) in the upper 1st-level treemap // specified by (fruitType), or nil if no value found. func (x *Fruit2Conf) FindFirstItem1(fruitType int32, price int32) *protoconf.Fruit2Conf_Fruit_Country_Item { val := x.FindItem1(fruitType, price) @@ -620,18 +620,18 @@ func (x *Fruit3Conf) processAfterLoad() error { // Index: CountryName -// FindCountryMap finds the index key (CountryName) to value (protoconf.Fruit3Conf_Fruit_Country) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindCountryMap finds the index: key(CountryName) to value(protoconf.Fruit3Conf_Fruit_Country) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit3Conf) FindCountryMap() Fruit3Conf_Index_CountryMap { return x.indexCountryMap } -// FindCountry finds a slice of all values of the given key. +// FindCountry finds a slice of all values of the given key(s). func (x *Fruit3Conf) FindCountry(name string) []*protoconf.Fruit3Conf_Fruit_Country { return x.indexCountryMap[name] } -// FindFirstCountry finds the first value of the given key, +// FindFirstCountry finds the first value of the given key(s), // or nil if no value found. func (x *Fruit3Conf) FindFirstCountry(name string) *protoconf.Fruit3Conf_Fruit_Country { val := x.FindCountry(name) @@ -643,18 +643,18 @@ func (x *Fruit3Conf) FindFirstCountry(name string) *protoconf.Fruit3Conf_Fruit_C // Index: CountryItemAttrName -// FindAttrMap finds the index key (CountryItemAttrName) to value (protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindAttrMap finds the index: key(CountryItemAttrName) to value(protoconf.Fruit3Conf_Fruit_Country_Item_Attr) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit3Conf) FindAttrMap() Fruit3Conf_Index_AttrMap { return x.indexAttrMap } -// FindAttr finds a slice of all values of the given key. +// FindAttr finds a slice of all values of the given key(s). func (x *Fruit3Conf) FindAttr(name string) []*protoconf.Fruit3Conf_Fruit_Country_Item_Attr { return x.indexAttrMap[name] } -// FindFirstAttr finds the first value of the given key, +// FindFirstAttr finds the first value of the given key(s), // or nil if no value found. func (x *Fruit3Conf) FindFirstAttr(name string) *protoconf.Fruit3Conf_Fruit_Country_Item_Attr { val := x.FindAttr(name) @@ -666,19 +666,19 @@ func (x *Fruit3Conf) FindFirstAttr(name string) *protoconf.Fruit3Conf_Fruit_Coun // OrderedIndex: CountryItemPrice -// FindItemMap finds the ordered index key (CountryItemPrice) to value (protoconf.Fruit3Conf_Fruit_Country_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemMap finds the ordered index: key(CountryItemPrice) to value(protoconf.Fruit3Conf_Fruit_Country_Item) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *Fruit3Conf) FindItemMap() *Fruit3Conf_OrderedIndex_ItemMap { return x.orderedIndexItemMap } -// FindItem finds a slice of all values of the given key. +// FindItem finds a slice of all values of the given key(s). func (x *Fruit3Conf) FindItem(price int32) []*protoconf.Fruit3Conf_Fruit_Country_Item { val, _ := x.orderedIndexItemMap.Get(price) return val } -// FindFirstItem finds the first value of the given key, +// FindFirstItem finds the first value of the given key(s), // or nil if no value found. func (x *Fruit3Conf) FindFirstItem(price int32) *protoconf.Fruit3Conf_Fruit_Country_Item { val := x.FindItem(price) diff --git a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go index 89121cef..c675f43e 100644 --- a/test/go-tableau-loader/protoconf/loader/item_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/item_conf.pc.go @@ -318,18 +318,18 @@ func (x *ItemConf) GetOrderedMap() *ItemConf_OrderedMap_ItemMap { // Index: Type -// FindItemMap finds the index key (Type) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemMap finds the index: key(Type) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemMap() ItemConf_Index_ItemMap { return x.indexItemMap } -// FindItem finds a slice of all values of the given key. +// FindItem finds a slice of all values of the given key(s). func (x *ItemConf) FindItem(type_ protoconf.FruitType) []*protoconf.ItemConf_Item { return x.indexItemMap[type_] } -// FindFirstItem finds the first value of the given key, +// FindFirstItem finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItem(type_ protoconf.FruitType) *protoconf.ItemConf_Item { val := x.FindItem(type_) @@ -341,18 +341,18 @@ func (x *ItemConf) FindFirstItem(type_ protoconf.FruitType) *protoconf.ItemConf_ // Index: Param@ItemInfo -// FindItemInfoMap finds the index key (Param@ItemInfo) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemInfoMap finds the index: key(Param@ItemInfo) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemInfoMap() ItemConf_Index_ItemInfoMap { return x.indexItemInfoMap } -// FindItemInfo finds a slice of all values of the given key. +// FindItemInfo finds a slice of all values of the given key(s). func (x *ItemConf) FindItemInfo(param int32) []*protoconf.ItemConf_Item { return x.indexItemInfoMap[param] } -// FindFirstItemInfo finds the first value of the given key, +// FindFirstItemInfo finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItemInfo(param int32) *protoconf.ItemConf_Item { val := x.FindItemInfo(param) @@ -364,18 +364,18 @@ func (x *ItemConf) FindFirstItemInfo(param int32) *protoconf.ItemConf_Item { // Index: Default@ItemDefaultInfo -// FindItemDefaultInfoMap finds the index key (Default@ItemDefaultInfo) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemDefaultInfoMap finds the index: key(Default@ItemDefaultInfo) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemDefaultInfoMap() ItemConf_Index_ItemDefaultInfoMap { return x.indexItemDefaultInfoMap } -// FindItemDefaultInfo finds a slice of all values of the given key. +// FindItemDefaultInfo finds a slice of all values of the given key(s). func (x *ItemConf) FindItemDefaultInfo(default_ string) []*protoconf.ItemConf_Item { return x.indexItemDefaultInfoMap[default_] } -// FindFirstItemDefaultInfo finds the first value of the given key, +// FindFirstItemDefaultInfo finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItemDefaultInfo(default_ string) *protoconf.ItemConf_Item { val := x.FindItemDefaultInfo(default_) @@ -387,18 +387,18 @@ func (x *ItemConf) FindFirstItemDefaultInfo(default_ string) *protoconf.ItemConf // Index: ExtType@ItemExtInfo -// FindItemExtInfoMap finds the index key (ExtType@ItemExtInfo) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemExtInfoMap finds the index: key(ExtType@ItemExtInfo) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemExtInfoMap() ItemConf_Index_ItemExtInfoMap { return x.indexItemExtInfoMap } -// FindItemExtInfo finds a slice of all values of the given key. +// FindItemExtInfo finds a slice of all values of the given key(s). func (x *ItemConf) FindItemExtInfo(extType protoconf.FruitType) []*protoconf.ItemConf_Item { return x.indexItemExtInfoMap[extType] } -// FindFirstItemExtInfo finds the first value of the given key, +// FindFirstItemExtInfo finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItemExtInfo(extType protoconf.FruitType) *protoconf.ItemConf_Item { val := x.FindItemExtInfo(extType) @@ -410,18 +410,18 @@ func (x *ItemConf) FindFirstItemExtInfo(extType protoconf.FruitType) *protoconf. // Index: (ID,Name)@AwardItem -// FindAwardItemMap finds the index key ((ID,Name)@AwardItem) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindAwardItemMap finds the index: key((ID,Name)@AwardItem) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindAwardItemMap() ItemConf_Index_AwardItemMap { return x.indexAwardItemMap } -// FindAwardItem finds a slice of all values of the given key. +// FindAwardItem finds a slice of all values of the given key(s). func (x *ItemConf) FindAwardItem(id uint32, name string) []*protoconf.ItemConf_Item { return x.indexAwardItemMap[ItemConf_Index_AwardItemKey{id, name}] } -// FindFirstAwardItem finds the first value of the given key, +// FindFirstAwardItem finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstAwardItem(id uint32, name string) *protoconf.ItemConf_Item { val := x.FindAwardItem(id, name) @@ -433,18 +433,18 @@ func (x *ItemConf) FindFirstAwardItem(id uint32, name string) *protoconf.ItemCon // Index: (ID,Type,Param,ExtType)@SpecialItem -// FindSpecialItemMap finds the index key ((ID,Type,Param,ExtType)@SpecialItem) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindSpecialItemMap finds the index: key((ID,Type,Param,ExtType)@SpecialItem) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindSpecialItemMap() ItemConf_Index_SpecialItemMap { return x.indexSpecialItemMap } -// FindSpecialItem finds a slice of all values of the given key. +// FindSpecialItem finds a slice of all values of the given key(s). func (x *ItemConf) FindSpecialItem(id uint32, type_ protoconf.FruitType, param int32, extType protoconf.FruitType) []*protoconf.ItemConf_Item { return x.indexSpecialItemMap[ItemConf_Index_SpecialItemKey{id, type_, param, extType}] } -// FindFirstSpecialItem finds the first value of the given key, +// FindFirstSpecialItem finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstSpecialItem(id uint32, type_ protoconf.FruitType, param int32, extType protoconf.FruitType) *protoconf.ItemConf_Item { val := x.FindSpecialItem(id, type_, param, extType) @@ -456,18 +456,18 @@ func (x *ItemConf) FindFirstSpecialItem(id uint32, type_ protoconf.FruitType, pa // Index: PathDir@ItemPathDir -// FindItemPathDirMap finds the index key (PathDir@ItemPathDir) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemPathDirMap finds the index: key(PathDir@ItemPathDir) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemPathDirMap() ItemConf_Index_ItemPathDirMap { return x.indexItemPathDirMap } -// FindItemPathDir finds a slice of all values of the given key. +// FindItemPathDir finds a slice of all values of the given key(s). func (x *ItemConf) FindItemPathDir(dir string) []*protoconf.ItemConf_Item { return x.indexItemPathDirMap[dir] } -// FindFirstItemPathDir finds the first value of the given key, +// FindFirstItemPathDir finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItemPathDir(dir string) *protoconf.ItemConf_Item { val := x.FindItemPathDir(dir) @@ -479,18 +479,18 @@ func (x *ItemConf) FindFirstItemPathDir(dir string) *protoconf.ItemConf_Item { // Index: PathName@ItemPathName -// FindItemPathNameMap finds the index key (PathName@ItemPathName) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemPathNameMap finds the index: key(PathName@ItemPathName) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemPathNameMap() ItemConf_Index_ItemPathNameMap { return x.indexItemPathNameMap } -// FindItemPathName finds a slice of all values of the given key. +// FindItemPathName finds a slice of all values of the given key(s). func (x *ItemConf) FindItemPathName(name string) []*protoconf.ItemConf_Item { return x.indexItemPathNameMap[name] } -// FindFirstItemPathName finds the first value of the given key, +// FindFirstItemPathName finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItemPathName(name string) *protoconf.ItemConf_Item { val := x.FindItemPathName(name) @@ -502,18 +502,18 @@ func (x *ItemConf) FindFirstItemPathName(name string) *protoconf.ItemConf_Item { // Index: PathFriendID@ItemPathFriendID -// FindItemPathFriendIDMap finds the index key (PathFriendID@ItemPathFriendID) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindItemPathFriendIDMap finds the index: key(PathFriendID@ItemPathFriendID) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindItemPathFriendIDMap() ItemConf_Index_ItemPathFriendIDMap { return x.indexItemPathFriendIdMap } -// FindItemPathFriendID finds a slice of all values of the given key. +// FindItemPathFriendID finds a slice of all values of the given key(s). func (x *ItemConf) FindItemPathFriendID(id uint32) []*protoconf.ItemConf_Item { return x.indexItemPathFriendIdMap[id] } -// FindFirstItemPathFriendID finds the first value of the given key, +// FindFirstItemPathFriendID finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstItemPathFriendID(id uint32) *protoconf.ItemConf_Item { val := x.FindItemPathFriendID(id) @@ -525,18 +525,18 @@ func (x *ItemConf) FindFirstItemPathFriendID(id uint32) *protoconf.ItemConf_Item // Index: UseEffectType@UseEffectType -// FindUseEffectTypeMap finds the index key (UseEffectType@UseEffectType) to value (protoconf.ItemConf_Item) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindUseEffectTypeMap finds the index: key(UseEffectType@UseEffectType) to value(protoconf.ItemConf_Item) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindUseEffectTypeMap() ItemConf_Index_UseEffectTypeMap { return x.indexUseEffectTypeMap } -// FindUseEffectType finds a slice of all values of the given key. +// FindUseEffectType finds a slice of all values of the given key(s). func (x *ItemConf) FindUseEffectType(type_ protoconf.UseEffect_Type) []*protoconf.ItemConf_Item { return x.indexUseEffectTypeMap[type_] } -// FindFirstUseEffectType finds the first value of the given key, +// FindFirstUseEffectType finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstUseEffectType(type_ protoconf.UseEffect_Type) *protoconf.ItemConf_Item { val := x.FindUseEffectType(type_) @@ -548,19 +548,19 @@ func (x *ItemConf) FindFirstUseEffectType(type_ protoconf.UseEffect_Type) *proto // OrderedIndex: ExtType@ExtType -// FindExtTypeMap finds the ordered index key (ExtType@ExtType) to value (protoconf.ItemConf_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindExtTypeMap finds the ordered index: key(ExtType@ExtType) to value(protoconf.ItemConf_Item) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindExtTypeMap() *ItemConf_OrderedIndex_ExtTypeMap { return x.orderedIndexExtTypeMap } -// FindExtType finds a slice of all values of the given key. +// FindExtType finds a slice of all values of the given key(s). func (x *ItemConf) FindExtType(extType protoconf.FruitType) []*protoconf.ItemConf_Item { val, _ := x.orderedIndexExtTypeMap.Get(extType) return val } -// FindFirstExtType finds the first value of the given key, +// FindFirstExtType finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstExtType(extType protoconf.FruitType) *protoconf.ItemConf_Item { val := x.FindExtType(extType) @@ -572,19 +572,19 @@ func (x *ItemConf) FindFirstExtType(extType protoconf.FruitType) *protoconf.Item // OrderedIndex: (Param,ExtType)@ParamExtType -// FindParamExtTypeMap finds the ordered index key ((Param,ExtType)@ParamExtType) to value (protoconf.ItemConf_Item) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindParamExtTypeMap finds the ordered index: key((Param,ExtType)@ParamExtType) to value(protoconf.ItemConf_Item) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *ItemConf) FindParamExtTypeMap() *ItemConf_OrderedIndex_ParamExtTypeMap { return x.orderedIndexParamExtTypeMap } -// FindParamExtType finds a slice of all values of the given key. +// FindParamExtType finds a slice of all values of the given key(s). func (x *ItemConf) FindParamExtType(param int32, extType protoconf.FruitType) []*protoconf.ItemConf_Item { val, _ := x.orderedIndexParamExtTypeMap.Get(ItemConf_OrderedIndex_ParamExtTypeKey{param, extType}) return val } -// FindFirstParamExtType finds the first value of the given key, +// FindFirstParamExtType finds the first value of the given key(s), // or nil if no value found. func (x *ItemConf) FindFirstParamExtType(param int32, extType protoconf.FruitType) *protoconf.ItemConf_Item { val := x.FindParamExtType(param, extType) diff --git a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go index fa2c50a7..254bb6e1 100644 --- a/test/go-tableau-loader/protoconf/loader/test_conf.pc.go +++ b/test/go-tableau-loader/protoconf/loader/test_conf.pc.go @@ -333,18 +333,18 @@ func (x *ActivityConf) GetOrderedMap3(activityId uint64, chapterId uint32, secti // Index: ActivityName -// FindActivityMap finds the index key (ActivityName) to value (protoconf.ActivityConf_Activity) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindActivityMap finds the index: key(ActivityName) to value(protoconf.ActivityConf_Activity) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindActivityMap() ActivityConf_Index_ActivityMap { return x.indexActivityMap } -// FindActivity finds a slice of all values of the given key. +// FindActivity finds a slice of all values of the given key(s). func (x *ActivityConf) FindActivity(activityName string) []*protoconf.ActivityConf_Activity { return x.indexActivityMap[activityName] } -// FindFirstActivity finds the first value of the given key, +// FindFirstActivity finds the first value of the given key(s), // or nil if no value found. func (x *ActivityConf) FindFirstActivity(activityName string) *protoconf.ActivityConf_Activity { val := x.FindActivity(activityName) @@ -356,18 +356,18 @@ func (x *ActivityConf) FindFirstActivity(activityName string) *protoconf.Activit // Index: ChapterID -// FindChapterMap finds the index key (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindChapterMap finds the index: key(ChapterID) to value(protoconf.ActivityConf_Activity_Chapter) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindChapterMap() ActivityConf_Index_ChapterMap { return x.indexChapterMap } -// FindChapter finds a slice of all values of the given key. +// FindChapter finds a slice of all values of the given key(s). func (x *ActivityConf) FindChapter(chapterId uint32) []*protoconf.ActivityConf_Activity_Chapter { return x.indexChapterMap[chapterId] } -// FindFirstChapter finds the first value of the given key, +// FindFirstChapter finds the first value of the given key(s), // or nil if no value found. func (x *ActivityConf) FindFirstChapter(chapterId uint32) *protoconf.ActivityConf_Activity_Chapter { val := x.FindChapter(chapterId) @@ -377,20 +377,20 @@ func (x *ActivityConf) FindFirstChapter(chapterId uint32) *protoconf.ActivityCon return nil } -// FindChapterMap1 finds the index key (ChapterID) to value (protoconf.ActivityConf_Activity_Chapter), -// which is the 1st-level map specified by (activityId). -// One key may correspond to multiple values, which are contained by a slice. +// FindChapterMap1 finds the index: key(ChapterID) to value(protoconf.ActivityConf_Activity_Chapter), +// which is the upper 1st-level map specified by (activityId). +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindChapterMap1(activityId uint64) ActivityConf_Index_ChapterMap { return x.indexChapterMap1[activityId] } -// FindChapter1 finds a slice of all values of the given key in the 1st-level map +// FindChapter1 finds a slice of all values of the given key(s) in the upper 1st-level map // specified by (activityId). func (x *ActivityConf) FindChapter1(activityId uint64, chapterId uint32) []*protoconf.ActivityConf_Activity_Chapter { return x.FindChapterMap1(activityId)[chapterId] } -// FindFirstChapter1 finds the first value of the given key in the 1st-level map +// FindFirstChapter1 finds the first value of the given key(s) in the upper 1st-level map // specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstChapter1(activityId uint64, chapterId uint32) *protoconf.ActivityConf_Activity_Chapter { val := x.FindChapter1(activityId, chapterId) @@ -402,18 +402,18 @@ func (x *ActivityConf) FindFirstChapter1(activityId uint64, chapterId uint32) *p // Index: ChapterName@NamedChapter -// FindNamedChapterMap finds the index key (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindNamedChapterMap finds the index: key(ChapterName@NamedChapter) to value(protoconf.ActivityConf_Activity_Chapter) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindNamedChapterMap() ActivityConf_Index_NamedChapterMap { return x.indexNamedChapterMap } -// FindNamedChapter finds a slice of all values of the given key. +// FindNamedChapter finds a slice of all values of the given key(s). func (x *ActivityConf) FindNamedChapter(chapterName string) []*protoconf.ActivityConf_Activity_Chapter { return x.indexNamedChapterMap[chapterName] } -// FindFirstNamedChapter finds the first value of the given key, +// FindFirstNamedChapter finds the first value of the given key(s), // or nil if no value found. func (x *ActivityConf) FindFirstNamedChapter(chapterName string) *protoconf.ActivityConf_Activity_Chapter { val := x.FindNamedChapter(chapterName) @@ -423,20 +423,20 @@ func (x *ActivityConf) FindFirstNamedChapter(chapterName string) *protoconf.Acti return nil } -// FindNamedChapterMap1 finds the index key (ChapterName@NamedChapter) to value (protoconf.ActivityConf_Activity_Chapter), -// which is the 1st-level map specified by (activityId). -// One key may correspond to multiple values, which are contained by a slice. +// FindNamedChapterMap1 finds the index: key(ChapterName@NamedChapter) to value(protoconf.ActivityConf_Activity_Chapter), +// which is the upper 1st-level map specified by (activityId). +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindNamedChapterMap1(activityId uint64) ActivityConf_Index_NamedChapterMap { return x.indexNamedChapterMap1[activityId] } -// FindNamedChapter1 finds a slice of all values of the given key in the 1st-level map +// FindNamedChapter1 finds a slice of all values of the given key(s) in the upper 1st-level map // specified by (activityId). func (x *ActivityConf) FindNamedChapter1(activityId uint64, chapterName string) []*protoconf.ActivityConf_Activity_Chapter { return x.FindNamedChapterMap1(activityId)[chapterName] } -// FindFirstNamedChapter1 finds the first value of the given key in the 1st-level map +// FindFirstNamedChapter1 finds the first value of the given key(s) in the upper 1st-level map // specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstNamedChapter1(activityId uint64, chapterName string) *protoconf.ActivityConf_Activity_Chapter { val := x.FindNamedChapter1(activityId, chapterName) @@ -448,18 +448,18 @@ func (x *ActivityConf) FindFirstNamedChapter1(activityId uint64, chapterName str // Index: SectionItemID@Award -// FindAwardMap finds the index key (SectionItemID@Award) to value (protoconf.Section_SectionItem) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindAwardMap finds the index: key(SectionItemID@Award) to value(protoconf.Section_SectionItem) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindAwardMap() ActivityConf_Index_AwardMap { return x.indexAwardMap } -// FindAward finds a slice of all values of the given key. +// FindAward finds a slice of all values of the given key(s). func (x *ActivityConf) FindAward(id uint32) []*protoconf.Section_SectionItem { return x.indexAwardMap[id] } -// FindFirstAward finds the first value of the given key, +// FindFirstAward finds the first value of the given key(s), // or nil if no value found. func (x *ActivityConf) FindFirstAward(id uint32) *protoconf.Section_SectionItem { val := x.FindAward(id) @@ -469,20 +469,20 @@ func (x *ActivityConf) FindFirstAward(id uint32) *protoconf.Section_SectionItem return nil } -// FindAwardMap1 finds the index key (SectionItemID@Award) to value (protoconf.Section_SectionItem), -// which is the 1st-level map specified by (activityId). -// One key may correspond to multiple values, which are contained by a slice. +// FindAwardMap1 finds the index: key(SectionItemID@Award) to value(protoconf.Section_SectionItem), +// which is the upper 1st-level map specified by (activityId). +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindAwardMap1(activityId uint64) ActivityConf_Index_AwardMap { return x.indexAwardMap1[activityId] } -// FindAward1 finds a slice of all values of the given key in the 1st-level map +// FindAward1 finds a slice of all values of the given key(s) in the upper 1st-level map // specified by (activityId). func (x *ActivityConf) FindAward1(activityId uint64, id uint32) []*protoconf.Section_SectionItem { return x.FindAwardMap1(activityId)[id] } -// FindFirstAward1 finds the first value of the given key in the 1st-level map +// FindFirstAward1 finds the first value of the given key(s) in the upper 1st-level map // specified by (activityId), or nil if no value found. func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf.Section_SectionItem { val := x.FindAward1(activityId, id) @@ -492,20 +492,20 @@ func (x *ActivityConf) FindFirstAward1(activityId uint64, id uint32) *protoconf. return nil } -// FindAwardMap2 finds the index key (SectionItemID@Award) to value (protoconf.Section_SectionItem), -// which is the 2nd-level map specified by (activityId, chapterId). -// One key may correspond to multiple values, which are contained by a slice. +// FindAwardMap2 finds the index: key(SectionItemID@Award) to value(protoconf.Section_SectionItem), +// which is the upper 2nd-level map specified by (activityId, chapterId). +// One key may correspond to multiple values, which are represented by a slice. func (x *ActivityConf) FindAwardMap2(activityId uint64, chapterId uint32) ActivityConf_Index_AwardMap { return x.indexAwardMap2[ActivityConf_LevelIndex_Activity_ChapterKey{activityId, chapterId}] } -// FindAward2 finds a slice of all values of the given key in the 2nd-level map +// FindAward2 finds a slice of all values of the given key(s) in the upper 2nd-level map // specified by (activityId, chapterId). func (x *ActivityConf) FindAward2(activityId uint64, chapterId uint32, id uint32) []*protoconf.Section_SectionItem { return x.FindAwardMap2(activityId, chapterId)[id] } -// FindFirstAward2 finds the first value of the given key in the 2nd-level map +// FindFirstAward2 finds the first value of the given key(s) in the upper 2nd-level map // specified by (activityId, chapterId), or nil if no value found. func (x *ActivityConf) FindFirstAward2(activityId uint64, chapterId uint32, id uint32) *protoconf.Section_SectionItem { val := x.FindAward2(activityId, chapterId, id) @@ -879,18 +879,18 @@ func (x *TaskConf) Get1(id int64) (*protoconf.TaskConf_Task, error) { // Index: ActivityID -// FindTaskMap finds the index key (ActivityID) to value (protoconf.TaskConf_Task) map. -// One key may correspond to multiple values, which are contained by a slice. +// FindTaskMap finds the index: key(ActivityID) to value(protoconf.TaskConf_Task) map. +// One key may correspond to multiple values, which are represented by a slice. func (x *TaskConf) FindTaskMap() TaskConf_Index_TaskMap { return x.indexTaskMap } -// FindTask finds a slice of all values of the given key. +// FindTask finds a slice of all values of the given key(s). func (x *TaskConf) FindTask(activityId int64) []*protoconf.TaskConf_Task { return x.indexTaskMap[activityId] } -// FindFirstTask finds the first value of the given key, +// FindFirstTask finds the first value of the given key(s), // or nil if no value found. func (x *TaskConf) FindFirstTask(activityId int64) *protoconf.TaskConf_Task { val := x.FindTask(activityId) @@ -902,19 +902,19 @@ func (x *TaskConf) FindFirstTask(activityId int64) *protoconf.TaskConf_Task { // OrderedIndex: Goal@OrderedTask -// FindOrderedTaskMap finds the ordered index key (Goal@OrderedTask) to value (protoconf.TaskConf_Task) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindOrderedTaskMap finds the ordered index: key(Goal@OrderedTask) to value(protoconf.TaskConf_Task) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *TaskConf) FindOrderedTaskMap() *TaskConf_OrderedIndex_OrderedTaskMap { return x.orderedIndexOrderedTaskMap } -// FindOrderedTask finds a slice of all values of the given key. +// FindOrderedTask finds a slice of all values of the given key(s). func (x *TaskConf) FindOrderedTask(goal int64) []*protoconf.TaskConf_Task { val, _ := x.orderedIndexOrderedTaskMap.Get(goal) return val } -// FindFirstOrderedTask finds the first value of the given key, +// FindFirstOrderedTask finds the first value of the given key(s), // or nil if no value found. func (x *TaskConf) FindFirstOrderedTask(goal int64) *protoconf.TaskConf_Task { val := x.FindOrderedTask(goal) @@ -926,19 +926,19 @@ func (x *TaskConf) FindFirstOrderedTask(goal int64) *protoconf.TaskConf_Task { // OrderedIndex: Expiry@TaskExpiry -// FindTaskExpiryMap finds the ordered index key (Expiry@TaskExpiry) to value (protoconf.TaskConf_Task) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindTaskExpiryMap finds the ordered index: key(Expiry@TaskExpiry) to value(protoconf.TaskConf_Task) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *TaskConf) FindTaskExpiryMap() *TaskConf_OrderedIndex_TaskExpiryMap { return x.orderedIndexTaskExpiryMap } -// FindTaskExpiry finds a slice of all values of the given key. +// FindTaskExpiry finds a slice of all values of the given key(s). func (x *TaskConf) FindTaskExpiry(expiry int64) []*protoconf.TaskConf_Task { val, _ := x.orderedIndexTaskExpiryMap.Get(expiry) return val } -// FindFirstTaskExpiry finds the first value of the given key, +// FindFirstTaskExpiry finds the first value of the given key(s), // or nil if no value found. func (x *TaskConf) FindFirstTaskExpiry(expiry int64) *protoconf.TaskConf_Task { val := x.FindTaskExpiry(expiry) @@ -950,19 +950,19 @@ func (x *TaskConf) FindFirstTaskExpiry(expiry int64) *protoconf.TaskConf_Task { // OrderedIndex: Expiry@SortedTaskExpiry -// FindSortedTaskExpiryMap finds the ordered index key (Expiry@SortedTaskExpiry) to value (protoconf.TaskConf_Task) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindSortedTaskExpiryMap finds the ordered index: key(Expiry@SortedTaskExpiry) to value(protoconf.TaskConf_Task) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *TaskConf) FindSortedTaskExpiryMap() *TaskConf_OrderedIndex_SortedTaskExpiryMap { return x.orderedIndexSortedTaskExpiryMap } -// FindSortedTaskExpiry finds a slice of all values of the given key. +// FindSortedTaskExpiry finds a slice of all values of the given key(s). func (x *TaskConf) FindSortedTaskExpiry(expiry int64) []*protoconf.TaskConf_Task { val, _ := x.orderedIndexSortedTaskExpiryMap.Get(expiry) return val } -// FindFirstSortedTaskExpiry finds the first value of the given key, +// FindFirstSortedTaskExpiry finds the first value of the given key(s), // or nil if no value found. func (x *TaskConf) FindFirstSortedTaskExpiry(expiry int64) *protoconf.TaskConf_Task { val := x.FindSortedTaskExpiry(expiry) @@ -974,19 +974,19 @@ func (x *TaskConf) FindFirstSortedTaskExpiry(expiry int64) *protoconf.TaskConf_T // OrderedIndex: (Expiry,ActivityID)@ActivityExpiry -// FindActivityExpiryMap finds the ordered index key ((Expiry,ActivityID)@ActivityExpiry) to value (protoconf.TaskConf_Task) treemap. -// One key may correspond to multiple values, which are contained by a slice. +// FindActivityExpiryMap finds the ordered index: key((Expiry,ActivityID)@ActivityExpiry) to value(protoconf.TaskConf_Task) treemap. +// One key may correspond to multiple values, which are represented by a slice. func (x *TaskConf) FindActivityExpiryMap() *TaskConf_OrderedIndex_ActivityExpiryMap { return x.orderedIndexActivityExpiryMap } -// FindActivityExpiry finds a slice of all values of the given key. +// FindActivityExpiry finds a slice of all values of the given key(s). func (x *TaskConf) FindActivityExpiry(expiry int64, activityId int64) []*protoconf.TaskConf_Task { val, _ := x.orderedIndexActivityExpiryMap.Get(TaskConf_OrderedIndex_ActivityExpiryKey{expiry, activityId}) return val } -// FindFirstActivityExpiry finds the first value of the given key, +// FindFirstActivityExpiry finds the first value of the given key(s), // or nil if no value found. func (x *TaskConf) FindFirstActivityExpiry(expiry int64, activityId int64) *protoconf.TaskConf_Task { val := x.FindActivityExpiry(expiry, activityId) From c35e2dc4a7c03dfeee68a6846583f5a5970113f9 Mon Sep 17 00:00:00 2001 From: Kybxd <627940450@qq.com> Date: Thu, 11 Dec 2025 21:42:10 +0800 Subject: [PATCH 15/15] fix: unittest --- internal/index/descriptor_test.go | 115 +++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 10 deletions(-) diff --git a/internal/index/descriptor_test.go b/internal/index/descriptor_test.go index d07423bf..aa5e0e29 100644 --- a/internal/index/descriptor_test.go +++ b/internal/index/descriptor_test.go @@ -34,8 +34,12 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: fd[*protoconf.ItemConf]("item_map"), + Depth: 1, + MapDepth: 1, + FD: fd[*protoconf.ItemConf]("item_map"), NextLevel: &LevelMessage{ + Depth: 2, + MapDepth: 2, Indexes: []*LevelIndex{ { Index: &Index{ @@ -242,6 +246,53 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, }, }, + OrderedIndexes: []*LevelIndex{ + { + Index: &Index{ + Cols: []string{"ExtType"}, + Name: "ExtType", + }, + MD: md[*protoconf.ItemConf_Item](), + ColFields: []*LevelField{ + { + FD: fd[*protoconf.ItemConf_Item]("ext_type_list"), + LeveledFDList: []protoreflect.FieldDescriptor{ + fd[*protoconf.ItemConf_Item]("ext_type_list"), + }, + }, + }, + }, + { + Index: &Index{ + Cols: []string{"Param", "ExtType"}, + SortedCols: []string{"ID"}, + Name: "ParamExtType", + }, + MD: md[*protoconf.ItemConf_Item](), + ColFields: []*LevelField{ + { + FD: fd[*protoconf.ItemConf_Item]("param_list"), + LeveledFDList: []protoreflect.FieldDescriptor{ + fd[*protoconf.ItemConf_Item]("param_list"), + }, + }, + { + FD: fd[*protoconf.ItemConf_Item]("ext_type_list"), + LeveledFDList: []protoreflect.FieldDescriptor{ + fd[*protoconf.ItemConf_Item]("ext_type_list"), + }, + }, + }, + SortedColFields: []*LevelField{ + { + FD: fd[*protoconf.ItemConf_Item]("id"), + LeveledFDList: []protoreflect.FieldDescriptor{ + fd[*protoconf.ItemConf_Item]("id"), + }, + }, + }, + }, + }, }, }, }, @@ -253,10 +304,16 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: fd[*protoconf.HeroConf]("hero_map"), + Depth: 1, + MapDepth: 1, + FD: fd[*protoconf.HeroConf]("hero_map"), NextLevel: &LevelMessage{ - FD: fd[*protoconf.HeroConf_Hero]("attr_map"), + Depth: 2, + MapDepth: 2, + FD: fd[*protoconf.HeroConf_Hero]("attr_map"), NextLevel: &LevelMessage{ + Depth: 3, + MapDepth: 3, Indexes: []*LevelIndex{ { Index: &Index{ @@ -286,9 +343,13 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: fd[*protoconf.ActivityConf]("activity_map"), + Depth: 1, + MapDepth: 1, + FD: fd[*protoconf.ActivityConf]("activity_map"), NextLevel: &LevelMessage{ - FD: fd[*protoconf.ActivityConf_Activity]("chapter_map"), + Depth: 2, + MapDepth: 2, + FD: fd[*protoconf.ActivityConf_Activity]("chapter_map"), Indexes: []*LevelIndex{ { Index: &Index{ @@ -307,7 +368,9 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, }, NextLevel: &LevelMessage{ - FD: fd[*protoconf.ActivityConf_Activity_Chapter]("section_map"), + Depth: 3, + MapDepth: 3, + FD: fd[*protoconf.ActivityConf_Activity_Chapter]("section_map"), Indexes: []*LevelIndex{ { Index: &Index{ @@ -350,9 +413,13 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, }, NextLevel: &LevelMessage{ - FD: fd[*protoconf.Section]("section_item_list"), + Depth: 4, + MapDepth: 4, + FD: fd[*protoconf.Section]("section_item_list"), NextLevel: &LevelMessage{ - FD: fd[*protoconf.Section_SectionItem]("decompose_item_list"), + Depth: 5, + MapDepth: 4, + FD: fd[*protoconf.Section_SectionItem]("decompose_item_list"), Indexes: []*LevelIndex{ { Index: &Index{ @@ -370,7 +437,10 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, }, }, - NextLevel: &LevelMessage{}, + NextLevel: &LevelMessage{ + Depth: 6, + MapDepth: 4, + }, }, }, }, @@ -385,8 +455,12 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, want: &IndexDescriptor{ LevelMessage: &LevelMessage{ - FD: fd[*protoconf.TaskConf]("task_map"), + Depth: 1, + MapDepth: 1, + FD: fd[*protoconf.TaskConf]("task_map"), NextLevel: &LevelMessage{ + Depth: 2, + MapDepth: 2, Indexes: []*LevelIndex{ { Index: &Index{ @@ -489,6 +563,27 @@ func Test_ParseIndexDescriptor(t *testing.T) { }, }, }, + { + Index: &Index{ + Cols: []string{"Expiry", "ActivityID"}, + Name: "ActivityExpiry", + }, + MD: md[*protoconf.TaskConf_Task](), + ColFields: []*LevelField{ + { + FD: fd[*protoconf.TaskConf_Task]("expiry"), + LeveledFDList: []protoreflect.FieldDescriptor{ + fd[*protoconf.TaskConf_Task]("expiry"), + }, + }, + { + FD: fd[*protoconf.TaskConf_Task]("activity_id"), + LeveledFDList: []protoreflect.FieldDescriptor{ + fd[*protoconf.TaskConf_Task]("activity_id"), + }, + }, + }, + }, }, }, },