github.com/prebid/prebid-server/v2@v2.18.0/exchange/price_granularity.go (about)

     1  package exchange
     2  
     3  import (
     4  	"math"
     5  	"strconv"
     6  
     7  	"github.com/prebid/openrtb/v20/openrtb2"
     8  	"github.com/prebid/prebid-server/v2/openrtb_ext"
     9  )
    10  
    11  // GetPriceBucket is the externally facing function for computing CPM buckets
    12  func GetPriceBucket(bid openrtb2.Bid, targetingData targetData) string {
    13  	cpmStr := ""
    14  	bucketMax := 0.0
    15  	bucketMin := 0.0
    16  	increment := 0.0
    17  
    18  	config := targetingData.priceGranularity //assign default price granularity
    19  
    20  	if bidType, err := getMediaTypeForBid(bid); err == nil {
    21  		if bidType == openrtb_ext.BidTypeBanner && targetingData.mediaTypePriceGranularity.Banner != nil {
    22  			config = *targetingData.mediaTypePriceGranularity.Banner
    23  		} else if bidType == openrtb_ext.BidTypeVideo && targetingData.mediaTypePriceGranularity.Video != nil {
    24  			config = *targetingData.mediaTypePriceGranularity.Video
    25  		} else if bidType == openrtb_ext.BidTypeNative && targetingData.mediaTypePriceGranularity.Native != nil {
    26  			config = *targetingData.mediaTypePriceGranularity.Native
    27  		}
    28  	}
    29  
    30  	precision := *config.Precision
    31  
    32  	cpm := bid.Price
    33  	for i := 0; i < len(config.Ranges); i++ {
    34  		if config.Ranges[i].Max > bucketMax {
    35  			bucketMax = config.Ranges[i].Max
    36  		}
    37  		// find what range cpm is in
    38  		if cpm >= config.Ranges[i].Min && cpm <= config.Ranges[i].Max {
    39  			increment = config.Ranges[i].Increment
    40  			bucketMin = config.Ranges[i].Min
    41  		}
    42  	}
    43  
    44  	if cpm > bucketMax {
    45  		// We are over max, just return that
    46  		cpmStr = strconv.FormatFloat(bucketMax, 'f', precision, 64)
    47  	} else if increment > 0 {
    48  		// If increment exists, get cpm string value
    49  		cpmStr = getCpmTarget(cpm, bucketMin, increment, precision)
    50  	}
    51  
    52  	return cpmStr
    53  }
    54  
    55  func getCpmTarget(cpm float64, bucketMin float64, increment float64, precision int) string {
    56  	roundedCPM := math.Floor((cpm-bucketMin)/increment)*increment + bucketMin
    57  	return strconv.FormatFloat(roundedCPM, 'f', precision, 64)
    58  }