github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/consense/dpoa/comm/quorum.go (about)

     1  package comm
     2  
     3  import (
     4  	"sync"
     5  )
     6  
     7  // Quorum records each acknowledgement and check for different types of quorum satisfied
     8  type Quorum struct {
     9  	sync.RWMutex
    10  	total int
    11  	size  int
    12  	acks  map[ID]bool
    13  	zones map[int]int
    14  	nacks map[ID]bool
    15  }
    16  
    17  // NewQuorum returns a new Quorum
    18  func NewQuorum(total int) *Quorum {
    19  	q := &Quorum{
    20  		total: total,
    21  		size:  0,
    22  		acks:  make(map[ID]bool),
    23  		zones: make(map[int]int),
    24  	}
    25  	return q
    26  }
    27  
    28  // ACK adds id to quorum ack records
    29  func (q *Quorum) ACK(id ID) {
    30  	q.Lock()
    31  	defer q.Unlock()
    32  	if !q.acks[id] {
    33  		q.acks[id] = true
    34  		q.size++
    35  		q.zones[id.Zone()]++
    36  	}
    37  }
    38  
    39  // ADD increase ack size by one
    40  func (q *Quorum) ADD() {
    41  	q.size++
    42  }
    43  
    44  // Size returns current ack size
    45  func (q *Quorum) Size() int {
    46  	return q.size
    47  }
    48  
    49  // Reset resets the quorum to empty
    50  func (q *Quorum) Reset() {
    51  	q.size = 0
    52  	q.acks = make(map[ID]bool)
    53  	q.zones = make(map[int]int)
    54  	q.nacks = make(map[ID]bool)
    55  }
    56  
    57  // Majority quorum satisfied
    58  func (q *Quorum) Majority() bool {
    59  	/*for k, _:=range q.acks{
    60  		fmt.Println("-<<<<<<<<<<<<<<<<", q.size, k)
    61  	}
    62  	fmt.Println("<<<<<<<<<<<<<<<<", q.size, q.total)*/
    63  	return q.size > q.total/2
    64  }
    65  
    66  // Q1 returns true if config.Quorum type is satisfied
    67  func (q *Quorum) Q1() bool {
    68  	return q.Majority()
    69  }
    70  
    71  // Q2 returns true if config.Quorum type is satisfied
    72  func (q *Quorum) Q2() bool {
    73  	return q.Majority()
    74  }