github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/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/log"
    20  	"github.com/pingcap/ticdc/cdc/model"
    21  )
    22  
    23  type barrierType int
    24  
    25  const (
    26  	// ddlJobBarrier denotes a replication barrier caused by a DDL.
    27  	ddlJobBarrier barrierType = iota
    28  	// syncPointBarrier denotes a barrier for snapshot replication.
    29  	syncPointBarrier
    30  	// finishBarrier denotes a barrier for changefeed finished.
    31  	finishBarrier
    32  )
    33  
    34  // barriers stores some barrierType and barrierTs, and can calculate the min barrierTs
    35  // barriers is NOT-THREAD-SAFE
    36  type barriers struct {
    37  	inner map[barrierType]model.Ts
    38  	dirty bool
    39  	min   barrierType
    40  }
    41  
    42  func newBarriers() *barriers {
    43  	return &barriers{
    44  		inner: make(map[barrierType]model.Ts),
    45  		dirty: true,
    46  	}
    47  }
    48  
    49  func (b *barriers) Update(tp barrierType, barrierTs model.Ts) {
    50  	// the barriers structure was given the ability to handle a fallback barrierTs by design.
    51  	// but the barrierTs should never fallback in owner replication model
    52  	if !b.dirty && (tp == b.min || barrierTs <= b.inner[b.min]) {
    53  		b.dirty = true
    54  	}
    55  	b.inner[tp] = barrierTs
    56  }
    57  
    58  func (b *barriers) Min() (tp barrierType, barrierTs model.Ts) {
    59  	if !b.dirty {
    60  		return b.min, b.inner[b.min]
    61  	}
    62  	tp, minTs := b.calcMin()
    63  	b.min = tp
    64  	b.dirty = false
    65  	return tp, minTs
    66  }
    67  
    68  func (b *barriers) calcMin() (tp barrierType, barrierTs model.Ts) {
    69  	barrierTs = uint64(math.MaxUint64)
    70  	for br, ts := range b.inner {
    71  		if ts <= barrierTs {
    72  			tp = br
    73  			barrierTs = ts
    74  		}
    75  	}
    76  	if barrierTs == math.MaxUint64 {
    77  		log.Panic("the barriers is empty, please report a bug")
    78  	}
    79  	return
    80  }
    81  
    82  func (b *barriers) Remove(tp barrierType) {
    83  	delete(b.inner, tp)
    84  	b.dirty = true
    85  }