github.com/anacrolix/torrent@v1.61.0/atomic-count.go (about)

     1  package torrent
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"sync/atomic"
     8  )
     9  
    10  type Count struct {
    11  	n int64
    12  }
    13  
    14  var _ fmt.Stringer = (*Count)(nil)
    15  
    16  func (me *Count) Add(n int64) {
    17  	atomic.AddInt64(&me.n, n)
    18  }
    19  
    20  func (me *Count) Int64() int64 {
    21  	return atomic.LoadInt64(&me.n)
    22  }
    23  
    24  func (me *Count) String() string {
    25  	return fmt.Sprintf("%v", me.Int64())
    26  }
    27  
    28  func (me *Count) MarshalJSON() ([]byte, error) {
    29  	return json.Marshal(me.n)
    30  }
    31  
    32  // TODO: Can this use more generics to speed it up? Should we be checking the field types?
    33  func copyCountFields[T any](src *T) (dst T) {
    34  	srcValue := reflect.ValueOf(src).Elem()
    35  	dstValue := reflect.ValueOf(&dst).Elem()
    36  	for i := 0; i < reflect.TypeFor[T]().NumField(); i++ {
    37  		n := srcValue.Field(i).Addr().Interface().(*Count).Int64()
    38  		dstValue.Field(i).Addr().Interface().(*Count).Add(n)
    39  	}
    40  	return
    41  }