Skip to content

Commit

Permalink
Optimize processMultiGuesses() speed
Browse files Browse the repository at this point in the history
  • Loading branch information
tzhf committed Feb 23, 2024
1 parent cba7ea4 commit 4b10b7d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 68 deletions.
10 changes: 7 additions & 3 deletions assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,18 @@
.gm-ui-hover-effect {
display: none !important;
}
.gm-style-iw-tc::after {
top: -4px !important;
}

.gm-style .gm-style-iw-c,
.gm-style .gm-style-iw-tc::after {
background: rgba(0, 0, 0, 0.5) !important;
}
.gm-style .gm-style-iw-c {
padding: 8px 10px !important;
}

.gm-style .gm-style-iw-d {
overflow: auto !important;
padding: 0 !important;
color: #ffffff;
text-align: center;
font-weight: 700;
Expand Down
77 changes: 38 additions & 39 deletions src/Classes/Game.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,7 @@ class Game {
await pMap(
guesses,
async (guess) => {
const correct = guess.country === this.#country;

this.#db.setGuessStreak(guess.id, correct ? guess.streak + 1 : 0, correct ? null : guess.streak);
if (correct) {
if (guess.country === this.#country) {
this.#db.addUserStreak(guess.userId, this.#roundId);
} else {
this.#db.resetUserStreak(guess.userId);
Expand All @@ -202,12 +199,12 @@ class Game {
const dbUser = this.#db.getOrCreateUser("BROADCASTER", this.#settings.channelName);

const guessedCountry = await GameHelper.getCountryCode(location);
/** @type {number|null} */
let lastStreak = null;
if (guessedCountry === this.#country) {
const lastStreak = this.#db.getUserStreak(dbUser.id);
const correct = guessedCountry === this.#country;
if (correct) {
this.#db.addUserStreak(dbUser.id, this.#roundId);
} else {
lastStreak = this.#db.resetUserStreak(dbUser.id);
this.#db.resetUserStreak(dbUser.id);
}

const distance = GameHelper.haversineDistance(location, this.location);
Expand All @@ -221,7 +218,7 @@ class Game {
location,
country: guessedCountry,
streak: streak?.count ?? 0,
lastStreak,
lastStreak: lastStreak?.count && !correct ? lastStreak.count : null,
distance,
score,
});
Expand All @@ -244,14 +241,17 @@ class Game {
throw Object.assign(new Error("Same guess"), { code: "submittedPreviousGuess" });
}

userstate.color = userstate.color || "#FFF";
const distance = GameHelper.haversineDistance(location, this.location);
const score = GameHelper.calculateScore(distance, this.mapScale);

/** @type {string | null} */
const guessedCountry = await GameHelper.getCountryCode(location);
let streak = this.#db.getUserStreak(dbUser.id);
/** @type {number | null} */
let lastStreak = null;
const correct = guessedCountry === this.#country;
const lastStreak = this.#db.getUserStreak(dbUser.id);

// Reset streak if the player skipped a round
if (streak && this.lastLocation && !latLngEqual(streak.lastLocation, this.lastLocation)) {
if (lastStreak && this.lastLocation && !latLngEqual(lastStreak.lastLocation, this.lastLocation)) {
this.#db.resetUserStreak(dbUser.id);
}

Expand All @@ -261,41 +261,40 @@ class Game {
if (guessedCountry === this.#country) {
this.#db.addUserStreak(dbUser.id, this.#roundId);
} else {
lastStreak = this.#db.resetUserStreak(dbUser.id);
this.#db.resetUserStreak(dbUser.id);
}
}

streak = this.#db.getUserStreak(dbUser.id);
const distance = GameHelper.haversineDistance(location, this.location);
const score = GameHelper.calculateScore(distance, this.mapScale);
/** @type {{ id?: string, count: number, location?: string } | undefined} */
let streak = this.#db.getUserStreak(dbUser.id);

userstate.color = userstate.color || "#FFF";
// With this we no longer need to update guess streak in processMultiGuesses() which was slow
if (this.isMultiGuess) {
if (correct) {
streak ? streak.count++ : (streak = { count: 1 });
} else {
streak = null;
}
}

const guess = {
color: userstate.color,
flag: dbUser.flag,
location,
country: guessedCountry,
streak: streak?.count ?? 0,
lastStreak: lastStreak?.count && !correct ? lastStreak.count : null,
distance,
score,
};

// Modify guess or push it
let modified = false;
if (this.isMultiGuess && existingGuess) {
this.#db.updateGuess(existingGuess.id, {
color: userstate.color,
flag: dbUser.flag,
location,
country: guessedCountry,
streak: streak?.count ?? 0,
lastStreak,
distance,
score,
});
this.#db.updateGuess(existingGuess.id, guess);
modified = true;
} else {
this.#db.createGuess(this.#roundId, dbUser.id, {
color: userstate.color,
flag: dbUser.flag,
location,
country: guessedCountry,
streak: streak?.count ?? 0,
lastStreak,
distance,
score,
});
this.#db.createGuess(this.#roundId, dbUser.id, guess);
}

// TODO save previous guess? No, fetch previous guess from the DB
Expand All @@ -309,7 +308,7 @@ class Game {
flag: dbUser.flag,
position: location,
streak: streak?.count ?? 0,
lastStreak,
lastStreak: lastStreak?.count && !correct ? lastStreak.count : null,
distance,
score,
modified,
Expand Down
53 changes: 27 additions & 26 deletions src/utils/Database.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,25 +392,25 @@ class Database {
});
}

/**
*
* @param {string} guessId
* @param {number} streak
* @param {number|null} [lastStreak]
*/
setGuessStreak(guessId, streak, lastStreak = null) {
const updateGuess = this.#db.prepare(`
UPDATE guesses
SET streak = :streak, last_streak = :lastStreak
WHERE id = :id
`);

updateGuess.run({
id: guessId,
streak,
lastStreak,
});
}
// /**
// *
// * @param {string} guessId
// * @param {number} streak
// * @param {number|null} [lastStreak]
// */
// setGuessStreak(guessId, streak, lastStreak = null) {
// const updateGuess = this.#db.prepare(`
// UPDATE guesses
// SET streak = :streak, last_streak = :lastStreak
// WHERE id = :id
// `);

// updateGuess.run({
// id: guessId,
// streak,
// lastStreak,
// });
// }

/**
*
Expand Down Expand Up @@ -485,15 +485,16 @@ class Database {

/**
* @param {string} userId
* @returns {number|null} Previous streak, if any.
*/
resetUserStreak(userId) {
const tx = this.#db.transaction(() => {
const streak = this.getUserStreak(userId);
this.#db.prepare("UPDATE users SET current_streak_id = NULL WHERE id = ?").run(userId);
return streak;
});
return tx()?.count ?? null;
// In handleUserGuess() we need to get lastLocation from the previous streak in order to reset the streak if the player skipped a round
// so we don't need to return last streak from here anymore, it also saves a query in processMultiGuesses() when streak is reseted
// const tx = this.#db.transaction(() => {
// const streak = this.getUserStreak(userId);
this.#db.prepare("UPDATE users SET current_streak_id = NULL WHERE id = ?").run(userId);
// return streak;
// });
// return tx()?.count ?? null;
}

/**
Expand Down

0 comments on commit 4b10b7d

Please sign in to comment.