Skip to content

Commit

Permalink
chore: cache round cells (#27)
Browse files Browse the repository at this point in the history
* chore: cache round cells

* chore: cache round cells x2

* chore: add failover to not panic on cell getting

* chore: add failover to not panic on cell getting, x2

* chore: fix first round not displaying

* chore: prevent overflow
  • Loading branch information
freak12techno authored Aug 10, 2024
1 parent 6cf21ae commit 6764b24
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 57 deletions.
103 changes: 69 additions & 34 deletions pkg/display/all_rounds_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,67 +15,102 @@ type AllRoundsTableData struct {
Validators types.ValidatorsWithInfoAndAllRoundVotes
DisableEmojis bool
Transpose bool

cells [][]*tview.TableCell
}

func NewAllRoundsTableData(disableEmojis bool, transpose bool) *AllRoundsTableData {
return &AllRoundsTableData{
Validators: types.ValidatorsWithInfoAndAllRoundVotes{},
DisableEmojis: disableEmojis,
Transpose: transpose,
cells: [][]*tview.TableCell{},
}
}

func (d *AllRoundsTableData) GetCell(row, column int) *tview.TableCell {
round := column - 1
if d.Transpose {
round = len(d.Validators.RoundsVotes) - column
}

// Table header.
if row == 0 {
text := "validator"
if column != 0 {
text = strconv.Itoa(round)
}

return tview.
NewTableCell(text).
SetAlign(tview.AlignCenter).
SetStyle(tcell.StyleDefault.Bold(true))
if len(d.cells) <= row {
return nil
}

// First column is always validators list.
if column == 0 {
text := d.Validators.Validators[row-1].Serialize()
cell := tview.NewTableCell(text)
return cell
}

roundVotes := d.Validators.RoundsVotes[round]
roundVote := roundVotes[row-1]
text := roundVote.Serialize(d.DisableEmojis)

cell := tview.NewTableCell(text)

if roundVote.IsProposer {
cell.SetBackgroundColor(tcell.ColorForestGreen)
if len(d.cells[row]) <= column {
return nil
}

return cell
return d.cells[row][column]
}

func (d *AllRoundsTableData) GetRowCount() int {
return len(d.Validators.Validators) + 1
return len(d.cells)
}

func (d *AllRoundsTableData) GetColumnCount() int {
return len(d.Validators.RoundsVotes) + 1
if len(d.cells) == 0 {
return 0
}

return len(d.cells[0])
}

func (d *AllRoundsTableData) SetValidators(validators types.ValidatorsWithInfoAndAllRoundVotes) {
if d.Validators.Equals(validators) {
return
}

d.Validators = validators
d.redrawCells()
}

func (d *AllRoundsTableData) SetTranspose(transpose bool) {
d.Transpose = transpose
d.redrawCells()
}

func (d *AllRoundsTableData) redrawCells() {
d.cells = make([][]*tview.TableCell, len(d.Validators.Validators)+1)

for row := 0; row < len(d.Validators.Validators)+1; row++ {
d.cells[row] = make([]*tview.TableCell, len(d.Validators.RoundsVotes)+1)

for column := 0; column < len(d.Validators.RoundsVotes)+1; column++ {
round := column - 1
if d.Transpose {
round = len(d.Validators.RoundsVotes) - column
}

// Table header.
if row == 0 {
text := "validator"
if column != 0 {
text = strconv.Itoa(round)
}

d.cells[row][column] = tview.
NewTableCell(text).
SetAlign(tview.AlignCenter).
SetStyle(tcell.StyleDefault.Bold(true))
continue
}

// First column is always validators list.
if column == 0 {
text := d.Validators.Validators[row-1].Serialize()
cell := tview.NewTableCell(text)
d.cells[row][column] = cell
continue
}

roundVotes := d.Validators.RoundsVotes[round]
roundVote := roundVotes[row-1]
text := roundVote.Serialize(d.DisableEmojis)

cell := tview.NewTableCell(text)

if roundVote.IsProposer {
cell.SetBackgroundColor(tcell.ColorForestGreen)
}

d.cells[row][column] = cell
}
}
}
76 changes: 54 additions & 22 deletions pkg/display/last_round_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ type LastRoundTableData struct {
ColumnsCount int
DisableEmojis bool
Transpose bool

cells [][]*tview.TableCell
}

func NewLastRoundTableData(columnsCount int, disableEmojis bool, transpose bool) *LastRoundTableData {
Expand All @@ -22,52 +24,82 @@ func NewLastRoundTableData(columnsCount int, disableEmojis bool, transpose bool)
Validators: make(types.ValidatorsWithInfo, 0),
DisableEmojis: disableEmojis,
Transpose: transpose,

cells: [][]*tview.TableCell{},
}
}

func (d *LastRoundTableData) SetColumnsCount(count int) {
d.ColumnsCount = count
d.redrawData()
}

func (d *LastRoundTableData) SetTranspose(transpose bool) {
d.Transpose = transpose
d.redrawData()
}

func (d *LastRoundTableData) GetCell(row, column int) *tview.TableCell {
index := row*d.ColumnsCount + column

if d.Transpose {
rows := d.GetRowCount()
index = column*rows + row
if len(d.cells) <= row {
return nil
}

text := ""

if index < len(d.Validators) {
text = d.Validators[index].Serialize(d.DisableEmojis)
}

cell := tview.NewTableCell(text)

if index < len(d.Validators) && d.Validators[index].RoundVote.IsProposer {
cell.SetBackgroundColor(tcell.ColorForestGreen)
if len(d.cells[row]) <= column {
return nil
}

return cell
return d.cells[row][column]
}

func (d *LastRoundTableData) GetRowCount() int {
if len(d.Validators)%d.ColumnsCount == 0 {
return len(d.Validators) / d.ColumnsCount
}

return len(d.Validators)/d.ColumnsCount + 1
return len(d.cells)
}

func (d *LastRoundTableData) GetColumnCount() int {
return d.ColumnsCount
if len(d.cells) == 0 {
return 0
}

return len(d.cells[0])
}

func (d *LastRoundTableData) SetValidators(validators types.ValidatorsWithInfo) {
d.Validators = validators
d.redrawData()
}

func (d *LastRoundTableData) redrawData() {
rowsCount := len(d.Validators)/d.ColumnsCount + 1
if len(d.Validators)%d.ColumnsCount == 0 {
rowsCount = len(d.Validators) / d.ColumnsCount
}

d.cells = make([][]*tview.TableCell, rowsCount)

for row := 0; row < rowsCount; row++ {
d.cells[row] = make([]*tview.TableCell, d.ColumnsCount)

for column := 0; column < d.ColumnsCount; column++ {
index := row*d.ColumnsCount + column

if d.Transpose {
rows := d.GetRowCount()
index = column*rows + row
}

text := ""

if index < len(d.Validators) {
text = d.Validators[index].Serialize(d.DisableEmojis)
}

cell := tview.NewTableCell(text)

if index < len(d.Validators) && d.Validators[index].RoundVote.IsProposer {
cell.SetBackgroundColor(tcell.ColorForestGreen)
}

d.cells[row][column] = cell
}
}
}
2 changes: 1 addition & 1 deletion pkg/display/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func NewWrapper(
SetBorders(false).
SetSelectable(false, false).
SetContent(allRoundsTableData).
SetFixed(0, 1)
SetFixed(1, 1)

consensusInfoTextView := tview.NewTextView().
SetDynamicColors(true).
Expand Down
91 changes: 91 additions & 0 deletions pkg/types/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ type RoundVote struct {
IsProposer bool
}

func (v RoundVote) Equals(other RoundVote) bool {
if v.Address != other.Address {
return false
}

if v.Prevote != other.Prevote {
return false
}

if v.Precommit != other.Precommit {
return false
}

if v.IsProposer != other.IsProposer {
return false
}

return false
}
func (v RoundVote) Serialize(disableEmojis bool) string {
return fmt.Sprintf(
" %s %s",
Expand Down Expand Up @@ -136,6 +155,46 @@ type ValidatorWithChainValidator struct {
ChainValidator *ChainValidator
}

func (v ValidatorWithChainValidator) Equals(other ValidatorWithChainValidator) bool {
if v.Validator.Index != other.Validator.Index {
return false
}

if v.Validator.Address != other.Validator.Address {
return false
}

if v.Validator.VotingPowerPercent.Cmp(other.Validator.VotingPowerPercent) != 0 {
return false
}

if v.Validator.VotingPower.Cmp(other.Validator.VotingPower) != 0 {
return false
}

if (v.ChainValidator == nil) != (other.ChainValidator == nil) {
return false
}

if v.ChainValidator == nil && other.ChainValidator == nil {
return true
}

if v.ChainValidator.Moniker != other.ChainValidator.Moniker {
return false
}

if v.ChainValidator.Address != other.ChainValidator.Address {
return false
}

if v.ChainValidator.AssignedAddress != other.ChainValidator.AssignedAddress {
return false
}

return true
}

func (v ValidatorWithChainValidator) Serialize() string {
name := v.Validator.Address
if v.ChainValidator != nil {
Expand All @@ -157,3 +216,35 @@ type ValidatorsWithInfoAndAllRoundVotes struct {
Validators []ValidatorWithChainValidator
RoundsVotes []RoundVotes
}

func (v ValidatorsWithInfoAndAllRoundVotes) Equals(other ValidatorsWithInfoAndAllRoundVotes) bool {
if len(v.RoundsVotes) != len(other.RoundsVotes) {
return false
}

for index, roundsVotes := range v.RoundsVotes {
otherRoundsVotes := other.RoundsVotes[index]
if len(roundsVotes) != len(otherRoundsVotes) {
return false
}

for innerIndex, roundVotes := range roundsVotes {
otherRoundVotes := otherRoundsVotes[innerIndex]
if roundVotes.Equals(otherRoundVotes) {
return false
}
}
}

if len(v.Validators) != len(other.Validators) {
return false
}

for index, validator := range v.Validators {
if !validator.Equals(other.Validators[index]) {
return false
}
}

return true
}

0 comments on commit 6764b24

Please sign in to comment.