github.com/matrixorigin/matrixone@v1.2.0/pkg/common/hashmap/joinmap.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  	"sync/atomic"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    21  )
    22  
    23  func NewJoinMap(sels [][]int32, expr *plan.Expr, ihm *IntHashMap, shm *StrHashMap, hasNull bool, isDup bool) *JoinMap {
    24  	cnt := int64(1)
    25  	return &JoinMap{
    26  		cnt:       &cnt,
    27  		shm:       shm,
    28  		ihm:       ihm,
    29  		expr:      expr,
    30  		multiSels: sels,
    31  		hasNull:   hasNull,
    32  		dupCnt:    new(int64),
    33  		isDup:     isDup,
    34  	}
    35  }
    36  
    37  func (jm *JoinMap) SetPushedRuntimeFilterIn(b bool) {
    38  	jm.runtimeFilter_In = b
    39  }
    40  
    41  func (jm *JoinMap) PushedRuntimeFilterIn() bool {
    42  	return jm.runtimeFilter_In
    43  }
    44  
    45  func (jm *JoinMap) Sels() [][]int32 {
    46  	return jm.multiSels
    47  }
    48  
    49  func (jm *JoinMap) Expr() *plan.Expr {
    50  	return jm.expr
    51  }
    52  
    53  func (jm *JoinMap) HasNull() bool {
    54  	return jm.hasNull
    55  }
    56  
    57  func (jm *JoinMap) IsDup() bool {
    58  	return jm.isDup
    59  }
    60  
    61  func (jm *JoinMap) NewIterator() Iterator {
    62  	if jm.shm == nil {
    63  		return &intHashMapIterator{
    64  			mp:      jm.ihm,
    65  			m:       jm.ihm.m,
    66  			ibucket: jm.ihm.ibucket,
    67  			nbucket: jm.ihm.nbucket,
    68  		}
    69  	} else {
    70  		return &strHashmapIterator{
    71  			mp:      jm.shm,
    72  			m:       jm.shm.m,
    73  			ibucket: jm.shm.ibucket,
    74  			nbucket: jm.shm.nbucket,
    75  		}
    76  	}
    77  }
    78  
    79  func (jm *JoinMap) Dup() *JoinMap {
    80  	if jm.shm == nil {
    81  		m0 := &IntHashMap{
    82  			m:       jm.ihm.m,
    83  			hashMap: jm.ihm.hashMap,
    84  			hasNull: jm.ihm.hasNull,
    85  			ibucket: jm.ihm.ibucket,
    86  			nbucket: jm.ihm.nbucket,
    87  			keys:    make([]uint64, UnitLimit),
    88  			keyOffs: make([]uint32, UnitLimit),
    89  			values:  make([]uint64, UnitLimit),
    90  			zValues: make([]int64, UnitLimit),
    91  			hashes:  make([]uint64, UnitLimit),
    92  		}
    93  		jm0 := &JoinMap{
    94  			ihm:       m0,
    95  			expr:      jm.expr,
    96  			multiSels: jm.multiSels,
    97  			hasNull:   jm.hasNull,
    98  			cnt:       jm.cnt,
    99  		}
   100  		if atomic.AddInt64(jm.dupCnt, -1) == 0 {
   101  			jm.ihm = nil
   102  			jm.multiSels = nil
   103  		}
   104  		return jm0
   105  	} else {
   106  		m0 := &StrHashMap{
   107  			m:             jm.shm.m,
   108  			hashMap:       jm.shm.hashMap,
   109  			hasNull:       jm.shm.hasNull,
   110  			ibucket:       jm.shm.ibucket,
   111  			nbucket:       jm.shm.nbucket,
   112  			values:        make([]uint64, UnitLimit),
   113  			zValues:       make([]int64, UnitLimit),
   114  			keys:          make([][]byte, UnitLimit),
   115  			strHashStates: make([][3]uint64, UnitLimit),
   116  		}
   117  		jm0 := &JoinMap{
   118  			shm:       m0,
   119  			expr:      jm.expr,
   120  			multiSels: jm.multiSels,
   121  			hasNull:   jm.hasNull,
   122  			cnt:       jm.cnt,
   123  		}
   124  		if atomic.AddInt64(jm.dupCnt, -1) == 0 {
   125  			jm.shm = nil
   126  			jm.multiSels = nil
   127  		}
   128  		return jm0
   129  	}
   130  }
   131  
   132  func (jm *JoinMap) IncRef(ref int64) {
   133  	atomic.AddInt64(jm.cnt, ref)
   134  }
   135  
   136  func (jm *JoinMap) SetDupCount(ref int64) {
   137  	atomic.AddInt64(jm.dupCnt, ref)
   138  }
   139  
   140  func (jm *JoinMap) Free() {
   141  	if atomic.AddInt64(jm.cnt, -1) != 0 {
   142  		return
   143  	}
   144  	for i := range jm.multiSels {
   145  		jm.multiSels[i] = nil
   146  	}
   147  	jm.multiSels = nil
   148  	if jm.ihm != nil {
   149  		jm.ihm.Free()
   150  	} else {
   151  		jm.shm.Free()
   152  	}
   153  }
   154  
   155  func (jm *JoinMap) Size() int64 {
   156  	// TODO: add the size of the other JoinMap parts
   157  	if jm.ihm == nil && jm.shm == nil {
   158  		return 0
   159  	}
   160  	if jm.ihm != nil {
   161  		return jm.ihm.Size()
   162  	} else {
   163  		return jm.shm.Size()
   164  	}
   165  }