github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/txpool/mainchain/tx_queue.go (about)

     1  package mainchain
     2  
     3  import (
     4  	"sort"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/sixexorg/magnetic-ring/common"
     9  	"github.com/sixexorg/magnetic-ring/core/mainchain/types"
    10  	"github.com/sixexorg/magnetic-ring/log"
    11  )
    12  
    13  /*
    14  	Transaction queue
    15  */
    16  type TxQueue struct {
    17  	sync.RWMutex
    18  	txs      map[int64]*queueTx
    19  	txhashMp map[common.Hash]int64
    20  }
    21  
    22  type Int64Slice []int64
    23  
    24  func (p Int64Slice) Len() int           { return len(p) }
    25  func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] }
    26  func (p Int64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
    27  
    28  type queueTx struct {
    29  	tx     *types.Transaction
    30  	quTime int64
    31  }
    32  
    33  func newQueueTx(tx *types.Transaction) *queueTx {
    34  	qt := new(queueTx)
    35  	qt.tx = tx
    36  	qt.quTime = time.Now().UnixNano()
    37  	return qt
    38  }
    39  
    40  func NewTxQueue() *TxQueue {
    41  	queue := new(TxQueue)
    42  	queue.txs = make(map[int64]*queueTx)
    43  	queue.txhashMp = make(map[common.Hash]int64)
    44  	return queue
    45  }
    46  
    47  /**
    48    Add a deal to the end of the queue
    49  */
    50  func (queue *TxQueue) Enqueue(tx *types.Transaction) {
    51  	queue.Lock()
    52  	defer queue.Unlock()
    53  	qt := newQueueTx(tx)
    54  	queue.txs[qt.quTime] = qt
    55  	queue.txhashMp[tx.Hash()] = qt.quTime
    56  	log.Info("current queue", "map=", queue.txs)
    57  }
    58  
    59  /**
    60  	Remove and remove the transaction from the queue head
    61  */
    62  func (queue *TxQueue) Dequeue() *types.Transaction {
    63  	if len(queue.txs) < 1 {
    64  		return nil
    65  	}
    66  	queue.Lock()
    67  	defer queue.Unlock()
    68  
    69  	timearr := make(Int64Slice, 0)
    70  
    71  	for k, _ := range queue.txs {
    72  		timearr = append(timearr, k)
    73  	}
    74  
    75  	sort.Sort(timearr)
    76  
    77  	got := queue.txs[timearr[0]]
    78  	delete(queue.txs, got.quTime)
    79  	delete(queue.txhashMp, got.tx.Hash())
    80  
    81  	return got.tx
    82  }
    83  
    84  func (queue *TxQueue) Remove(hash common.Hash) *types.Transaction {
    85  	if len(queue.txs) < 1 {
    86  		return nil
    87  	}
    88  	queue.Lock()
    89  	defer queue.Unlock()
    90  
    91  	if tm, ok := queue.txhashMp[hash]; ok {
    92  		got := queue.txs[tm]
    93  		delete(queue.txs, got.quTime)
    94  		delete(queue.txhashMp, got.tx.Hash())
    95  		return got.tx
    96  	}
    97  
    98  	return nil
    99  }
   100  
   101  /**
   102  	Determine if the transaction is empty
   103  */
   104  func (q *TxQueue) IsEmpty() bool {
   105  	return len(q.txs) == 0
   106  }
   107  
   108  /**
   109  	Get the current number of transactions in the queue
   110  */
   111  func (pool *TxQueue) Size() int {
   112  	return len(pool.txs)
   113  }