优化领地缓存更新加载策略,提高效率

This commit is contained in:
zhangyuheng 2024-06-21 15:49:40 +08:00
parent 723ac794fe
commit 17870432fe
5 changed files with 71 additions and 50 deletions

View File

@ -31,11 +31,14 @@ public class Cache {
/** /**
* 从数据库加载所有领地 * 从数据库加载所有领地
* 如果idToLoad为null则加载所有领地
*
* @param idToLoad 领地ID
*/ */
public void loadDominions() { public void loadDominions(Integer idToLoad) {
if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) { if (_last_update_dominion.get() + UPDATE_INTERVAL < System.currentTimeMillis()) {
XLogger.debug("run loadDominionsExecution directly"); XLogger.debug("run loadDominionsExecution directly");
loadDominionsExecution(); loadDominionsExecution(idToLoad);
} else { } else {
if (_update_dominion_is_scheduled.get()) return; if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution"); XLogger.debug("schedule loadDominionsExecution");
@ -43,20 +46,27 @@ public class Cache {
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L; long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> { Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadDominionsExecution scheduled"); XLogger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution(); loadDominionsExecution(idToLoad);
_update_dominion_is_scheduled.set(false); _update_dominion_is_scheduled.set(false);
}, },
delay_tick); delay_tick);
} }
} }
private void loadDominionsExecution() { public void loadDominions() {
loadDominions(null);
}
private void loadDominionsExecution(Integer idToLoad) {
Scheduler.runTaskAsync(() -> { Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
int count = 0;
if (idToLoad == null) {
id_dominions = new ConcurrentHashMap<>(); id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>(); world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>(); dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll(); List<DominionDTO> dominions = DominionDTO.selectAll();
count = dominions.size();
Map<String, List<DominionDTO>> world_dominions = new HashMap<>(); Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO d : dominions) { for (DominionDTO d : dominions) {
if (!world_dominions.containsKey(d.getWorld())) { if (!world_dominions.containsKey(d.getWorld())) {
@ -72,11 +82,20 @@ public class Cache {
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions.entrySet()) { for (Map.Entry<String, List<DominionDTO>> entry : world_dominions.entrySet()) {
world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue())); world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
} }
} else {
DominionDTO dominion = DominionDTO.select(idToLoad);
if (dominion == null && id_dominions.containsKey(idToLoad)) {
id_dominions.remove(idToLoad);
} else if (dominion != null) {
id_dominions.put(idToLoad, dominion);
count = 1;
}
}
BlueMapConnect.render(); BlueMapConnect.render();
recheckPlayerState = true; recheckPlayerState = true;
_last_update_dominion.set(System.currentTimeMillis()); _last_update_dominion.set(System.currentTimeMillis());
XLogger.debug("loadDominionsExecution cost: %d ms for %d dominions" XLogger.debug("loadDominionsExecution cost: %d ms for %d dominions"
, System.currentTimeMillis() - start, dominions.size()); , System.currentTimeMillis() - start, count);
}); });
} }
@ -266,7 +285,7 @@ public class Cache {
if (player == null) return dominionTree; if (player == null) return dominionTree;
for (List<DominionNode> tree : world_dominion_tree.values()) { for (List<DominionNode> tree : world_dominion_tree.values()) {
for (DominionNode node : tree) { for (DominionNode node : tree) {
if (node.dominion.getOwner().equals(player.getUuid())) { if (node.getDominion().getOwner().equals(player.getUuid())) {
dominionTree.add(node); dominionTree.add(node);
} }
} }

View File

@ -8,8 +8,16 @@ import javax.annotation.Nullable;
import java.util.*; import java.util.*;
public class DominionNode { public class DominionNode {
public DominionDTO dominion; private Integer dominion_id;
public List<DominionNode> children = new ArrayList<>(); private List<DominionNode> children = new ArrayList<>();
public DominionDTO getDominion() {
return Cache.instance.getDominion(dominion_id);
}
public List<DominionNode> getChildren() {
return children;
}
public static List<DominionNode> BuildNodeTree(Integer rootId, List<DominionDTO> dominions) { public static List<DominionNode> BuildNodeTree(Integer rootId, List<DominionDTO> dominions) {
// 映射父节点ID到其子节点列表 // 映射父节点ID到其子节点列表
@ -31,7 +39,7 @@ public class DominionNode {
if (children != null) { if (children != null) {
for (DominionDTO dominion : children) { for (DominionDTO dominion : children) {
DominionNode node = new DominionNode(); DominionNode node = new DominionNode();
node.dominion = dominion; node.dominion_id = dominion.getId();
node.children = buildTree(dominion.getId(), parentToChildrenMap); node.children = buildTree(dominion.getId(), parentToChildrenMap);
dominionTree.add(node); dominionTree.add(node);
} }
@ -42,7 +50,7 @@ public class DominionNode {
public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) { public static DominionNode getLocInDominionNode(@NotNull List<DominionNode> nodes, @NotNull Location loc) {
for (DominionNode node : nodes) { for (DominionNode node : nodes) {
if (isInDominion(node.dominion, loc)) { if (isInDominion(node.getDominion(), loc)) {
if (node.children.isEmpty()) { if (node.children.isEmpty()) {
return node; return node;
} else { } else {
@ -62,7 +70,7 @@ public class DominionNode {
if (nodes == null) return null; if (nodes == null) return null;
if (nodes.isEmpty()) return null; if (nodes.isEmpty()) return null;
DominionNode dominionNode = getLocInDominionNode(nodes, loc); DominionNode dominionNode = getLocInDominionNode(nodes, loc);
return dominionNode == null ? null : dominionNode.dominion; return dominionNode == null ? null : dominionNode.getDominion();
} }
public static boolean isInDominion(@Nullable DominionDTO dominion, Location location) { public static boolean isInDominion(@Nullable DominionDTO dominion, Location location) {

View File

@ -19,10 +19,6 @@ public class DominionDTO {
private static List<DominionDTO> query(String sql, Object... args) { private static List<DominionDTO> query(String sql, Object... args) {
List<DominionDTO> dominions = new ArrayList<>(); List<DominionDTO> dominions = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, args)) { try (ResultSet rs = DatabaseManager.instance.query(sql, args)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadDominions();
}
return getDTOFromRS(rs); return getDTOFromRS(rs);
} catch (SQLException e) { } catch (SQLException e) {
DatabaseManager.handleDatabaseError("数据库操作失败: ", e, sql); DatabaseManager.handleDatabaseError("数据库操作失败: ", e, sql);
@ -145,6 +141,7 @@ public class DominionDTO {
public static void delete(DominionDTO dominion) { public static void delete(DominionDTO dominion) {
String sql = "DELETE FROM dominion WHERE id = ?;"; String sql = "DELETE FROM dominion WHERE id = ?;";
query(sql, dominion.getId()); query(sql, dominion.getId());
Cache.instance.loadDominions();
} }
private DominionDTO(Integer id, UUID owner, String name, String world, private DominionDTO(Integer id, UUID owner, String name, String world,
@ -228,7 +225,7 @@ public class DominionDTO {
try (ResultSet rs = updateRow.execute()) { try (ResultSet rs = updateRow.execute()) {
List<DominionDTO> dominions = getDTOFromRS(rs); List<DominionDTO> dominions = getDTOFromRS(rs);
if (dominions.size() == 0) return null; if (dominions.size() == 0) return null;
Cache.instance.loadDominions(); Cache.instance.loadDominions((Integer) id.value);
return dominions.get(0); return dominions.get(0);
} catch (SQLException e) { } catch (SQLException e) {
DatabaseManager.handleDatabaseError("更新领地信息失败: ", e, updateRow.toString()); DatabaseManager.handleDatabaseError("更新领地信息失败: ", e, updateRow.toString());

View File

@ -12,6 +12,16 @@ import java.util.*;
public class PlayerPrivilegeDTO { public class PlayerPrivilegeDTO {
private static List<PlayerPrivilegeDTO> query(String sql, Object... params) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
return getDTOFromRS(rs);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询玩家权限失败: ", e, sql);
}
return players;
}
private static List<PlayerPrivilegeDTO> getDTOFromRS(ResultSet rs) { private static List<PlayerPrivilegeDTO> getDTOFromRS(ResultSet rs) {
List<PlayerPrivilegeDTO> players = new ArrayList<>(); List<PlayerPrivilegeDTO> players = new ArrayList<>();
if (rs == null) return players; if (rs == null) return players;
@ -90,6 +100,7 @@ public class PlayerPrivilegeDTO {
public static void delete(UUID player, Integer domID) { public static void delete(UUID player, Integer domID) {
String sql = "DELETE FROM player_privilege WHERE player_uuid = ? AND dom_id = ?;"; String sql = "DELETE FROM player_privilege WHERE player_uuid = ? AND dom_id = ?;";
query(sql, player.toString(), domID); query(sql, player.toString(), domID);
Cache.instance.loadPlayerPrivileges(player);
} }
public static List<PlayerPrivilegeDTO> selectAll() { public static List<PlayerPrivilegeDTO> selectAll() {
@ -172,18 +183,4 @@ public class PlayerPrivilegeDTO {
} }
} }
private static List<PlayerPrivilegeDTO> query(String sql, Object... params) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
try (ResultSet rs = DatabaseManager.instance.query(sql, params)) {
if (sql.contains("UPDATE") || sql.contains("DELETE") || sql.contains("INSERT")) {
// 如果是更新操作重新加载缓存
Cache.instance.loadPlayerPrivileges();
}
return getDTOFromRS(rs);
} catch (Exception e) {
DatabaseManager.handleDatabaseError("查询玩家权限失败: ", e, sql);
}
return players;
}
} }

View File

@ -47,11 +47,11 @@ public class ListDominion {
prefix.append(" | "); prefix.append(" | ");
} }
for (DominionNode node : dominionTree) { for (DominionNode node : dominionTree) {
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.dominion.getName()).build(); TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.getDominion().getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.dominion.getName()).build(); TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.getDominion().getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.dominion.getName()); Line line = Line.create().append(delete).append(manage).append(prefix + node.getDominion().getName());
lines.add(line); lines.add(line);
lines.addAll(BuildTreeLines(node.children, depth + 1)); lines.addAll(BuildTreeLines(node.getChildren(), depth + 1));
} }
return lines; return lines;
} }