github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/sequencer/efficiencylist.go (about) 1 package sequencer 2 3 import ( 4 "fmt" 5 "sort" 6 "sync" 7 8 "github.com/0xPolygon/supernets2-node/log" 9 ) 10 11 // efficiencyList represents a list of tx sorted by efficiency 12 type efficiencyList struct { 13 list map[string]*TxTracker 14 sorted []*TxTracker 15 mutex sync.Mutex 16 } 17 18 // newEfficiencyList creates and init an efficiencyList 19 func newEfficiencyList() *efficiencyList { 20 return &efficiencyList{ 21 list: make(map[string]*TxTracker), 22 sorted: []*TxTracker{}, 23 } 24 } 25 26 // add adds a tx to the efficiencyList 27 func (e *efficiencyList) add(tx *TxTracker) bool { 28 e.mutex.Lock() 29 defer e.mutex.Unlock() 30 31 if _, found := e.list[tx.HashStr]; !found { 32 e.list[tx.HashStr] = tx 33 e.addSort(tx) 34 return true 35 } 36 return false 37 } 38 39 // delete deletes the tx from the efficiencyList 40 func (e *efficiencyList) delete(tx *TxTracker) bool { 41 e.mutex.Lock() 42 defer e.mutex.Unlock() 43 44 if tx, found := e.list[tx.HashStr]; found { 45 sLen := len(e.sorted) 46 i := sort.Search(sLen, func(i int) bool { 47 return e.isGreaterThan(tx, e.list[e.sorted[i].HashStr]) 48 }) 49 50 if (e.sorted[i].HashStr != tx.HashStr) || i == sLen { 51 log.Errorf("Error deleting tx from efficiencyList: %s", tx.HashStr) 52 return false 53 } 54 55 delete(e.list, tx.HashStr) 56 57 copy(e.sorted[i:], e.sorted[i+1:]) 58 e.sorted[sLen-1] = nil 59 e.sorted = e.sorted[:sLen-1] 60 61 return true 62 } 63 return false 64 } 65 66 // getByIndex retrieves the tx at the i position in the sorted EfficiencyList 67 func (e *efficiencyList) getByIndex(i int) *TxTracker { 68 e.mutex.Lock() 69 defer e.mutex.Unlock() 70 71 tx := e.sorted[i] 72 73 return tx 74 } 75 76 // len returns the length of the EfficiencyList 77 func (e *efficiencyList) len() int { 78 e.mutex.Lock() 79 defer e.mutex.Unlock() 80 81 l := len(e.sorted) 82 83 return l 84 } 85 86 // print prints the contents of the EfficiencyList 87 func (e *efficiencyList) Print() { 88 e.mutex.Lock() 89 defer e.mutex.Unlock() 90 91 fmt.Println("Len: ", len(e.sorted)) 92 for _, txi := range e.sorted { 93 fmt.Printf("Hash=%s, efficiency=%f\n", txi.HashStr, txi.Efficiency) 94 } 95 } 96 97 // addSort adds the tx to the EfficiencyList in a sorted way 98 func (e *efficiencyList) addSort(tx *TxTracker) { 99 i := sort.Search(len(e.sorted), func(i int) bool { 100 return e.isGreaterThan(tx, e.list[e.sorted[i].HashStr]) 101 }) 102 103 e.sorted = append(e.sorted, nil) 104 copy(e.sorted[i+1:], e.sorted[i:]) 105 e.sorted[i] = tx 106 log.Infof("Added tx(%s) to efficiencyList. With efficiency(%f) at index(%d) from total(%d)", tx.HashStr, tx.Efficiency, i, len(e.sorted)) 107 } 108 109 // isGreaterThan returns true if the tx1 has best efficiency than tx2 110 func (e *efficiencyList) isGreaterThan(tx1 *TxTracker, tx2 *TxTracker) bool { 111 if tx1.Efficiency > tx2.Efficiency { 112 return true 113 } else if tx1.Efficiency == tx2.Efficiency { 114 return tx1.HashStr >= tx2.HashStr 115 } else { 116 return false 117 } 118 } 119 120 // GetSorted returns the sorted list of tx 121 func (e *efficiencyList) GetSorted() []*TxTracker { 122 e.mutex.Lock() 123 defer e.mutex.Unlock() 124 125 return e.sorted 126 }