优化领地缓存更新加载策略,提高效率
This commit is contained in:
parent
723ac794fe
commit
17870432fe
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user