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

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()) {
XLogger.debug("run loadDominionsExecution directly");
loadDominionsExecution();
loadDominionsExecution(idToLoad);
} else {
if (_update_dominion_is_scheduled.get()) return;
XLogger.debug("schedule loadDominionsExecution");
@ -43,40 +46,56 @@ public class Cache {
long delay_tick = (UPDATE_INTERVAL - (System.currentTimeMillis() - _last_update_dominion.get())) / 1000 * 20L;
Scheduler.runTaskLaterAsync(() -> {
XLogger.debug("run loadDominionsExecution scheduled");
loadDominionsExecution();
loadDominionsExecution(idToLoad);
_update_dominion_is_scheduled.set(false);
},
delay_tick);
}
}
private void loadDominionsExecution() {
public void loadDominions() {
loadDominions(null);
}
private void loadDominionsExecution(Integer idToLoad) {
Scheduler.runTaskAsync(() -> {
long start = System.currentTimeMillis();
id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO d : dominions) {
if (!world_dominions.containsKey(d.getWorld())) {
world_dominions.put(d.getWorld(), new ArrayList<>());
int count = 0;
if (idToLoad == null) {
id_dominions = new ConcurrentHashMap<>();
world_dominion_tree = new ConcurrentHashMap<>();
dominion_children = new ConcurrentHashMap<>();
List<DominionDTO> dominions = DominionDTO.selectAll();
count = dominions.size();
Map<String, List<DominionDTO>> world_dominions = new HashMap<>();
for (DominionDTO d : dominions) {
if (!world_dominions.containsKey(d.getWorld())) {
world_dominions.put(d.getWorld(), new ArrayList<>());
}
world_dominions.get(d.getWorld()).add(d);
id_dominions.put(d.getId(), d);
if (!dominion_children.containsKey(d.getParentDomId())) {
dominion_children.put(d.getParentDomId(), new ArrayList<>());
}
dominion_children.get(d.getParentDomId()).add(d.getId());
}
world_dominions.get(d.getWorld()).add(d);
id_dominions.put(d.getId(), d);
if (!dominion_children.containsKey(d.getParentDomId())) {
dominion_children.put(d.getParentDomId(), new ArrayList<>());
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions.entrySet()) {
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;
}
dominion_children.get(d.getParentDomId()).add(d.getId());
}
for (Map.Entry<String, List<DominionDTO>> entry : world_dominions.entrySet()) {
world_dominion_tree.put(entry.getKey(), DominionNode.BuildNodeTree(-1, entry.getValue()));
}
BlueMapConnect.render();
recheckPlayerState = true;
_last_update_dominion.set(System.currentTimeMillis());
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;
for (List<DominionNode> tree : world_dominion_tree.values()) {
for (DominionNode node : tree) {
if (node.dominion.getOwner().equals(player.getUuid())) {
if (node.getDominion().getOwner().equals(player.getUuid())) {
dominionTree.add(node);
}
}

View File

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

View File

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

View File

@ -12,6 +12,16 @@ import java.util.*;
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) {
List<PlayerPrivilegeDTO> players = new ArrayList<>();
if (rs == null) return players;
@ -90,6 +100,7 @@ public class PlayerPrivilegeDTO {
public static void delete(UUID player, Integer domID) {
String sql = "DELETE FROM player_privilege WHERE player_uuid = ? AND dom_id = ?;";
query(sql, player.toString(), domID);
Cache.instance.loadPlayerPrivileges(player);
}
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(" | ");
}
for (DominionNode node : dominionTree) {
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.dominion.getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.dominion.getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.dominion.getName());
TextComponent manage = Button.createGreen("管理").setExecuteCommand("/dominion manage " + node.getDominion().getName()).build();
TextComponent delete = Button.createRed("删除").setExecuteCommand("/dominion delete " + node.getDominion().getName()).build();
Line line = Line.create().append(delete).append(manage).append(prefix + node.getDominion().getName());
lines.add(line);
lines.addAll(BuildTreeLines(node.children, depth + 1));
lines.addAll(BuildTreeLines(node.getChildren(), depth + 1));
}
return lines;
}