github.com/matrixorigin/matrixone@v1.2.0/pkg/container/hashtable/fixed_set.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 hashtable 16 17 import ( 18 "math/bits" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 ) 22 23 type FixedSet struct { 24 cellCnt uint32 25 bitmap []uint64 26 } 27 28 type FixedSetIterator struct { 29 table *FixedSet 30 bitmapIdx uint32 31 bitmapSize uint32 32 bitmapVal uint64 33 } 34 35 func (ht *FixedSet) Init(cellCnt uint32) { 36 ht.cellCnt = cellCnt 37 ht.bitmap = make([]uint64, (int64(cellCnt)-1)/64+1) 38 } 39 40 func (ht *FixedSet) Insert(key uint32) (inserted bool) { 41 inserted = (ht.bitmap[key/8] | (1 << (key % 8))) == 0 42 ht.bitmap[key/8] |= 1 << (key % 8) 43 return 44 } 45 46 func (ht *FixedSet) Merge(other *FixedSet) { 47 for i, v := range other.bitmap { 48 ht.bitmap[i] |= v 49 } 50 } 51 52 func (ht *FixedSet) Cardinality() (cnt uint64) { 53 for _, v := range ht.bitmap { 54 cnt += uint64(bits.OnesCount64(v)) 55 } 56 return 57 } 58 59 func (it *FixedSetIterator) Init(ht *FixedSet) { 60 it.table = ht 61 it.bitmapIdx = 0 62 it.bitmapSize = uint32(len(ht.bitmap)) 63 it.bitmapVal = ht.bitmap[0] 64 } 65 66 func (it *FixedSetIterator) Next() (key uint32, err error) { 67 if it.bitmapVal != 0 { 68 tz := bits.TrailingZeros64(it.bitmapVal) 69 key = 64*it.bitmapIdx + uint32(tz) 70 it.bitmapVal ^= 1 << tz 71 72 return 73 } 74 75 for it.bitmapIdx < it.bitmapSize && it.table.bitmap[it.bitmapIdx] == 0 { 76 it.bitmapIdx++ 77 } 78 79 if it.bitmapIdx == it.bitmapSize { 80 err = moerr.NewInternalErrorNoCtx("out of range") 81 return 82 } 83 84 it.bitmapVal = it.table.bitmap[it.bitmapIdx] 85 key = 64*it.bitmapIdx + uint32(bits.TrailingZeros64(it.bitmapVal)) 86 87 return 88 }