github.com/matrixorigin/matrixone@v1.2.0/pkg/common/hashmap/iterator.go (about) 1 // Copyright 2021 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 hashmap 16 17 import ( 18 "unsafe" 19 20 "github.com/matrixorigin/matrixone/pkg/container/vector" 21 ) 22 23 func (itr *strHashmapIterator) Find(start, count int, vecs []*vector.Vector, inBuckets []uint8) ([]uint64, []int64) { 24 defer func() { 25 for i := 0; i < count; i++ { 26 itr.mp.keys[i] = itr.mp.keys[i][:0] 27 } 28 }() 29 copy(itr.mp.zValues[:count], OneInt64s[:count]) 30 itr.mp.encodeHashKeys(vecs, start, count) 31 if itr.nbucket != 0 { 32 itr.mp.hashMap.FindStringBatchInBucket(itr.mp.strHashStates, itr.mp.keys[:count], itr.mp.values, inBuckets, itr.ibucket, itr.nbucket) 33 } else { 34 itr.mp.hashMap.FindStringBatch(itr.mp.strHashStates, itr.mp.keys[:count], itr.mp.values) 35 } 36 return itr.mp.values[:count], itr.mp.zValues[:count] 37 } 38 39 func (itr *strHashmapIterator) Insert(start, count int, vecs []*vector.Vector) ([]uint64, []int64, error) { 40 var err error 41 42 defer func() { 43 for i := 0; i < count; i++ { 44 itr.mp.keys[i] = itr.mp.keys[i][:0] 45 } 46 }() 47 copy(itr.mp.zValues[:count], OneInt64s[:count]) 48 itr.mp.encodeHashKeys(vecs, start, count) 49 if itr.nbucket != 0 { 50 if itr.mp.hasNull { 51 err = itr.mp.hashMap.InsertStringBatchInBucket(itr.mp.strHashStates, itr.mp.keys[:count], itr.mp.values, itr.ibucket, itr.nbucket, itr.m) 52 } else { 53 err = itr.mp.hashMap.InsertStringBatchWithRingInBucket(itr.mp.zValues, itr.mp.strHashStates, itr.mp.keys[:count], itr.mp.values, itr.ibucket, itr.nbucket, itr.m) 54 } 55 } else { 56 if itr.mp.hasNull { 57 err = itr.mp.hashMap.InsertStringBatch(itr.mp.strHashStates, itr.mp.keys[:count], itr.mp.values, itr.m) 58 } else { 59 err = itr.mp.hashMap.InsertStringBatchWithRing(itr.mp.zValues, itr.mp.strHashStates, itr.mp.keys[:count], itr.mp.values, itr.m) 60 } 61 } 62 vs, zvs := itr.mp.values[:count], itr.mp.zValues[:count] 63 updateHashTableRows(itr.mp, vs, zvs) 64 return vs, zvs, err 65 } 66 67 func (itr *intHashMapIterator) Find(start, count int, vecs []*vector.Vector, inBuckets []uint8) ([]uint64, []int64) { 68 defer func() { 69 for i := 0; i < count; i++ { 70 itr.mp.keys[i] = 0 71 } 72 copy(itr.mp.keyOffs[:count], zeroUint32) 73 }() 74 copy(itr.mp.zValues[:count], OneInt64s[:count]) 75 itr.mp.encodeHashKeys(vecs, start, count) 76 copy(itr.mp.hashes[:count], zeroUint64[:count]) 77 if itr.nbucket != 0 { 78 itr.mp.hashMap.FindBatchInBucket(count, itr.mp.hashes[:count], unsafe.Pointer(&itr.mp.keys[0]), itr.mp.values[:count], inBuckets, itr.ibucket, itr.nbucket) 79 } else { 80 itr.mp.hashMap.FindBatch(count, itr.mp.hashes[:count], unsafe.Pointer(&itr.mp.keys[0]), itr.mp.values[:count]) 81 } 82 return itr.mp.values[:count], itr.mp.zValues[:count] 83 } 84 85 func (itr *intHashMapIterator) Insert(start, count int, vecs []*vector.Vector) ([]uint64, []int64, error) { 86 var err error 87 88 defer func() { 89 for i := 0; i < count; i++ { 90 itr.mp.keys[i] = 0 91 } 92 copy(itr.mp.keyOffs[:count], zeroUint32) 93 }() 94 95 copy(itr.mp.zValues[:count], OneInt64s[:count]) 96 itr.mp.encodeHashKeys(vecs, start, count) 97 copy(itr.mp.hashes[:count], zeroUint64[:count]) 98 if itr.nbucket != 0 { 99 if itr.mp.hasNull { 100 err = itr.mp.hashMap.InsertBatchInBucket(count, itr.mp.hashes[:count], unsafe.Pointer(&itr.mp.keys[0]), itr.mp.values, itr.ibucket, itr.nbucket, itr.m) 101 } else { 102 err = itr.mp.hashMap.InsertBatchWithRingInBucket(count, itr.mp.zValues, itr.mp.hashes[:count], unsafe.Pointer(&itr.mp.keys[0]), itr.mp.values, itr.ibucket, itr.nbucket, itr.m) 103 } 104 } else { 105 if itr.mp.hasNull { 106 err = itr.mp.hashMap.InsertBatch(count, itr.mp.hashes[:count], unsafe.Pointer(&itr.mp.keys[0]), itr.mp.values, itr.m) 107 } else { 108 err = itr.mp.hashMap.InsertBatchWithRing(count, itr.mp.zValues, itr.mp.hashes[:count], unsafe.Pointer(&itr.mp.keys[0]), itr.mp.values, itr.m) 109 } 110 } 111 vs, zvs := itr.mp.values[:count], itr.mp.zValues[:count] 112 updateHashTableRows(itr.mp, vs, zvs) 113 return vs, zvs, err 114 } 115 116 func updateHashTableRows(hashMap HashMap, vs []uint64, zvs []int64) { 117 groupCount := hashMap.GroupCount() 118 if hashMap.HasNull() { 119 for _, v := range vs { 120 if v > groupCount { 121 groupCount++ 122 } 123 } 124 } else { 125 for i, v := range vs { 126 if zvs[i] == 0 { 127 continue 128 } 129 if v > groupCount { 130 groupCount++ 131 } 132 } 133 } 134 count := groupCount - hashMap.GroupCount() 135 hashMap.AddGroups(count) 136 }