github.com/amazechain/amc@v0.1.3/internal/download/resultstore.go (about)

     1  // Copyright 2022 The AmazeChain Authors
     2  // This file is part of the AmazeChain library.
     3  //
     4  // The AmazeChain library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The AmazeChain library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package download
    18  
    19  import (
    20  	"sync"
    21  )
    22  
    23  // resultStore implements a structure for maintaining fetchResults, tracking their
    24  // download-progress and delivering (finished) results.
    25  type resultStore struct {
    26  	items        []*fetchResult // Downloaded but not yet delivered fetch results
    27  	resultOffset uint64         // Offset of the first cached fetch result in the block chain
    28  
    29  	// Internal index of first non-completed entry, updated atomically when needed.
    30  	// If all items are complete, this will equal length(items), so
    31  	// *important* : is not safe to use for indexing without checking against length
    32  	indexIncomplete int32 // atomic access
    33  
    34  	// throttleThreshold is the limit up to which we _want_ to fill the
    35  	// results. If blocks are large, we want to limit the results to less
    36  	// than the number of available slots, and maybe only fill 1024 out of
    37  	// 8192 possible places. The queue will, at certain times, recalibrate
    38  	// this index.
    39  	throttleThreshold uint64
    40  
    41  	lock sync.RWMutex
    42  }
    43  
    44  func newResultStore(size int) *resultStore {
    45  	return &resultStore{
    46  		resultOffset:      0,
    47  		items:             make([]*fetchResult, size),
    48  		throttleThreshold: uint64(size),
    49  	}
    50  }
    51  
    52  // SetThrottleThreshold updates the throttling threshold based on the requested
    53  // limit and the total queue capacity. It returns the (possibly capped) threshold
    54  func (r *resultStore) SetThrottleThreshold(threshold uint64) uint64 {
    55  	r.lock.Lock()
    56  	defer r.lock.Unlock()
    57  
    58  	limit := uint64(len(r.items))
    59  	if threshold >= limit {
    60  		threshold = limit
    61  	}
    62  	r.throttleThreshold = threshold
    63  	return r.throttleThreshold
    64  }
    65  
    66  // Prepare initialises the offset with the given block number
    67  func (r *resultStore) Prepare(offset uint64) {
    68  	r.lock.Lock()
    69  	defer r.lock.Unlock()
    70  
    71  	if r.resultOffset < offset {
    72  		r.resultOffset = offset
    73  	}
    74  }