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

Optimize the fleet filter. #105

Open
github-actions bot opened this issue Jul 26, 2024 · 0 comments
Open

Optimize the fleet filter. #105

github-actions bot opened this issue Jul 26, 2024 · 0 comments
Assignees
Labels

Comments

@github-actions
Copy link

We are only interested in fleets that are at war with another fleet or system,

or fleets that are located in their owner's systems with shipyards for healing.

(The fleets are not the problem, but the potentially large amount of ships they contain.)

The first condition in SQL:

SELECT * FROM fleets as attacker, wars as war, fleets as defender WHERE attacker.owner = war.attacker AND defender.owner = war.defender

The second condition in SQL:

SELECT * FROM fleets as fleet, systems as system WHERE fleet.owner = system.owner AND 'building' IN system.buildings

https://github.com/sekassel-research/stp-24-server/blob/350e6943ecfdb4f476744cc44b3531495d8e0cc3/src/game-logic/game-logic.service.ts#L116

  async updateGame(game: Game) {
    const empires = await this.empireService.findAll({game: game._id});
    const systems = await this.systemService.findAll({game: game._id});
    const wars = await this.warService.findAll({game: game._id});
    // TODO Optimize the fleet filter.
    //  We are only interested in fleets that are at war with another fleet or system,
    //  or fleets that are located in their owner's systems with shipyards for healing.
    //  (The fleets are not the problem, but the potentially large amount of ships they contain.)
    // The first condition in SQL:
    //  SELECT * FROM fleets as attacker, wars as war, fleets as defender WHERE attacker.owner = war.attacker AND defender.owner = war.defender
    // The second condition in SQL:
    //  SELECT * FROM fleets as fleet, systems as system WHERE fleet.owner = system.owner AND 'building' IN system.buildings
    const fleets = await this.fleetService.findAll({game: game._id});
    const ships = await this.shipService.findAll({fleet: {$in: fleets.map(f => f._id)}});

    await this.jobService.deleteMany({game: game._id, $expr: {$gte: ['$progress', '$total']}});
    const jobs = await this.jobService.findAll({game: game._id}, {sort: {priority: 1, createdAt: 1}});
    await this.updateEmpires(empires, systems, jobs, ships);
    await this.updateFleets(empires, systems, fleets, ships, wars);

    await this.empireService.saveAll(empires);
    await this.systemService.saveAll(systems);
    await this.jobService.saveAll(jobs);
    await this.shipService.saveAll(ships);
    // We save all ships first to notify clients of 0HP with an updated event followed by the deleted event.
    await this.deleteDestroyedShipsAndFleets(fleets, ships);
    await this.deleteEmpiresWithoutSystems(empires, systems);
  }

  private async updateEmpires(empires: EmpireDocument[], systems: SystemDocument[], jobs: JobDocument[], ships: ShipDocument[]) {
    for (const empire of empires) {
      const empireSystems = systems.filter(system => system.owner?.equals(empire._id));
      const empireJobs = jobs.filter(job => job.empire.equals(empire._id));
      const empireShips = ships.filter(ship => ship.empire?.equals(empire._id));
      await this.jobService.updateJobs(empire, empireJobs, systems);
      this.updateEmpire(empire, empireSystems, empireShips);
    }
  }

  updateEmpire(empire: EmpireDocument, systems: SystemDocument[], ships: Ship[], aggregates?: Partial<Record<ResourceName, AggregateResult>>) {
    const variables = getInitialVariables();
    calculateVariables(variables, empire);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant