Skip to content

Commit

Permalink
update auction algorithm logic for long-form (prebid#3625)
Browse files Browse the repository at this point in the history
  • Loading branch information
jaiminpanchal27 authored and jsnellbaker committed Mar 12, 2019
1 parent 0b39298 commit 6c48043
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 32 deletions.
15 changes: 15 additions & 0 deletions modules/adpod.js
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,18 @@ export function callPrebidCacheAfterAuction(bids, callback) {
}
})
}

/**
* Compare function to be used in sorting long-form bids. This will compare bids on price per second.
* @param {Object} bid
* @param {Object} bid
*/
export function sortByPricePerSecond(a, b) {
if (a.cpm / a.video.durationBucket < b.cpm / b.video.durationBucket) {
return 1;
}
if (a.cpm / a.video.durationBucket > b.cpm / b.video.durationBucket) {
return -1;
}
return 0;
}
18 changes: 3 additions & 15 deletions modules/freeWheelAdserverVideo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import { registerVideoSupport } from '../src/adServerManager';
import { auctionManager } from '../src/auctionManager';
import { groupBy, deepAccess, logError } from '../src/utils';
import { groupBy, deepAccess, logError, compareOn } from '../src/utils';
import { config } from '../src/config';
import { ADPOD } from '../src/mediaTypes';
import { initAdpodHooks, TARGETING_KEY_PB_CAT_DUR, TARGETING_KEY_CACHE_ID, callPrebidCacheAfterAuction } from './adpod';
import { initAdpodHooks, TARGETING_KEY_PB_CAT_DUR, TARGETING_KEY_CACHE_ID, callPrebidCacheAfterAuction, sortByPricePerSecond } from './adpod';
import { getHook } from '../src/hook';

export function notifyTranslationModule(fn) {
Expand Down Expand Up @@ -37,7 +37,7 @@ export function getTargeting({codes, callback} = {}) {

let bids = getBidsForAdpod(bidsReceived, adPodAdUnits);
bids = (competiveExclusionEnabled || deferCachingEnabled) ? getExclusiveBids(bids) : bids;
bids.sort(compareOn('cpm'));
bids.sort(sortByPricePerSecond);

let targeting = {};
if (deferCachingEnabled === false) {
Expand Down Expand Up @@ -119,18 +119,6 @@ function getAdPodAdUnits(codes) {
.filter((adUnit) => (codes.length > 0) ? codes.indexOf(adUnit.code) != -1 : true);
}

function compareOn(property) {
return function compare(a, b) {
if (a[property] < b[property]) {
return 1;
}
if (a[property] > b[property]) {
return -1;
}
return 0;
}
}

/**
* This function removes bids of same freewheel category. It will be used when competitive exclusion is enabled.
* @param {Array[Object]} bidsReceived
Expand Down
17 changes: 17 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1276,3 +1276,20 @@ export function getMinValueFromArray(array) {
export function getMaxValueFromArray(array) {
return Math.max(...array);
}

/**
* This function will create compare function to sort on object property
* @param {string} property
* @returns {function} compare function to be used in sorting
*/
export function compareOn(property) {
return function compare(a, b) {
if (a[property] < b[property]) {
return 1;
}
if (a[property] > b[property]) {
return -1;
}
return 0;
}
}
61 changes: 60 additions & 1 deletion test/spec/modules/adpod_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as videoCache from 'src/videoCache';
import * as auction from 'src/auction';
import { ADPOD } from 'src/mediaTypes';

import { callPrebidCacheHook, checkAdUnitSetupHook, checkVideoBidSetupHook, adpodSetConfig } from 'modules/adpod';
import { callPrebidCacheHook, checkAdUnitSetupHook, checkVideoBidSetupHook, adpodSetConfig, sortByPricePerSecond } from 'modules/adpod';

let expect = require('chai').expect;

Expand Down Expand Up @@ -990,4 +990,63 @@ describe('adpod.js', function () {
expect(logWarnStub.called).to.equal(false);
})
});

describe('adpod utils', function() {
it('should sort bids array', function() {
let bids = [{
cpm: 10.12345,
video: {
durationBucket: 15
}
}, {
cpm: 15,
video: {
durationBucket: 15
}
}, {
cpm: 15.00,
video: {
durationBucket: 30
}
}, {
cpm: 5.45,
video: {
durationBucket: 5
}
}, {
cpm: 20.1234567,
video: {
durationBucket: 60
}
}]
bids.sort(sortByPricePerSecond);
let sortedBids = [{
cpm: 5.45,
video: {
durationBucket: 5
}
}, {
cpm: 15,
video: {
durationBucket: 15
}
}, {
cpm: 10.12345,
video: {
durationBucket: 15
}
}, {
cpm: 15.00,
video: {
durationBucket: 30
}
}, {
cpm: 20.1234567,
video: {
durationBucket: 60
}
}]
expect(bids).to.include.deep.ordered.members(sortedBids);
});
})
});
32 changes: 16 additions & 16 deletions test/spec/modules/freeWheelAdserverVideo_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ describe('freeWheel adserver module', function() {
});

