Skip to content

Commit

Permalink
Database code optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
WatchAndyTW committed Apr 21, 2024
1 parent 31b5307 commit 676302c
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 102 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ tmp/
/languages
/proto
/lua
lib/kcp-1.5.1.jar

/*.jar
/*.sh
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/main/java/emu/grasscutter/Grasscutter.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ public static void main(String[] args) throws Exception {

/** Server shutdown event. */
private static void onShutdown() {
// Save all data.
Database.saveAll();

// Disable all plugins.
if (pluginManager != null) pluginManager.disablePlugins();
// Shutdown the game server.
Expand Down
86 changes: 86 additions & 0 deletions src/main/java/emu/grasscutter/database/Database.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package emu.grasscutter.database;

import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.utils.objects.DatabaseObject;
import org.slf4j.*;

import java.util.*;
import java.util.concurrent.*;

/**
* Complicated manager of the MongoDB database.
* Handles caching, data operations, and more.
*/
public interface Database {
Logger logger = LoggerFactory.getLogger("Database");
List<DatabaseObject<?>> objects = new CopyOnWriteArrayList<>();

/**
* Queues an object to be saved.
*
* @param object The object to save.
*/
static void save(DatabaseObject<?> object) {
if (object.saveImmediately()) {
object.save();
} else {
objects.add(object);
}
}

/**
* Performs a bulk save of all deferred objects.
*/
static void saveAll() {
var size = objects.size();
Database.saveAll(objects);

logger.debug("Performed auto save on {} objects.", size);
}

/**
* Performs a bulk save of all deferred objects.
*
* @param objects The objects to save.
*/
static void saveAll(List<? extends DatabaseObject<?>> objects) {
// Sort all objects into their respective databases.
var gameObjects = objects.stream()
.filter(DatabaseObject::isGameObject)
.toList();
var accountObjects = objects.stream()
.filter(o -> !o.isGameObject())
.toList();

// Clear the collective list.
objects.clear();

// Save all objects.
var executor = DatabaseHelper.getEventExecutor();
if (Grasscutter.getRunMode() != Grasscutter.ServerRunMode.DISPATCH_ONLY) {
executor.submit(() -> {
DatabaseManager.getGameDatastore().save(gameObjects);
});
}
if (Grasscutter.getRunMode() != Grasscutter.ServerRunMode.GAME_ONLY) {
executor.submit(() -> {
DatabaseManager.getAccountDatastore().save(accountObjects);
});
}
}

/**
* Starts the auto-save thread.
* Runs every 10s 1000为1秒.
*/
static void startSaveThread() {
var timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Database.saveAll();
}
}, 0, 1000 * 10);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
import emu.grasscutter.server.packet.send.PacketActivityUpdateWatcherNotify;
import emu.grasscutter.utils.JsonUtils;
import java.util.*;

import emu.grasscutter.utils.objects.DatabaseObject;
import lombok.*;
import lombok.experimental.FieldDefaults;

@Entity("activities")
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Builder(builderMethodName = "of")
public class PlayerActivityData {
public class PlayerActivityData implements DatabaseObject<PlayerActivityData> {
@Id String id;
int uid;
int activityId;
Expand All @@ -34,8 +36,25 @@ public static PlayerActivityData getByPlayer(Player player, int activityId) {
return DatabaseHelper.getPlayerActivityData(player.getUid(), activityId);
}

/**
* Saves this object to the database.
* As of Grasscutter 1.7.1, this is by default a {@link DatabaseObject#deferSave()} call.
*/
public void save() {
DatabaseHelper.savePlayerActivityData(this);
this.deferSave();
}

/**
* Saves this object to the database.
*
* @param immediate If true, this will be a {@link DatabaseObject#save()} call instead of a {@link DatabaseObject#deferSave()} call.
*/
public void save(boolean immediate) {
if (immediate) {
DatabaseObject.super.save();
} else {
this.save();
}
}

public synchronized void addWatcherProgress(int watcherId) {
Expand Down
22 changes: 20 additions & 2 deletions src/main/java/emu/grasscutter/game/avatar/Avatar.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import emu.grasscutter.net.proto.TrialAvatarInfoOuterClass.TrialAvatarInfo;
import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.helpers.ProtoHelper;
import emu.grasscutter.utils.objects.DatabaseObject;
import it.unimi.dsi.fastutil.ints.*;
import java.util.*;
import java.util.stream.Stream;
Expand All @@ -39,7 +40,7 @@
import org.bson.types.ObjectId;

@Entity(value = "avatars", useDiscriminator = false)
public class Avatar {
public class Avatar implements DatabaseObject<Avatar> {
@Transient @Getter private final Int2ObjectMap<GameItem> equips;
@Transient @Getter private final Int2FloatOpenHashMap fightProperties;
@Transient @Getter private final Int2FloatOpenHashMap fightPropOverrides;
Expand Down Expand Up @@ -989,8 +990,25 @@ public int getEntityId() {
return entity != null ? entity.getId() : 0;
}

/**
* Saves this object to the database.
* As of Grasscutter 1.7.1, this is by default a {@link DatabaseObject#deferSave()} call.
*/
public void save() {
DatabaseHelper.saveAvatar(this);
this.deferSave();
}

/**
* Saves this object to the database.
*
* @param immediate If true, this will be a {@link DatabaseObject#save()} call instead of a {@link DatabaseObject#deferSave()} call.
*/
public void save(boolean immediate) {
if (immediate) {
DatabaseObject.super.save();
} else {
this.save();
}
}

public AvatarInfo toProto() {
Expand Down
Loading

0 comments on commit 676302c

Please sign in to comment.