precompute more data in workerUpdateServerData.loadTribes
This commit is contained in:
parent
674f1fe63c
commit
e9248b1f71
|
@ -99,18 +99,6 @@ type searchableByID interface {
|
|||
len() int
|
||||
}
|
||||
|
||||
func makePlayersSearchable(players []*models.Player) searchableByID {
|
||||
return playersSearchableByID{
|
||||
players: players,
|
||||
}
|
||||
}
|
||||
|
||||
func makeTribesSearchable(tribes []*models.Tribe) searchableByID {
|
||||
return tribesSearchableByID{
|
||||
tribes: tribes,
|
||||
}
|
||||
}
|
||||
|
||||
func searchByID(haystack searchableByID, id int) int {
|
||||
low := 0
|
||||
high := haystack.len() - 1
|
||||
|
|
|
@ -107,13 +107,13 @@ func (w *workerUpdateServerData) loadPlayers(od map[int]*models.OpponentsDefeate
|
|||
result.ids[index] = player.ID
|
||||
}
|
||||
|
||||
searchableNewPlayers := &playersSearchableByID{result.players}
|
||||
searchablePlayers := &playersSearchableByID{result.players}
|
||||
if err := w.db.
|
||||
Model(&models.Player{}).
|
||||
Column("id").
|
||||
Where("exists = true").
|
||||
ForEach(func(player *models.Player) error {
|
||||
if index := searchByID(searchableNewPlayers, player.ID); index < 0 {
|
||||
if index := searchByID(searchablePlayers, player.ID); index < 0 {
|
||||
result.deletedPlayers = append(result.deletedPlayers, player.ID)
|
||||
}
|
||||
return nil
|
||||
|
@ -124,12 +124,24 @@ func (w *workerUpdateServerData) loadPlayers(od map[int]*models.OpponentsDefeate
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (w *workerUpdateServerData) loadTribes(od map[int]*models.OpponentsDefeated, numberOfVillages int) ([]*models.Tribe, error) {
|
||||
tribes, err := w.dataloader.LoadTribes()
|
||||
type loadTribesResult struct {
|
||||
ids []int
|
||||
tribes []*models.Tribe
|
||||
deletedTribes []int
|
||||
numberOfTribes int
|
||||
}
|
||||
|
||||
func (w *workerUpdateServerData) loadTribes(od map[int]*models.OpponentsDefeated, numberOfVillages int) (loadTribesResult, error) {
|
||||
var err error
|
||||
result := loadTribesResult{}
|
||||
result.tribes, err = w.dataloader.LoadTribes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return result, errors.Wrap(err, "workerUpdateServerData.loadTribes")
|
||||
}
|
||||
for _, tribe := range tribes {
|
||||
|
||||
result.numberOfTribes = len(result.tribes)
|
||||
result.ids = make([]int, result.numberOfTribes)
|
||||
for index, tribe := range result.tribes {
|
||||
tribeOD, ok := od[tribe.ID]
|
||||
if ok {
|
||||
tribe.OpponentsDefeated = *tribeOD
|
||||
|
@ -139,8 +151,24 @@ func (w *workerUpdateServerData) loadTribes(od map[int]*models.OpponentsDefeated
|
|||
} else {
|
||||
tribe.Dominance = 0
|
||||
}
|
||||
result.ids[index] = tribe.ID
|
||||
}
|
||||
return tribes, nil
|
||||
|
||||
searchableTribes := &tribesSearchableByID{result.tribes}
|
||||
if err := w.db.
|
||||
Model(&models.Tribe{}).
|
||||
Column("id").
|
||||
Where("exists = true").
|
||||
ForEach(func(tribe *models.Tribe) error {
|
||||
if index := searchByID(searchableTribes, tribe.ID); index < 0 {
|
||||
result.deletedTribes = append(result.deletedTribes, tribe.ID)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return result, errors.Wrap(err, "workerUpdateServerData.loadTribes: Tribes that have been deleted couldn't be detected")
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (w *workerUpdateServerData) calculateODifference(od1 models.OpponentsDefeated, od2 models.OpponentsDefeated) models.OpponentsDefeated {
|
||||
|
@ -161,7 +189,7 @@ func (w *workerUpdateServerData) calculateTodaysTribeStats(
|
|||
history []*models.TribeHistory,
|
||||
) []*models.DailyTribeStats {
|
||||
var todaysStats []*models.DailyTribeStats
|
||||
searchableTribes := makeTribesSearchable(tribes)
|
||||
searchableTribes := &tribesSearchableByID{tribes}
|
||||
|
||||
for _, historyRecord := range history {
|
||||
if index := searchByID(searchableTribes, historyRecord.TribeID); index != -1 {
|
||||
|
@ -183,10 +211,12 @@ func (w *workerUpdateServerData) calculateTodaysTribeStats(
|
|||
return todaysStats
|
||||
}
|
||||
|
||||
func (w *workerUpdateServerData) calculateDailyPlayerStats(players []*models.Player,
|
||||
history []*models.PlayerHistory) []*models.DailyPlayerStats {
|
||||
func (w *workerUpdateServerData) calculateDailyPlayerStats(
|
||||
players []*models.Player,
|
||||
history []*models.PlayerHistory,
|
||||
) []*models.DailyPlayerStats {
|
||||
var todaysStats []*models.DailyPlayerStats
|
||||
searchablePlayers := makePlayersSearchable(players)
|
||||
searchablePlayers := &playersSearchableByID{players}
|
||||
|
||||
for _, historyRecord := range history {
|
||||
if index := searchByID(searchablePlayers, historyRecord.PlayerID); index != -1 {
|
||||
|
@ -222,11 +252,10 @@ func (w *workerUpdateServerData) update() error {
|
|||
}
|
||||
numberOfVillages := len(villages)
|
||||
|
||||
tribes, err := w.loadTribes(tod, countPlayerVillages(villages))
|
||||
tribesResult, err := w.loadTribes(tod, countPlayerVillages(villages))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "workerUpdateServerData.update")
|
||||
}
|
||||
numberOfTribes := len(tribes)
|
||||
|
||||
playersResult, err := w.loadPlayers(pod)
|
||||
if err != nil {
|
||||
|
@ -249,13 +278,19 @@ func (w *workerUpdateServerData) update() error {
|
|||
}
|
||||
|
||||
return w.db.RunInTransaction(context.Background(), func(tx *pg.Tx) error {
|
||||
if len(tribes) > 0 {
|
||||
ids := make([]int, len(tribes))
|
||||
for index, tribe := range tribes {
|
||||
ids[index] = tribe.ID
|
||||
if len(tribesResult.deletedTribes) > 0 {
|
||||
if _, err := tx.Model(&models.Tribe{}).
|
||||
Where("tribe.id = ANY (?)", pg.Array(tribesResult.deletedTribes)).
|
||||
Set("exists = false").
|
||||
Set("deleted_at = now()").
|
||||
Set("dominance = 0").
|
||||
Update(); err != nil && err != pg.ErrNoRows {
|
||||
return errors.Wrap(err, "couldn't update non-existent tribes")
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := tx.Model(&tribes).
|
||||
if tribesResult.numberOfTribes > 0 {
|
||||
if _, err := tx.Model(&tribesResult.tribes).
|
||||
OnConflict("(id) DO UPDATE").
|
||||
Set("name = EXCLUDED.name").
|
||||
Set("tag = EXCLUDED.tag").
|
||||
|
@ -271,14 +306,6 @@ func (w *workerUpdateServerData) update() error {
|
|||
Insert(); err != nil {
|
||||
return errors.Wrap(err, "couldn't insert tribes")
|
||||
}
|
||||
if _, err := tx.Model(&tribes).
|
||||
Where("NOT (tribe.id = ANY (?))", pg.Array(ids)).
|
||||
Set("exists = false").
|
||||
Set("deleted_at = now()").
|
||||
Set("dominance = 0").
|
||||
Update(); err != nil && err != pg.ErrNoRows {
|
||||
return errors.Wrap(err, "couldn't update non-existent tribes")
|
||||
}
|
||||
|
||||
var tribesHistory []*models.TribeHistory
|
||||
if err := tx.
|
||||
|
@ -291,7 +318,7 @@ func (w *workerUpdateServerData) update() error {
|
|||
Select(); err != nil && err != pg.ErrNoRows {
|
||||
return errors.Wrap(err, "couldn't select tribe history records")
|
||||
}
|
||||
todaysTribeStats := w.calculateTodaysTribeStats(tribes, tribesHistory)
|
||||
todaysTribeStats := w.calculateTodaysTribeStats(tribesResult.tribes, tribesHistory)
|
||||
if len(todaysTribeStats) > 0 {
|
||||
if _, err := tx.
|
||||
Model(&todaysTribeStats).
|
||||
|
@ -385,7 +412,7 @@ func (w *workerUpdateServerData) update() error {
|
|||
Set("building_config = ?", buildingCfg).
|
||||
Set("config = ?", cfg).
|
||||
Set("number_of_players = ?", playersResult.numberOfPlayers).
|
||||
Set("number_of_tribes = ?", numberOfTribes).
|
||||
Set("number_of_tribes = ?", tribesResult.numberOfTribes).
|
||||
Set("number_of_villages = ?", numberOfVillages).
|
||||
Returning("*").
|
||||
WherePK().
|
||||
|
|
Reference in New Issue