1
+ // Licensed to the Apache Software Foundation (ASF) under one
2
+ // or more contributor license agreements. See the NOTICE file
3
+ // distributed with this work for additional information
4
+ // regarding copyright ownership. The ASF licenses this file
5
+ // to you under the Apache License, Version 2.0 (the
6
+ // "License"); you may not use this file except in compliance
7
+ // with the License. You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing,
12
+ // software distributed under the License is distributed on an
13
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ // KIND, either express or implied. See the License for the
15
+ // specific language governing permissions and limitations
16
+ // under the License.
17
+
18
+ #include < gtest/gtest.h>
19
+
20
+ #include " testutil/column_helper.h"
21
+ #include " vec/common/columns_hashing.h"
22
+ #include " vec/common/hash_table/hash.h"
23
+ #include " vec/common/hash_table/hash_map_context.h"
24
+ #include " vec/common/hash_table/ph_hash_map.h"
25
+ #include " vec/data_types/data_type_number.h"
26
+
27
+ namespace doris ::vectorized {
28
+
29
+ template <typename HashMethodType>
30
+ void test_insert (HashMethodType& method, ColumnPtrs column) {
31
+ using State = typename HashMethodType::State;
32
+ ColumnRawPtrs key_raw_columns;
33
+ for (auto column : column) {
34
+ key_raw_columns.push_back (column.get ());
35
+ }
36
+ State state (key_raw_columns);
37
+ const size_t rows = key_raw_columns[0 ]->size ();
38
+ method.init_serialized_keys (key_raw_columns, rows);
39
+
40
+ for (int i = 0 ; i < rows; i++) {
41
+ auto creator = [&](const auto & ctor, auto & key, auto & origin) { ctor (key, i); };
42
+
43
+ auto creator_for_null_key = [&](auto & mapped) {
44
+ throw doris::Exception (ErrorCode::INTERNAL_ERROR,
45
+ " no null key" ); // NOLINT
46
+ };
47
+ method.lazy_emplace (state, i, creator, creator_for_null_key);
48
+ }
49
+ }
50
+
51
+ template <typename HashMethodType>
52
+ void test_find (HashMethodType& method, ColumnPtrs column,
53
+ const std::vector<int64_t >& except_result) {
54
+ using State = typename HashMethodType::State;
55
+ ColumnRawPtrs key_raw_columns;
56
+ for (auto column : column) {
57
+ key_raw_columns.push_back (column.get ());
58
+ }
59
+ State state (key_raw_columns);
60
+ const size_t rows = key_raw_columns[0 ]->size ();
61
+ method.init_serialized_keys (key_raw_columns, rows);
62
+ for (size_t i = 0 ; i < rows; ++i) {
63
+ auto find_result = method.find (state, i);
64
+ if (find_result.is_found ()) {
65
+ EXPECT_EQ (except_result[i], find_result.get_mapped ());
66
+ } else {
67
+ EXPECT_EQ (except_result[i], -1 ); // not found
68
+ }
69
+ }
70
+ }
71
+
72
+ TEST (HashTableMethodTest, testMethodOneNumber) {
73
+ MethodOneNumber<UInt32, PHHashMap<UInt32, IColumn::ColumnIndex, HashCRC32<UInt32>>> method;
74
+
75
+ test_insert (method, {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 })});
76
+
77
+ test_find (method, {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 })},
78
+ {0 , 1 , 2 , 3 , 4 });
79
+
80
+ test_find (method, {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 7 , 4 , 6 , 5 })},
81
+ {0 , 1 , -1 , 3 , -1 , 4 });
82
+ }
83
+
84
+ TEST (HashTableMethodTest, testMethodFixed) {
85
+ MethodKeysFixed<PHHashMap<UInt64, IColumn::ColumnIndex, HashCRC32<UInt64>>> method (
86
+ Sizes {sizeof (int ), sizeof (int )});
87
+
88
+ test_insert (method, {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 }),
89
+ ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 })});
90
+
91
+ test_find (method,
92
+ {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 }),
93
+ ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 })},
94
+ {0 , 1 , 2 , 3 , 4 });
95
+
96
+ test_find (method,
97
+ {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 7 , 4 , 6 , 5 }),
98
+ ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 7 , 4 , 6 , 5 })},
99
+ {0 , 1 , -1 , 3 , -1 , 4 });
100
+ }
101
+
102
+ TEST (HashTableMethodTest, testMethodSerialized) {
103
+ MethodSerialized<StringHashMap<IColumn::ColumnIndex>> method;
104
+
105
+ test_insert (method, {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 }),
106
+ ColumnHelper::create_column<DataTypeString>({" 1" , " 2" , " 3" , " 4" , " 5" })});
107
+
108
+ test_find (method,
109
+ {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 3 , 4 , 5 }),
110
+ ColumnHelper::create_column<DataTypeString>({" 1" , " 2" , " 3" , " 4" , " 5" })},
111
+ {0 , 1 , 2 , 3 , 4 });
112
+
113
+ test_find (method,
114
+ {ColumnHelper::create_column<DataTypeInt32>({1 , 2 , 7 , 4 , 6 , 5 }),
115
+ ColumnHelper::create_column<DataTypeString>({" 1" , " 2" , " 7" , " 4" , " 6" , " 5" })},
116
+ {0 , 1 , -1 , 3 , -1 , 4 });
117
+ }
118
+
119
+ TEST (HashTableMethodTest, testMethodStringNoCache) {
120
+ MethodStringNoCache<StringHashMap<IColumn::ColumnIndex>> method;
121
+
122
+ test_insert (method, {ColumnHelper::create_column<DataTypeString>({" 1" , " 2" , " 3" , " 4" , " 5" })});
123
+
124
+ test_find (method, {ColumnHelper::create_column<DataTypeString>({" 1" , " 2" , " 3" , " 4" , " 5" })},
125
+ {0 , 1 , 2 , 3 , 4 });
126
+
127
+ test_find (method, {ColumnHelper::create_column<DataTypeString>({" 1" , " 2" , " 7" , " 4" , " 6" , " 5" })},
128
+ {0 , 1 , -1 , 3 , -1 , 4 });
129
+ }
130
+
131
+ } // namespace doris::vectorized
0 commit comments