From 3d97028b92b9bb5bde4580c41fb404f4ee8715d6 Mon Sep 17 00:00:00 2001 From: Kiana Sheibani Date: Fri, 13 Oct 2023 18:15:25 -0400 Subject: [PATCH] Add more configurable metadata to datasets --- src/datasets.rs | 58 +++++++++++++++++++++++--------- src/main.rs | 4 +++ src/queries/tournament_events.rs | 2 ++ src/sync.rs | 28 ++++++++++----- 4 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/datasets.rs b/src/datasets.rs index 61699ae..aaea58c 100644 --- a/src/datasets.rs +++ b/src/datasets.rs @@ -11,7 +11,12 @@ pub struct DatasetMetadata { pub game_id: VideogameId, pub game_name: String, + pub country: Option, pub state: Option, + + pub decay_rate: f64, + pub period: f64, + pub tau: f64, } /// Return the path to the datasets file. @@ -33,16 +38,19 @@ fn datasets_path(config_dir: &Path) -> io::Result { pub fn open_datasets(config_dir: &Path) -> sqlite::Result { let path = datasets_path(config_dir).unwrap(); - let query = " - PRAGMA foreign_keys = ON; + let query = "PRAGMA foreign_keys = ON; - CREATE TABLE IF NOT EXISTS datasets ( - name TEXT UNIQUE NOT NULL, - last_sync INTEGER NOT NULL, - game_id INTEGER NOT NULL, - game_name TEXT NOT NULL, - state TEXT - ) STRICT;"; +CREATE TABLE IF NOT EXISTS datasets ( + name TEXT UNIQUE NOT NULL, + last_sync INTEGER NOT NULL, + game_id INTEGER NOT NULL, + game_name TEXT NOT NULL, + country TEXT, + state TEXT, + decay_rate REAL NOT NULL, + period REAL NOT NULL, + tau REAL NOT NULL +) STRICT;"; let connection = sqlite::open(path)?; connection.execute(query)?; @@ -75,7 +83,11 @@ pub fn list_datasets(connection: &Connection) -> sqlite::Result("last_sync") as u64), game_id: VideogameId(r_.read::("game_id") as u64), game_name: r_.read::<&str, _>("game_name").to_owned(), + country: r_.read::, _>("country").map(String::from), state: r_.read::, _>("state").map(String::from), + decay_rate: r_.read::("decay_rate"), + period: r_.read::("period"), + tau: r_.read::("tau"), }, )) }) @@ -99,7 +111,7 @@ pub fn new_dataset( dataset: &str, metadata: DatasetMetadata, ) -> sqlite::Result<()> { - let query1 = r#"INSERT INTO datasets VALUES (?, ?, ?, ?, ?)"#; + let query1 = r#"INSERT INTO datasets VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"#; let query2 = format!( r#"CREATE TABLE "{0}_players" ( id INTEGER PRIMARY KEY, @@ -148,7 +160,11 @@ CREATE VIEW "{0}_view" .bind((2, metadata.last_sync.0 as i64))? .bind((3, metadata.game_id.0 as i64))? .bind((4, &metadata.game_name[..]))? - .bind((5, metadata.state.as_deref()))? + .bind((5, metadata.country.as_deref()))? + .bind((6, metadata.state.as_deref()))? + .bind((7, metadata.decay_rate))? + .bind((8, metadata.period))? + .bind((9, metadata.tau))? .try_for_each(|x| x.map(|_| ()))?; connection.execute(query2) @@ -158,7 +174,7 @@ pub fn get_metadata( connection: &Connection, dataset: &str, ) -> sqlite::Result> { - let query = "SELECT last_sync, game_id, game_name, state FROM datasets WHERE name = ?"; + let query = "SELECT * FROM datasets WHERE name = ?"; Ok(connection .prepare(query)? @@ -171,7 +187,11 @@ pub fn get_metadata( last_sync: Timestamp(r_.read::("last_sync") as u64), game_id: VideogameId(r_.read::("game_id") as u64), game_name: r_.read::<&str, _>("game_name").to_owned(), + country: r_.read::, _>("country").map(String::from), state: r_.read::, _>("state").map(String::from), + decay_rate: r_.read::("decay_rate"), + period: r_.read::("period"), + tau: r_.read::("tau"), }) }) .and_then(Result::ok)) @@ -395,6 +415,7 @@ pub fn is_isolated( pub fn hypothetical_advantage( connection: &Connection, dataset: &str, + decay_rate: f64, player1: PlayerId, player2: PlayerId, ) -> sqlite::Result { @@ -444,16 +465,17 @@ pub fn hypothetical_advantage( } let (final_adv, len) = final_path.unwrap(); - Ok(final_adv * 0.5_f64.powi(len as i32)) + Ok(final_adv * decay_rate.powi(len as i32)) } pub fn initialize_edge( connection: &Connection, dataset: &str, + decay_rate: f64, player1: PlayerId, player2: PlayerId, ) -> sqlite::Result { - let adv = hypothetical_advantage(connection, dataset, player1, player2)?; + let adv = hypothetical_advantage(connection, dataset, decay_rate, player1, player2)?; insert_advantage(connection, dataset, player1, player2, adv)?; Ok(adv) } @@ -489,7 +511,11 @@ pub mod tests { last_sync: Timestamp(1), game_id: VideogameId(0), game_name: String::from("Test Game"), + country: None, state: None, + decay_rate: 0.5, + period: (3600 * 24 * 30) as f64, + tau: 0.2, } } @@ -598,7 +624,7 @@ pub mod tests { for i in 1..=num_players { for j in 1..=num_players { assert_eq!( - hypothetical_advantage(&connection, "test", PlayerId(i), PlayerId(j))?, + hypothetical_advantage(&connection, "test", 0.5, PlayerId(i), PlayerId(j))?, 0.0 ); } @@ -616,7 +642,7 @@ pub mod tests { insert_advantage(&connection, "test", PlayerId(1), PlayerId(2), 1.0)?; assert_eq!( - hypothetical_advantage(&connection, "test", PlayerId(1), PlayerId(2))?, + hypothetical_advantage(&connection, "test", 0.5, PlayerId(1), PlayerId(2))?, 1.0 ); diff --git a/src/main.rs b/src/main.rs index 8a7a73a..d7ad4d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -193,7 +193,11 @@ fn dataset_new(name: Option, auth_token: Option) { last_sync: Timestamp(1), game_id, game_name, + country: None, state: None, + decay_rate: 0.5, + period: (3600 * 24 * 30) as f64, + tau: 0.2, }, ) .expect("Error communicating with SQLite"); diff --git a/src/queries/tournament_events.rs b/src/queries/tournament_events.rs index 0c61478..582c8eb 100644 --- a/src/queries/tournament_events.rs +++ b/src/queries/tournament_events.rs @@ -13,6 +13,7 @@ pub struct TournamentEventsVars<'a> { pub last_sync: Timestamp, pub game_id: VideogameId, + pub country: Option<&'a str>, pub state: Option<&'a str>, pub page: i32, } @@ -30,6 +31,7 @@ pub struct TournamentEvents { past: true, afterDate: $last_sync, videogameIds: [$game_id], + countryCode: $country, addrState: $state }})] tournaments: Option, diff --git a/src/sync.rs b/src/sync.rs index f9d5325..a90aaa6 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -39,10 +39,11 @@ fn glicko_adjust( other_deviation: f64, won: bool, time: u64, + metadata: &DatasetMetadata, ) -> (f64, f64, f64) { // TODO: Turn this into dataset metadata - let tau = 0.2; - let period = (3600 * 24 * 30) as f64; + let period = metadata.period; + let tau = metadata.tau; let g_val = 1.0 / (1.0 + 3.0 * other_deviation * other_deviation / PI / PI).sqrt(); let exp_val = 1.0 / (1.0 + f64::exp(-g_val * advantage)); @@ -122,6 +123,7 @@ fn get_tournament_events(metadata: &DatasetMetadata, auth: &str) -> Option Option Option sqlite::Result<()> { +fn update_from_set( + connection: &Connection, + dataset: &str, + metadata: &DatasetMetadata, + results: SetData, +) -> sqlite::Result<()> { let players_data = results.teams; add_players(connection, dataset, &players_data, results.time)?; @@ -193,7 +201,7 @@ fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> let (deviation2, volatility2, last_played2) = get_player_data(connection, dataset, player1)?; let advantage = match get_advantage(connection, dataset, player1, player2) { Err(e) => Err(e)?, - Ok(None) => initialize_edge(connection, dataset, player1, player2)?, + Ok(None) => initialize_edge(connection, dataset, metadata.decay_rate, player1, player2)?, Ok(Some(adv)) => adv, }; let (adjust1, dev_new1, vol_new1) = glicko_adjust( @@ -203,6 +211,7 @@ fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> deviation2, results.winner == 0, results.time.0 - last_played1.0, + metadata, ); let (adjust2, dev_new2, vol_new2) = glicko_adjust( advantage, @@ -211,6 +220,7 @@ fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> deviation1, results.winner == 1, results.time.0 - last_played2.0, + metadata, ); set_player_data( @@ -230,14 +240,15 @@ fn update_from_set(connection: &Connection, dataset: &str, results: SetData) -> vol_new2, )?; - adjust_advantages(connection, dataset, player1, 0.5 * adjust1)?; - adjust_advantages(connection, dataset, player2, 0.5 * adjust2)?; + let decay_rate = metadata.decay_rate; + adjust_advantages(connection, dataset, player1, decay_rate * adjust1)?; + adjust_advantages(connection, dataset, player2, decay_rate * adjust2)?; adjust_advantage( connection, dataset, player1, player2, - (1.0 - 0.5) * (adjust2 - adjust1), + (1.0 - decay_rate) * (adjust2 - adjust1), ) } @@ -265,7 +276,7 @@ pub fn sync_dataset( println!(" Updating ratings from event..."); sets.into_iter() - .try_for_each(|set| update_from_set(connection, dataset, set))?; + .try_for_each(|set| update_from_set(connection, dataset, &metadata, set))?; } connection.execute("COMMIT;") } @@ -285,6 +296,7 @@ mod tests { update_from_set( &connection, "test", + &metadata(), SetData { time: Timestamp(0), teams: players,