expect(targeting['preroll_1'].length).to.equal(3);
expect(targeting['midroll_1'].length).to.equal(2);
expect(targeting['midroll_1'].length).to.equal(3);
});

it('should return targeting for passed adunit code', function() {
Expand Down Expand Up @@ -128,7 +128,7 @@ describe('freeWheel adserver module', function() {
});

expect(targeting['preroll_1'].length).to.equal(3);
expect(targeting['midroll_1'].length).to.equal(2);
expect(targeting['midroll_1'].length).to.equal(3);
});

it('should return unique category bids when competitive exclusion is enabled', function() {
Expand All @@ -139,10 +139,10 @@ describe('freeWheel adserver module', function() {
}
});
amStub.returns([
createBid(10, 'preroll_1', 30, '10.00_airline_30s', '123', 'airline'),
createBid(15, 'preroll_1', 30, '15.00_airline_30s', '123', 'airline'),
createBid(15, 'midroll_1', 60, '15.00_travel_60s', '123', 'travel'),
createBid(10, 'preroll_1', 30, '10.00_airline_30s', '123', 'airline')
createBid(10, 'preroll_1', 30, '10.00_395_30s', '123', '395'),
createBid(15, 'preroll_1', 30, '15.00_395_30s', '123', '395'),
createBid(15, 'midroll_1', 60, '15.00_406_60s', '123', '406'),
createBid(10, 'preroll_1', 30, '10.00_395_30s', '123', '395')
]);
let targeting;
getTargeting({
Expand All @@ -157,9 +157,9 @@ describe('freeWheel adserver module', function() {

it('should only select bids less than adpod duration', function() {
amStub.returns([
createBid(10, 'preroll_1', 90, '10.00_airline_90s', '123', 'airline'),
createBid(15, 'preroll_1', 90, '15.00_airline_90s', '123', 'airline'),
createBid(15, 'midroll_1', 90, '15.00_travel_90s', '123', 'travel')
createBid(10, 'preroll_1', 90, '10.00_395_90s', '123', '395'),
createBid(15, 'preroll_1', 90, '15.00_395_90s', '123', '395'),
createBid(15, 'midroll_1', 90, '15.00_406_90s', '123', '406')
]);
let targeting;
getTargeting({
Expand Down Expand Up @@ -194,11 +194,11 @@ describe('freeWheel adserver module', function() {

function getBidsReceived() {
return [
createBid(10, 'preroll_1', 15, '10.00_airline_15s', '123', 'airline'),
createBid(15, 'preroll_1', 15, '15.00_airline_15s', '123', 'airline'),
createBid(15, 'midroll_1', 30, '15.00_travel_30s', '123', 'travel'),
createBid(5, 'midroll_1', 5, '5.00_travel_5s', '123', 'travel'),
createBid(20, 'midroll_1', 60, '20.00_travel_60s', '123', 'travel'),
createBid(10, 'preroll_1', 15, '10.00_395_15s', '123', '395'),
createBid(15, 'preroll_1', 15, '15.00_395_15s', '123', '395'),
createBid(15, 'midroll_1', 30, '15.00_406_30s', '123', '406'),
createBid(5, 'midroll_1', 5, '5.00_406_5s', '123', '406'),
createBid(20, 'midroll_1', 60, '20.00_406_60s', '123', '406'),
]
}

Expand All @@ -225,8 +225,8 @@ function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid,
'appnexus': {
'buyerMemberId': 9325
},
'vastUrl': 'http://nym1-ib.adnxs.com/ab?ro=1&referrer=http%3A%2F%2Fprebid.org%2Fexamples%2Fvideo%2FjwPlayerPrebid.html&e=wqT_3QKQCKAQBAAAAwDWAAUBCOC2reIFENXVz86_iKrdKRiyjp7_7P7s0GQqNgkAAAECCBRAEQEHNAAAFEAZAAAA4HoUFEAhERIAKREJADERG6gw6dGnBjjtSEDtSEgCUMuBwC5YnPFbYABozbp1eIHdBIABAYoBA1VTRJIBAQbwUJgBAaABAagBAbABALgBA8ABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU0ODQ0MjQ2NCk7dWYoJ3InLCA5NzUxNzc3MTYeAPQAAZIC8QEhOXpPdkVBaTItTHdLRU11QndDNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTZkR25CbGdBWUVwb0FIQ0FBWGdBZ0FHMEFvZ0JBSkFCQVpnQkFhQUJBYWdCQTdBQkFMa0I4NjFxcEFBQUZFREJBZk90YXFRQUFCUkF5UUhWSVlsRnN5SDRQOWtCQUFBQUFBQUE4RF9nQVFEMUFRQUFBQUNZQWdDZ0FnQzFBZ0FBQUFDOUFnQUFBQURBQWdESUFnRGdBZ0RvQWdENEFnQ0FBd0dRQXdDWUF3R29BN2I0dkFxNkF3bE9XVTB5T2pRd016SGdBODBGmgJhIU53M1VaUWkyLvQAKG5QRmJJQVFvQURFCY1cQUFVUURvSlRsbE5Nam8wTURNeFFNMEZTBZwYQUFBUEFfVREMDEFBQVcdDPBMwgI_aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy12aWRlby13aXRoLWEtZGZwLXZpZGVvLXRhZy5odG1s2AIA4AKtmEjqAjRGSgAgZXhhbXBsZXMvBUUkL2p3UGxheWVyUAlseGh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw3-8E6YBACiBAsxMC4xLjEyLjE4MKgEjq4IsgQSCAEQAhiABSDoAigBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNOWU0yOjQwMzHaBAIIAeAEAPAEYTYgiAUBmAUAoAX_EQEUAcAFAMkFaXAU8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklJPA_yAYA2gYWChAJEDQAAAAAAAAAAAAAEAAYAA..&s=539bcaeb9ce05a13a8c4a6cab3c000194a8e8f53',
'vastImpUrl': 'http://nym1-ib.adnxs.com/vast_track/v2?info=ZQAAAAMArgAFAQlgW0tcAAAAABHV6tP5Q6i6KRlgW0tcAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQ6dGnBljDlQtiAkZSaAFwAXgAgAEBiAEBkAGABZgB6AKgAQCoAcuBwC4.&s=61db1767c8c362ef1a58d2c5587dd6a9b1015aeb&event_type=1',
'vastUrl': 'http://some-vast-url.com',
'vastImpUrl': 'http://some-vast-imp-url.com',
'auctionId': 'ec266b31-d652-49c5-8295-e83fafe5532b',
'responseTimestamp': 1548442460888,
'requestTimestamp': 1548442460827,
Expand Down

0 comments on commit 6c48043

Please sign in to comment.