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  }