github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/owner/barrier.go (about)

     1  // Copyright 2021 PingCAP, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package owner
    15  
    16  import (
    17  	"math"
    18  
    19  	"github.com/pingcap/tiflow/cdc/model"
    20  )
    21  
    22  type barrierType int
    23  
    24  const (
    25  	// syncPointBarrier denotes a barrier for snapshot replication.
    26  	syncPointBarrier barrierType = iota
    27  	// finishBarrier denotes a barrier for changefeed finished.
    28  	finishBarrier
    29  )
    30  
    31  // barriers stores some barrierType and barrierTs, and can calculate the min barrierTs
    32  // barriers is NOT-THREAD-SAFE
    33  type barriers struct {
    34  	inner map[barrierType]model.Ts
    35  	dirty bool
    36  	min   barrierType
    37  }
    38  
    39  func newBarriers() *barriers {
    40  	return &barriers{
    41  		inner: make(map[barrierType]model.Ts),
    42  		dirty: true,
    43  	}
    44  }
    45  
    46  func (b *barriers) Update(tp barrierType, barrierTs model.Ts) {
    47  	// the barriers structure was given the ability to
    48  	// handle a fallback barrierTs by design.
    49  	// but the barrierTs should never fall back in owner replication model
    50  	if !b.dirty && (tp == b.min || barrierTs <= b.inner[b.min]) {
    51  		b.dirty = true
    52  	}
    53  	b.inner[tp] = barrierTs
    54  }
    55  
    56  func (b *barriers) Min() (tp barrierType, barrierTs model.Ts) {
    57  	if !b.dirty {
    58  		return b.min, b.inner[b.min]
    59  	}
    60  	tp, minTs := b.calcMin()
    61  	b.min = tp
    62  	b.dirty = false
    63  	return tp, minTs
    64  }
    65  
    66  func (b *barriers) calcMin() (tp barrierType, barrierTs model.Ts) {
    67  	barrierTs = uint64(math.MaxUint64)
    68  	for br, ts := range b.inner {
    69  		if ts <= barrierTs {
    70  			tp = br
    71  			barrierTs = ts
    72  		}
    73  	}
    74  	return
    75  }
    76  
    77  func (b *barriers) Remove(tp barrierType) {
    78  	delete(b.inner, tp)
    79  	b.dirty = true
    80  }