github.com/prebid/prebid-server/v2@v2.18.0/usersync/bidderchooser.go (about)

     1  package usersync
     2  
     3  // bidderChooser determines which bidders to consider for user syncing.
     4  type bidderChooser interface {
     5  	// choose returns an ordered collection of potentially non-unique bidders.
     6  	choose(requested, available []string, cooperative Cooperative) []string
     7  }
     8  
     9  // standardBidderChooser implements the bidder choosing algorithm per official Prebid specification.
    10  type standardBidderChooser struct {
    11  	shuffler shuffler
    12  }
    13  
    14  func (c standardBidderChooser) choose(requested, available []string, cooperative Cooperative) []string {
    15  	if cooperative.Enabled {
    16  		return c.chooseCooperative(requested, available, cooperative.PriorityGroups)
    17  	}
    18  
    19  	if len(requested) == 0 {
    20  		return c.shuffledCopy(available)
    21  	}
    22  
    23  	return c.shuffledCopy(requested)
    24  }
    25  
    26  func (c standardBidderChooser) chooseCooperative(requested, available []string, priorityGroups [][]string) []string {
    27  	// allocate enough memory for the slice to try to avoid re-allocation. the 50% overhead is a guess
    28  	// at a satisfactory value. since all available bidders are included in the slice, along with
    29  	// requested and prioritized bidders, expect there to be be many duplicates. the duplicate are
    30  	// resolved in the upstream chooser algorithm.
    31  	biddersCapacity := int(float64(len(available)) * 1.5)
    32  	bidders := make([]string, 0, biddersCapacity)
    33  
    34  	// requested
    35  	bidders = c.shuffledAppend(bidders, requested)
    36  
    37  	// priority groups
    38  	for _, group := range priorityGroups {
    39  		bidders = c.shuffledAppend(bidders, group)
    40  	}
    41  
    42  	// available
    43  	bidders = c.shuffledAppend(bidders, available)
    44  
    45  	return bidders
    46  }
    47  
    48  func (c standardBidderChooser) shuffledCopy(a []string) []string {
    49  	aCopy := make([]string, len(a))
    50  	copy(aCopy, a)
    51  	c.shuffler.shuffle(aCopy)
    52  	return aCopy
    53  }
    54  
    55  func (c standardBidderChooser) shuffledAppend(a, b []string) []string {
    56  	startIndex := len(a)
    57  	a = append(a, b...)
    58  	c.shuffler.shuffle(a[startIndex:])
    59  	return a
    60  }