From e1de5af8335f146628fc8ddda9e4d3de2f18b2bc Mon Sep 17 00:00:00 2001 From: jimingquan Date: Wed, 13 Oct 2021 22:33:49 +0800 Subject: [PATCH] add hash & hash (#3051) --- src/common/datatypes/Map.cpp | 11 ++++++++++ src/common/datatypes/Map.h | 8 ++++++++ src/common/datatypes/Set.cpp | 11 ++++++++++ src/common/datatypes/Set.h | 9 ++++++++- src/common/datatypes/Value.cpp | 4 ++-- .../tck/features/go/GoYieldVertexEdge.feature | 20 +++++++++++++++---- tests/tck/features/match/Base.feature | 15 ++++++++++++++ 7 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/common/datatypes/Map.cpp b/src/common/datatypes/Map.cpp index 7ab73d5c9b7..5ac176ae86a 100644 --- a/src/common/datatypes/Map.cpp +++ b/src/common/datatypes/Map.cpp @@ -46,3 +46,14 @@ folly::dynamic Map::getMetaData() const { } } // namespace nebula + +namespace std { +std::size_t hash::operator()(const nebula::Map& m) const noexcept { + size_t seed = 0; + for (auto& v : m.kvs) { + seed ^= hash()(v.first) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + return seed; +} + +} // namespace std diff --git a/src/common/datatypes/Map.h b/src/common/datatypes/Map.h index 333e5d0cb0d..9e7db20c1b3 100644 --- a/src/common/datatypes/Map.h +++ b/src/common/datatypes/Map.h @@ -70,4 +70,12 @@ struct Map { inline std::ostream& operator<<(std::ostream& os, const Map& m) { return os << m.toString(); } } // namespace nebula + +namespace std { +template <> +struct hash { + std::size_t operator()(const nebula::Map& m) const noexcept; +}; + +} // namespace std #endif // COMMON_DATATYPES_MAP_H_ diff --git a/src/common/datatypes/Set.cpp b/src/common/datatypes/Set.cpp index 2e0e90a2f5a..5a130ace3e5 100644 --- a/src/common/datatypes/Set.cpp +++ b/src/common/datatypes/Set.cpp @@ -43,3 +43,14 @@ folly::dynamic Set::getMetaData() const { } } // namespace nebula + +namespace std { +std::size_t hash::operator()(const nebula::Set& s) const noexcept { + size_t seed = 0; + for (auto& v : s.values) { + seed ^= hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + return seed; +} + +} // namespace std diff --git a/src/common/datatypes/Set.h b/src/common/datatypes/Set.h index dabc33e0d7e..425097c04f2 100644 --- a/src/common/datatypes/Set.h +++ b/src/common/datatypes/Set.h @@ -54,6 +54,13 @@ struct Set { }; inline std::ostream& operator<<(std::ostream& os, const Set& s) { return os << s.toString(); } - } // namespace nebula + +namespace std { +template <> +struct hash { + std::size_t operator()(const nebula::Set& s) const noexcept; +}; + +} // namespace std #endif // COMMON_DATATYPES_SET_H_ diff --git a/src/common/datatypes/Value.cpp b/src/common/datatypes/Value.cpp index e4294a551ab..e6f82a2d517 100644 --- a/src/common/datatypes/Value.cpp +++ b/src/common/datatypes/Value.cpp @@ -69,10 +69,10 @@ std::size_t hash::operator()(const nebula::Value& v) const noexce return hash()(v.getGeography()); } case nebula::Value::Type::MAP: { - LOG(FATAL) << "Hash for MAP has not been implemented"; + return hash()(v.getMap()); } case nebula::Value::Type::SET: { - LOG(FATAL) << "Hash for SET has not been implemented"; + return hash()(v.getSet()); } case nebula::Value::Type::DATASET: { LOG(FATAL) << "Hash for DATASET has not been implemented"; diff --git a/tests/tck/features/go/GoYieldVertexEdge.feature b/tests/tck/features/go/GoYieldVertexEdge.feature index b38ebc7f876..4075300fbbf 100644 --- a/tests/tck/features/go/GoYieldVertexEdge.feature +++ b/tests/tck/features/go/GoYieldVertexEdge.feature @@ -226,9 +226,7 @@ Feature: Go Yield Vertex And Edge Sentence """ Then a SyntaxError should be raised at runtime: syntax error near `OVER' - @skip - # reason we not support hash hash hash from now on. line 67 in Value.cpp - Scenario: distinct map + Scenario: distinct map and set When executing query: """ GO FROM "Boris Diaw" OVER like YIELD dst(edge) as id | @@ -236,7 +234,21 @@ Feature: Go Yield Vertex And Edge Sentence GO FROM $-.id OVER serve YIELD DISTINCT dst(edge) as dst, edge as e, properties(edge) as props """ Then the result should be, in any order, with relax comparison: - | dst | e | props | + | dst | e | props | + | "Spurs" | [:serve "Manu Ginobili"->"Spurs" @0 {end_year: 2018, start_year: 2002}] | {end_year: 2018, start_year: 2002} | + | "Spurs" | [:serve "Tim Duncan"->"Spurs" @0 {end_year: 2016, start_year: 1997}] | {end_year: 2016, start_year: 1997} | + | "Hornets" | [:serve "Tony Parker"->"Hornets" @0 {end_year: 2019, start_year: 2018}] | {end_year: 2019, start_year: 2018} | + | "Spurs" | [:serve "Tony Parker"->"Spurs" @0 {end_year: 2018, start_year: 1999}] | {end_year: 2018, start_year: 1999} | + | "Spurs" | [:serve "LaMarcus Aldridge"->"Spurs" @0 {end_year: 2019, start_year: 2015}] | {end_year: 2019, start_year: 2015} | + | "Trail Blazers" | [:serve "LaMarcus Aldridge"->"Trail Blazers" @0 {end_year: 2015, start_year: 2006}] | {end_year: 2015, start_year: 2006} | + When executing query: + """ + GO 2 STEPS FROM "Tim Duncan" OVER like YIELD dst(edge) as id | + YIELD DISTINCT collect($-.id) as a, collect_set($-.id) as b + """ + Then the result should be, in any order, with relax comparison: + | a | b | + | ["Tim Duncan", "LaMarcus Aldridge", "Manu Ginobili", "Tim Duncan"] | {"Manu Ginobili", "LaMarcus Aldridge", "Tim Duncan"} | Scenario: distinct When executing query: diff --git a/tests/tck/features/match/Base.feature b/tests/tck/features/match/Base.feature index 98705f6b212..8cd92190d1a 100644 --- a/tests/tck/features/match/Base.feature +++ b/tests/tck/features/match/Base.feature @@ -211,6 +211,21 @@ Feature: Basic match | ("Paul Gasol" :player{age: 38, name: "Paul Gasol"}) | [:like "Paul Gasol"->"Marc Gasol" @0 {likeness: 99}] | ("Marc Gasol" :player{age: 34, name: "Marc Gasol"}) | | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | [:like "Yao Ming"->"Shaquile O'Neal" @0 {likeness: 90}] | ("Shaquile O'Neal" :player{age: 47, name: "Shaquile O'Neal"}) | | ("Yao Ming" :player{age: 38, name: "Yao Ming"}) | [:like "Yao Ming"->"Tracy McGrady" @0 {likeness: 90}] | ("Tracy McGrady" :player{age: 39, name: "Tracy McGrady"}) | + When executing query: + """ + MATCH (v:player)-[e:like]->(v2) where id(v) == "Tim Duncan" RETURN DISTINCT properties(e) as props, e + """ + Then the result should be, in any order, with relax comparison: + | props | e | + | {likeness: 95} | [:like "Tim Duncan"->"Manu Ginobili" @0 {likeness: 95}] | + | {likeness: 95} | [:like "Tim Duncan"->"Tony Parker" @0 {likeness: 95}] | + When executing query: + """ + MATCH (v:player)-[e:like]->(v2) where id(v) == "Tim Duncan" RETURN DISTINCT properties(e) as props + """ + Then the result should be, in any order, with relax comparison: + | props | + | {likeness: 95} | Scenario: two steps When executing query: