github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitpage/compaction_iter.go (about)

     1  // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors.
     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 bitpage
    16  
    17  import (
    18  	"bytes"
    19  	"errors"
    20  )
    21  
    22  type compactionIter struct {
    23  	bp        *Bitpage
    24  	iter      internalIterator
    25  	err       error
    26  	key       internalKey
    27  	value     []byte
    28  	keyBuf    []byte
    29  	valid     bool
    30  	iterKey   *internalKey
    31  	iterValue []byte
    32  	skip      bool
    33  	pos       iterPos
    34  }
    35  
    36  func newCompactionIter(bp *Bitpage, iter internalIterator) *compactionIter {
    37  	i := &compactionIter{
    38  		bp:   bp,
    39  		iter: iter,
    40  	}
    41  	return i
    42  }
    43  
    44  func (i *compactionIter) First() (*internalKey, []byte) {
    45  	if i.err != nil {
    46  		return nil, nil
    47  	}
    48  	i.iterKey, i.iterValue = i.iter.First()
    49  	i.pos = iterPosNext
    50  	return i.Next()
    51  }
    52  
    53  func (i *compactionIter) Next() (*internalKey, []byte) {
    54  	if i.err != nil {
    55  		return nil, nil
    56  	}
    57  
    58  	if i.pos == iterPosCurForward {
    59  		if i.skip {
    60  			i.skipInStripe()
    61  		} else {
    62  			i.nextInStripe()
    63  		}
    64  	}
    65  
    66  	i.pos = iterPosCurForward
    67  	i.valid = false
    68  	for i.iterKey != nil {
    69  		switch i.iterKey.Kind() {
    70  		case internalKeyKindSet, internalKeyKindDelete, internalKeyKindPrefixDelete:
    71  			i.saveKey()
    72  			i.value = i.iterValue
    73  			i.valid = true
    74  			i.skip = true
    75  			return &i.key, i.value
    76  
    77  		default:
    78  			i.err = errors.New("invalid internal key kind")
    79  			i.valid = false
    80  			return nil, nil
    81  		}
    82  	}
    83  
    84  	return nil, nil
    85  }
    86  
    87  func (i *compactionIter) skipInStripe() {
    88  	i.skip = true
    89  	var change stripeChangeType
    90  	for {
    91  		change = i.nextInStripe()
    92  		if change == sameStripeNonSkippable || change == newStripe {
    93  			break
    94  		}
    95  	}
    96  
    97  	if change == newStripe {
    98  		i.skip = false
    99  	}
   100  }
   101  
   102  func (i *compactionIter) iterNext() bool {
   103  	i.iterKey, i.iterValue = i.iter.Next()
   104  	return i.iterKey != nil
   105  }
   106  
   107  type stripeChangeType int
   108  
   109  const (
   110  	newStripe stripeChangeType = iota
   111  	sameStripeSkippable
   112  	sameStripeNonSkippable
   113  )
   114  
   115  func (i *compactionIter) nextInStripe() stripeChangeType {
   116  	if !i.iterNext() {
   117  		return newStripe
   118  	}
   119  
   120  	key := i.iterKey
   121  	if !bytes.Equal(i.key.UserKey, key.UserKey) {
   122  		return newStripe
   123  	}
   124  
   125  	if key.Kind() == internalKeyKindInvalid {
   126  		return sameStripeNonSkippable
   127  	}
   128  
   129  	if i.bp != nil && key.SeqNum() == 1 {
   130  		i.bp.deleteBithashKey(i.iterValue)
   131  	}
   132  
   133  	return sameStripeSkippable
   134  }
   135  
   136  func (i *compactionIter) saveKey() {
   137  	i.keyBuf = append(i.keyBuf[:0], i.iterKey.UserKey...)
   138  	i.key.UserKey = i.keyBuf
   139  	i.key.Trailer = i.iterKey.Trailer
   140  }
   141  
   142  func (i *compactionIter) Key() internalKey {
   143  	return i.key
   144  }
   145  
   146  func (i *compactionIter) Value() []byte {
   147  	return i.value
   148  }
   149  
   150  func (i *compactionIter) Valid() bool {
   151  	return i.valid
   152  }
   153  
   154  func (i *compactionIter) Error() error {
   155  	return i.err
   156  }
   157  
   158  func (i *compactionIter) Close() error {
   159  	err := i.iter.Close()
   160  	if i.err == nil {
   161  		i.err = err
   162  	}
   163  
   164  	return i.err
   165  }