Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance Improvements & Some refactor #21

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 26 additions & 18 deletions regional_standings/model/data_loader.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
"use strict";

const fs = require('fs');
const Region = require('./util/region');
const Team = require('./team');
const remapValueClamped = require('./util/remap_value_clamped');

const __highValueEvents = [6372,6711,6712,6713,6714,6586,6588]; //explicitly include RMR events, Majors
const matchData = require('../data/matchdata.json');
const {SortOrderEnum} = require("./enums/sort_order");

function parsePrizePool( prizePool ) {
if ( prizePool === undefined )
Expand All @@ -18,13 +15,29 @@ function parsePrizePool( prizePool ) {
return 0;
}

function sortMatches( matches, order = 'desc' ) {
if ( order === 'asc' )
function sortMatches( matches, order = SortOrderEnum.DESC ) {
if ( order === SortOrderEnum.ASC )
matches.sort( (a, b) => a.matchStartTime - b.matchStartTime );
else
matches.sort( (a, b) => b.matchStartTime - a.matchStartTime );
}

function cloneEvent(event) {
return {
...event,
prizeDistribution: event.prizeDistribution.map(team => ({...team}))
}
}

function cloneMatch(match) {
return {
...match,
team1Players: match.team1Players.map(player => ({...player})),
team2Players: match.team2Players.map(player => ({...player})),
maps: match.maps.map(map => ({...map}))
}
}

function filterIncompleteMatches( matches ) {
return matches.filter( match => ( match.team1Players.length === 5 && match.team2Players.length === 5 ) );
}
Expand Down Expand Up @@ -157,23 +170,18 @@ class DataLoader

loadData( versionTimestamp = -1 )
{
const data = fs.readFileSync( '../data/matchdata.json' );
const dataJson = JSON.parse( data );

// initialize match list
let matches = dataJson.matches;

// Filter matches to only the data we are interested in.
this.setTimeFilter( versionTimestamp );
matches = filterIncompleteMatches( matches );
let matches = filterIncompleteMatches( matchData.matches );
const [startTime,endTime] = findTimeWindow( matches, this.filterEndTime, this.filterWindow );
let graceperiod = 30 * 24 * 3600; // 1 month
this.rankingContext.setTimeWindow( startTime, endTime - graceperiod );
matches = filterMatchesByTime( matches, startTime, endTime );
matches = matches.map(match => cloneMatch(match));

// initialize event list
let events = {};
dataJson.events.forEach( eventJson => events[eventJson.eventId] = new Event( eventJson ) );
matchData.events.forEach(eventJson => events[eventJson.eventId] = new Event( cloneEvent(eventJson) ));

// Let each event know what matches were part of it
matches.forEach( match => {
Expand All @@ -195,14 +203,14 @@ class DataLoader

// When initializing the teams, sort matches by reverse start time so we always see the
// most recent match for a particular roster as the 'base' roster for that team.
sortMatches( matches, 'desc' );
sortMatches( matches, SortOrderEnum.DESC );

let teams = initTeams( matches, events, this.rankingContext );
const teams = initTeams( matches, events, this.rankingContext );

// For processing the games and calculating ratings, we will go in forward order in time. This
// also has the effect of making sure that recent data is considered the most strongly, and also
// with as much context as possible given past results.
sortMatches( matches, 'asc' );
sortMatches( matches, SortOrderEnum.ASC );

this.matches = matches;
this.teams = teams;
Expand Down
11 changes: 11 additions & 0 deletions regional_standings/model/enums/region.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use strict";

const RegionEnum = Object.freeze({
EU: 0,
AMERICAS: 1,
NA: 1,
SA: 1,
OTHERS: 2,
});

module.exports = {RegionEnum}
10 changes: 10 additions & 0 deletions regional_standings/model/enums/sort_order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"use strict";

const SortOrderEnum = Object.freeze({
ASC: 'asc',
DESC: 'desc'
})

module.exports = {
SortOrderEnum
};
9 changes: 9 additions & 0 deletions regional_standings/model/enums/text_pad_direction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use strict";

const TextPadDirection = Object.freeze({
LEFT: -1,
RIGHT: 1,
CENTER: 0,
})

module.exports = {TextPadDirection};
3 changes: 0 additions & 3 deletions regional_standings/model/fit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ module.exports = {
outputEWRBins: outputEWRBins
}

const { match } = require('assert');
const Glicko = require('./glicko');
const Ranking = require('./ranking');
const fs = require('fs');
const { time } = require('console');

const defaultGlickoParams = {
rd : 75,
Expand Down
5 changes: 3 additions & 2 deletions regional_standings/model/ranking.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ function seedTeams( glicko, teams ) {
} );

// remap teams from current range to minRankValue..maxRankValue
let minSeedValue = Math.min( ...teams.map(t => t.seedValue ) );
let maxSeedValue = Math.max( ...teams.map(t => t.seedValue ) );
const teamsSeedValue = teams.map(t => t.seedValue )
let minSeedValue = Math.min( ...teamsSeedValue );
let maxSeedValue = Math.max( ...teamsSeedValue );

teams.forEach( team => {
team.rankValue = remapValueClamped( team.seedValue, minSeedValue, maxSeedValue, MIN_SEEDED_RANK, MAX_SEEDED_RANK );
Expand Down
24 changes: 13 additions & 11 deletions regional_standings/model/table.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
"use strict";

const { TextPadDirection } = require("./enums/text_pad_direction");

// Pad/truncate a string to a given length
function stringWithLength( s, n, padDirection = -1 )
function stringWithLength( s, n, padDirection = TextPadDirection.LEFT )
{
s = String( s );

// check for strings that are short enough
if( n < s.length )
return s.substring( 0, n );
else if( n == s.length )
else if( n === s.length )
return s;

// otherwise we need to pad.
const extra = n - s.length;
if( padDirection < 0 )
return ' '.repeat( extra ) + s;
else if( padDirection > 0 )
return s + ' '.repeat( extra );
if( padDirection === TextPadDirection.LEFT )
return s.padStart(n, ' ');
else if( padDirection === TextPadDirection.RIGHT )
return s.padEnd(n, ' ');

// else center
const extra = n - s.length;
const left = Math.floor( extra / 2 );
const right = extra - left;
return [ ' '.repeat( left ), s, ' '.repeat( right) ].join('');
Expand All @@ -38,7 +40,7 @@ class Column
this.minWidth = null;
this.maxWidth = null;
this.sortOrder = 1;
this.padDirection = 1; // left-justify
this.padDirection = TextPadDirection.RIGHT;

this.width = null;
}
Expand All @@ -63,19 +65,19 @@ class Column

setAlignLeft()
{
this.padDirection = 1;
this.padDirection = TextPadDirection.RIGHT;
return this;
}

setAlignCenter()
{
this.padDirection = 0;
this.padDirection = TextPadDirection.CENTER;
return this;
}

setAlignRight()
{
this.padDirection = -1;
this.padDirection = TextPadDirection.LEFT;
return this;
}

Expand Down
4 changes: 1 addition & 3 deletions regional_standings/model/team.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class Team {
}
});

opponentMap.forEach( ( lastWinTime, opp ) => {
opponentMap.forEach( ( lastWinTime ) => {
team.distinctTeamsDefeated += context.getTimestampModifier( lastWinTime );
} );

Expand Down Expand Up @@ -168,7 +168,6 @@ class Team {
} );

// Phase 3 looks at each team's opponents and rates each team highly if it can regularly win against other prestigous teams.

teams.forEach( team => {
// Bounties (and your opponents' networks) are 'buckets' that fill up as you win matches.
// Bounties/Networks are scaled by the stakes (i.e., prize pool) of the event where they occur and the age of the result
Expand All @@ -195,7 +194,6 @@ class Team {
} );

// Finally, build modifiers from calculated values

teams.forEach( team => {
team.modifiers.bountyCollected = curveFunction( team.opponentWinnings );
team.modifiers.bountyOffered = curveFunction( team.winnings );
Expand Down
Loading