From 90badd6a83f9ff1b4e8b9addf58a83503f67e36e Mon Sep 17 00:00:00 2001 From: Haaai <55118568+Liuhaai@users.noreply.github.com> Date: Tue, 11 Jan 2022 23:25:49 -0800 Subject: [PATCH] [actpool] replace struct's value with its pointer in the heap (#2975) * store struct's pointer in the heap --- actpool/actqueue.go | 16 +++++++++------- actpool/actqueue_test.go | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/actpool/actqueue.go b/actpool/actqueue.go index f5b7599dff..6ff3d85962 100644 --- a/actpool/actqueue.go +++ b/actpool/actqueue.go @@ -27,24 +27,26 @@ type nonceWithTTL struct { deadline time.Time } -type noncePriorityQueue []nonceWithTTL +type noncePriorityQueue []*nonceWithTTL func (h noncePriorityQueue) Len() int { return len(h) } func (h noncePriorityQueue) Less(i, j int) bool { return h[i].nonce < h[j].nonce } func (h noncePriorityQueue) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *noncePriorityQueue) Push(x interface{}) { - in, ok := x.(nonceWithTTL) - if !ok { - return + if in, ok := x.(*nonceWithTTL); ok { + *h = append(*h, in) } - *h = append(*h, in) } func (h *noncePriorityQueue) Pop() interface{} { old := *h n := len(old) + if n == 0 { + return nil + } x := old[n-1] + old[n-1] = nil // avoid memory leak *h = old[0 : n-1] return x } @@ -121,7 +123,7 @@ func (q *actQueue) Put(act action.SealedEnvelope) error { } return nil } - heap.Push(&q.index, nonceWithTTL{nonce: nonce, deadline: q.clock.Now().Add(q.ttl)}) + heap.Push(&q.index, &nonceWithTTL{nonce: nonce, deadline: q.clock.Now().Add(q.ttl)}) q.items[nonce] = act return nil } @@ -131,7 +133,7 @@ func (q *actQueue) FilterNonce(threshold uint64) []action.SealedEnvelope { var removed []action.SealedEnvelope // Pop off priority queue and delete corresponding entries from map until the threshold is reached for q.index.Len() > 0 && (q.index)[0].nonce < threshold { - nonce := heap.Pop(&q.index).(nonceWithTTL).nonce + nonce := heap.Pop(&q.index).(*nonceWithTTL).nonce removed = append(removed, q.items[nonce]) delete(q.items, nonce) } diff --git a/actpool/actqueue_test.go b/actpool/actqueue_test.go index 7c4720ab44..56b67094d5 100644 --- a/actpool/actqueue_test.go +++ b/actpool/actqueue_test.go @@ -29,27 +29,27 @@ func TestNoncePriorityQueue(t *testing.T) { require := require.New(t) pq := noncePriorityQueue{} // Push four dummy nonce to the queue - heap.Push(&pq, nonceWithTTL{nonce: uint64(1)}) - heap.Push(&pq, nonceWithTTL{nonce: uint64(3)}) - heap.Push(&pq, nonceWithTTL{nonce: uint64(2)}) + heap.Push(&pq, &nonceWithTTL{nonce: uint64(1)}) + heap.Push(&pq, &nonceWithTTL{nonce: uint64(3)}) + heap.Push(&pq, &nonceWithTTL{nonce: uint64(2)}) // Test Pop implementation i := uint64(1) for pq.Len() > 0 { - nonce := heap.Pop(&pq).(nonceWithTTL).nonce + nonce := heap.Pop(&pq).(*nonceWithTTL).nonce require.Equal(i, nonce) i++ } // Repush the four dummy nonce back to the queue - heap.Push(&pq, nonceWithTTL{nonce: uint64(3)}) - heap.Push(&pq, nonceWithTTL{nonce: uint64(2)}) - heap.Push(&pq, nonceWithTTL{nonce: uint64(1)}) + heap.Push(&pq, &nonceWithTTL{nonce: uint64(3)}) + heap.Push(&pq, &nonceWithTTL{nonce: uint64(2)}) + heap.Push(&pq, &nonceWithTTL{nonce: uint64(1)}) // Test built-in Remove implementation // Remove a random nonce from noncePriorityQueue rand.Seed(time.Now().UnixNano()) heap.Remove(&pq, rand.Intn(pq.Len())) t.Log("After randomly removing a dummy nonce, the remaining dummy nonces in the order of popped are as follows:") for pq.Len() > 0 { - nonce := heap.Pop(&pq).(nonceWithTTL).nonce + nonce := heap.Pop(&pq).(*nonceWithTTL).nonce t.Log(nonce) t.Log() } @@ -66,9 +66,9 @@ func TestActQueuePut(t *testing.T) { tsf2, err := action.SignedTransfer(addr2, priKey1, 1, big.NewInt(100), nil, uint64(0), big.NewInt(1)) require.NoError(err) require.NoError(q.Put(tsf2)) - require.Equal(uint64(1), heap.Pop(&q.index).(nonceWithTTL).nonce) + require.Equal(uint64(1), heap.Pop(&q.index).(*nonceWithTTL).nonce) require.Equal(tsf2, q.items[uint64(1)]) - require.Equal(uint64(2), heap.Pop(&q.index).(nonceWithTTL).nonce) + require.Equal(uint64(2), heap.Pop(&q.index).(*nonceWithTTL).nonce) require.Equal(tsf1, q.items[uint64(2)]) // tsf3 is a act which fails to cut in line tsf3, err := action.SignedTransfer(addr2, priKey1, 1, big.NewInt(1000), nil, uint64(0), big.NewInt(0)) @@ -236,7 +236,7 @@ func TestActQueueCleanTimeout(t *testing.T) { q.items[6] = tsf6 q.items[7] = tsf7 - q.index = []nonceWithTTL{ + q.index = []*nonceWithTTL{ {1, validTime}, {5, validTime}, {2, validTime}, @@ -251,7 +251,7 @@ func TestActQueueCleanTimeout(t *testing.T) { require.Equal(expectedHeap[i], q.index[i].nonce) } - q.index = []nonceWithTTL{ + q.index = []*nonceWithTTL{ {1, validTime}, {5, validTime}, {2, validTime},