github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/cdc/processor/sinkmanager/table_progress_heap.go (about)

     1  // Copyright 2022 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 sinkmanager
    15  
    16  import (
    17  	"container/heap"
    18  	"sync"
    19  
    20  	"github.com/pingcap/tiflow/cdc/processor/sourcemanager/sorter"
    21  	"github.com/pingcap/tiflow/cdc/processor/tablepb"
    22  )
    23  
    24  // progress is the fetch progress of a table.
    25  type progress struct {
    26  	span              tablepb.Span
    27  	nextLowerBoundPos sorter.Position
    28  	version           uint64
    29  }
    30  
    31  // Assert progressHeap implements heap.Interface
    32  var _ heap.Interface = (*progressHeap)(nil)
    33  
    34  type progressHeap struct {
    35  	heap []*progress
    36  }
    37  
    38  func newProgressHeap() *progressHeap {
    39  	return &progressHeap{
    40  		heap: make([]*progress, 0),
    41  	}
    42  }
    43  
    44  func (p *progressHeap) Len() int {
    45  	return len(p.heap)
    46  }
    47  
    48  func (p *progressHeap) Less(i, j int) bool {
    49  	a := p.heap[i]
    50  	b := p.heap[j]
    51  	return a.nextLowerBoundPos.Compare(b.nextLowerBoundPos) == -1
    52  }
    53  
    54  func (p *progressHeap) Swap(i, j int) {
    55  	p.heap[i], p.heap[j] = p.heap[j], p.heap[i]
    56  }
    57  
    58  func (p *progressHeap) Push(x any) {
    59  	p.heap = append(p.heap, x.(*progress))
    60  }
    61  
    62  func (p *progressHeap) Pop() any {
    63  	n := len(p.heap)
    64  	x := p.heap[n-1]
    65  	p.heap = p.heap[:n-1]
    66  	return x
    67  }
    68  
    69  // tableProgresses used to manage the progress of all tables.
    70  // SinkManager will use this to determine when and how to fetch data from the sorter.
    71  type tableProgresses struct {
    72  	mu   sync.Mutex
    73  	heap *progressHeap
    74  }
    75  
    76  func newTableProgresses() *tableProgresses {
    77  	ph := newProgressHeap()
    78  	heap.Init(ph)
    79  	return &tableProgresses{
    80  		heap: ph,
    81  	}
    82  }
    83  
    84  func (p *tableProgresses) push(progress *progress) {
    85  	p.mu.Lock()
    86  	defer p.mu.Unlock()
    87  	heap.Push(p.heap, progress)
    88  }
    89  
    90  func (p *tableProgresses) pop() *progress {
    91  	p.mu.Lock()
    92  	defer p.mu.Unlock()
    93  	return heap.Pop(p.heap).(*progress)
    94  }
    95  
    96  func (p *tableProgresses) len() int {
    97  	p.mu.Lock()
    98  	defer p.mu.Unlock()
    99  	return p.heap.Len()
   100  }