// newQueue creates a new download queue for scheduling block retrieval. func newQueue() *queue { return &queue{ hashPool: make(map[common.Hash]int), hashQueue: prque.New(), headerPool: make(map[common.Hash]*types.Header), headerQueue: prque.New(), pendPool: make(map[string]*fetchRequest), blockPool: make(map[common.Hash]uint64), blockCache: make([]*Block, blockCacheLimit), } }
// New creates a block fetcher to retrieve blocks based on hash announcements. func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertChain chainInsertFn, dropPeer peerDropFn) *Fetcher { return &Fetcher{ notify: make(chan *announce), inject: make(chan *inject), blockFilter: make(chan chan []*types.Block), headerFilter: make(chan chan *headerFilterTask), bodyFilter: make(chan chan *bodyFilterTask), done: make(chan common.Hash), quit: make(chan struct{}), announces: make(map[string]int), announced: make(map[common.Hash][]*announce), fetching: make(map[common.Hash]*announce), fetched: make(map[common.Hash][]*announce), completing: make(map[common.Hash]*announce), queue: prque.New(), queues: make(map[string]int), queued: make(map[common.Hash]*inject), getBlock: getBlock, validateBlock: validateBlock, broadcastBlock: broadcastBlock, chainHeight: chainHeight, insertChain: insertChain, dropPeer: dropPeer, } }
// newQueue creates a new download queue for scheduling block retrieval. func newQueue() *queue { return &queue{ hashPool: make(map[common.Hash]int), hashQueue: prque.New(), pendPool: make(map[string]*fetchRequest), blockPool: make(map[common.Hash]int), } }
// NewTrieSync creates a new trie data download scheduler. func NewTrieSync(root common.Hash, database ethdb.Database, callback TrieSyncLeafCallback) *TrieSync { ts := &TrieSync{ database: database, requests: make(map[common.Hash]*request), queue: prque.New(), } ts.AddSubTrie(root, 0, common.Hash{}, callback) return ts }
// newQueue creates a new download queue for scheduling block retrieval. func newQueue(stateDb ethdb.Database) *queue { return &queue{ hashPool: make(map[common.Hash]int), hashQueue: prque.New(), blockTaskPool: make(map[common.Hash]*types.Header), blockTaskQueue: prque.New(), blockPendPool: make(map[string]*fetchRequest), blockDonePool: make(map[common.Hash]struct{}), receiptTaskPool: make(map[common.Hash]*types.Header), receiptTaskQueue: prque.New(), receiptPendPool: make(map[string]*fetchRequest), receiptDonePool: make(map[common.Hash]struct{}), stateTaskPool: make(map[common.Hash]int), stateTaskQueue: prque.New(), statePendPool: make(map[string]*fetchRequest), stateDatabase: stateDb, resultCache: make([]*fetchResult, blockCacheLimit), } }
// newQueue creates a new download queue for scheduling block retrieval. func newQueue(stateDb ethdb.Database) *queue { lock := new(sync.Mutex) return &queue{ headerPendPool: make(map[string]*fetchRequest), headerContCh: make(chan bool), blockTaskPool: make(map[common.Hash]*types.Header), blockTaskQueue: prque.New(), blockPendPool: make(map[string]*fetchRequest), blockDonePool: make(map[common.Hash]struct{}), receiptTaskPool: make(map[common.Hash]*types.Header), receiptTaskQueue: prque.New(), receiptPendPool: make(map[string]*fetchRequest), receiptDonePool: make(map[common.Hash]struct{}), stateTaskPool: make(map[common.Hash]int), stateTaskQueue: prque.New(), statePendPool: make(map[string]*fetchRequest), stateDatabase: stateDb, resultCache: make([]*fetchResult, blockCacheLimit), active: sync.NewCond(lock), lock: lock, } }
// Insert some data into a priority queue and pop them out in prioritized order. func Example_usage() { // Define some data to push into the priority queue prio := []float32{77.7, 22.2, 44.4, 55.5, 11.1, 88.8, 33.3, 99.9, 0.0, 66.6} data := []string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"} // Create the priority queue and insert the prioritized data pq := prque.New() for i := 0; i < len(data); i++ { pq.Push(data[i], prio[i]) } // Pop out the data and print them for !pq.Empty() { val, prio := pq.Pop() fmt.Printf("%.1f:%s ", prio, val) } // Output: // 99.9:seven 88.8:five 77.7:zero 66.6:nine 55.5:three 44.4:two 33.3:six 22.2:one 11.1:four 0.0:eight }
// ScheduleSkeleton adds a batch of header retrieval tasks to the queue to fill // up an already retrieved header skeleton. func (q *queue) ScheduleSkeleton(from uint64, skeleton []*types.Header) { q.lock.Lock() defer q.lock.Unlock() // No skeleton retrieval can be in progress, fail hard if so (huge implementation bug) if q.headerResults != nil { panic("skeleton assembly already in progress") } // Shedule all the header retrieval tasks for the skeleton assembly q.headerTaskPool = make(map[uint64]*types.Header) q.headerTaskQueue = prque.New() q.headerPeerMiss = make(map[string]map[uint64]struct{}) // Reset availability to correct invalid chains q.headerResults = make([]*types.Header, len(skeleton)*MaxHeaderFetch) q.headerProced = 0 q.headerOffset = from q.headerContCh = make(chan bool, 1) for i, header := range skeleton { index := from + uint64(i*MaxHeaderFetch) q.headerTaskPool[index] = header q.headerTaskQueue.Push(index, -float32(index)) } }