github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/multi/hash.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package multi 16 17 import ( 18 "unsafe" 19 20 "github.com/matrixorigin/matrixone/pkg/common/hashmap" 21 "github.com/matrixorigin/matrixone/pkg/container/hashtable" 22 "github.com/matrixorigin/matrixone/pkg/container/types" 23 "github.com/matrixorigin/matrixone/pkg/container/vector" 24 "github.com/matrixorigin/matrixone/pkg/vm/process" 25 ) 26 27 func Hash(vecs []*vector.Vector, proc *process.Process) (*vector.Vector, error) { 28 vec := vector.New(types.New(types.T_int64, 0, 0, 0)) 29 count := vecs[0].Length() 30 keys := make([][]byte, hashmap.UnitLimit) 31 states := make([][3]uint64, hashmap.UnitLimit) 32 for i := 0; i < count; i += hashmap.UnitLimit { 33 n := count - i 34 if n > hashmap.UnitLimit { 35 n = hashmap.UnitLimit 36 } 37 encodeHashKeys(keys, vecs, i, n) 38 hashtable.BytesBatchGenHashStates(&keys[0], &states[0], n) 39 for j := 0; j < n; j++ { 40 if err := vec.Append(int64(states[j][0]), false, proc.Mp()); err != nil { 41 vec.Free(proc.Mp()) 42 return nil, err 43 } 44 } 45 } 46 return vec, nil 47 } 48 49 func encodeHashKeys(keys [][]byte, vecs []*vector.Vector, start, count int) { 50 for _, vec := range vecs { 51 if vec.GetType().IsFixedLen() { 52 fillGroupStr(keys, vec, count, vec.GetType().TypeSize(), start) 53 } else { 54 fillStringGroupStr(keys, vec, count, start) 55 } 56 } 57 for i := 0; i < count; i++ { 58 if l := len(keys[i]); l < 16 { 59 keys[i] = append(keys[i], hashtable.StrKeyPadding[l:]...) 60 } 61 } 62 } 63 64 func fillStringGroupStr(keys [][]byte, vec *vector.Vector, n int, start int) { 65 area := vec.GetArea() 66 vs := vector.MustTCols[types.Varlena](vec) 67 if !vec.GetNulls().Any() { 68 for i := 0; i < n; i++ { 69 keys[i] = append(keys[i], byte(0)) 70 keys[i] = append(keys[i], vs[i+start].GetByteSlice(area)...) 71 } 72 } else { 73 nsp := vec.GetNulls() 74 for i := 0; i < n; i++ { 75 hasNull := nsp.Contains(uint64(i + start)) 76 if hasNull { 77 keys[i] = append(keys[i], byte(1)) 78 } else { 79 keys[i] = append(keys[i], byte(0)) 80 keys[i] = append(keys[i], vs[i+start].GetByteSlice(area)...) 81 } 82 } 83 } 84 } 85 86 func fillGroupStr(keys [][]byte, vec *vector.Vector, n int, sz int, start int) { 87 data := unsafe.Slice((*byte)(vector.GetPtrAt(vec, 0)), (n+start)*sz) 88 if !vec.GetNulls().Any() { 89 for i := 0; i < n; i++ { 90 keys[i] = append(keys[i], byte(0)) 91 keys[i] = append(keys[i], data[(i+start)*sz:(i+start+1)*sz]...) 92 } 93 } else { 94 nsp := vec.GetNulls() 95 for i := 0; i < n; i++ { 96 isNull := nsp.Contains(uint64(i + start)) 97 if isNull { 98 keys[i] = append(keys[i], byte(1)) 99 } else { 100 keys[i] = append(keys[i], byte(0)) 101 keys[i] = append(keys[i], data[(i+start)*sz:(i+start+1)*sz]...) 102 } 103 } 104 } 105 }