Skip to content

Commit

Permalink
Merge pull request #820 from StarWishsama/feature/795_add_clear_data_if
Browse files Browse the repository at this point in the history
添加清理世界数据接口
  • Loading branch information
StarWishsama authored Jan 16, 2024
2 parents 3b6147a + 21b8c38 commit 26d13ad
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ protected void scheduleReadTask(Runnable run) {
readExecutor.submit(run);
}

protected void scheduleWriteTask(Runnable run) {
checkDestroy();
writeExecutor.submit(run);
}

protected List<RecordSet> getData(RecordKey key) {
return getData(key, false);
}
Expand All @@ -180,6 +185,13 @@ protected void deleteData(RecordKey key) {
dataAdapter.deleteData(key);
}

protected void abortScopeTask(ScopeKey key) {
var task = scheduledWriteTasks.remove(key);
if (task != null) {
task.abort();
}
}

public final DataType getDataType() {
return dataType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,16 @@ void saveNewBlock(Location l, String sfId) {
public void removeBlock(Location l) {
checkDestroy();

Slimefun.getNetworkManager().updateAllNetworks(l);

var removed = getChunkDataCache(l.getChunk(), true).removeBlockData(l);
Slimefun.getNetworkManager().updateAllNetworks(l);
if (removed == null) {
return;
}

if (!removed.isDataLoaded()) {
return;
}

var menu = removed.getBlockMenu();
if (menu != null) {
InventoryUtil.closeInventory(menu.toInventory());
Expand Down Expand Up @@ -278,7 +281,7 @@ public void setBlockDataLocation(SlimefunBlockData blockData, Location target) {

var hasTicker = false;

if (Slimefun.getRegistry().getTickerBlocks().contains(blockData.getSfId())) {
if (blockData.isDataLoaded() && Slimefun.getRegistry().getTickerBlocks().contains(blockData.getSfId())) {
Slimefun.getTickerTask().disableTicker(blockData.getLocation());
hasTicker = true;
}
Expand Down Expand Up @@ -373,12 +376,7 @@ public void loadChunk(Chunk chunk, boolean isNewChunk) {
chunkData.addBlockCacheInternal(blockData, false);

if (sfItem.loadDataByDefault()) {
scheduleReadTask(() -> {
loadBlockData(blockData);
if (sfItem.isTicking()) {
Slimefun.getTickerTask().enableTicker(blockData.getLocation());
}
});
scheduleReadTask(() -> loadBlockData(blockData));
}
});
Bukkit.getPluginManager().callEvent(new SlimefunChunkDataLoadEvent(chunkData));
Expand Down Expand Up @@ -470,6 +468,11 @@ public void loadBlockData(SlimefunBlockData blockData) {
invSnapshots.put(blockData.getKey(), InvStorageUtils.getInvSnapshot(content));
}
}

var sfItem = SlimefunItem.getById(blockData.getSfId());
if (sfItem != null && sfItem.isTicking()) {
Slimefun.getTickerTask().enableTicker(blockData.getLocation());
}
} finally {
lock.unlock(key);
}
Expand Down Expand Up @@ -537,6 +540,60 @@ public Set<SlimefunChunkData> getAllLoadedChunkData() {
return new HashSet<>(loadedChunk.values());
}

public void removeAllDataInChunk(Chunk chunk) {
var cKey = LocationUtils.getChunkKey(chunk);
var cache = loadedChunk.remove(cKey);

if (cache != null && cache.isDataLoaded()) {
cache.getAllBlockData().forEach(this::clearBlockCacheAndTasks);
}
deleteChunkAndBlockDataDirectly(cKey);
}

public void removeAllDataInChunkAsync(Chunk chunk, Runnable onFinishedCallback) {
scheduleWriteTask(() -> {
removeAllDataInChunk(chunk);
onFinishedCallback.run();
});
}

public void removeAllDataInWorld(World world) {
// 1. remove block cache
var loadedBlockData = new HashSet<SlimefunBlockData>();
for (var chunkData : getAllLoadedChunkData(world)) {
loadedBlockData.addAll(chunkData.getAllBlockData());
chunkData.removeAllCacheInternal();
}

// 2. remove ticker and delayed tasks
loadedBlockData.forEach(this::clearBlockCacheAndTasks);

// 3. remove from database
var prefix = world.getName() + ";";
deleteChunkAndBlockDataDirectly(prefix + "%");

// 4. remove chunk cache
loadedChunk.entrySet().removeIf(entry -> entry.getKey().startsWith(prefix));
}

public void removeAllDataInWorldAsync(World world, Runnable onFinishedCallback) {
scheduleWriteTask(() -> {
removeAllDataInWorld(world);
onFinishedCallback.run();
});
}

public Set<SlimefunChunkData> getAllLoadedChunkData(World world) {
var prefix = world.getName() + ";";
var re = new HashSet<SlimefunChunkData>();
loadedChunk.forEach((k, v) -> {
if (k.startsWith(prefix)) {
re.add(v);
}
});
return re;
}

private void scheduleDelayedBlockInvUpdate(SlimefunBlockData blockData, int slot) {
var scopeKey = new LocationKey(DataScope.NONE, blockData.getLocation());
var reqKey = new RecordKey(DataScope.BLOCK_INVENTORY);
Expand Down Expand Up @@ -671,4 +728,26 @@ private SlimefunChunkData getChunkDataCache(Chunk chunk, boolean createOnNotExis
})
: loadedChunk.get(LocationUtils.getChunkKey(chunk));
}

private void deleteChunkAndBlockDataDirectly(String cKey) {
var req = new RecordKey(DataScope.BLOCK_DATA);
req.addCondition(FieldKey.CHUNK, cKey);
deleteData(req);

req = new RecordKey(DataScope.CHUNK_DATA);
req.addCondition(FieldKey.CHUNK, cKey);
deleteData(req);
}

private void clearBlockCacheAndTasks(SlimefunBlockData blockData) {
var l = blockData.getLocation();
if (blockData.isDataLoaded() && Slimefun.getRegistry().getTickerBlocks().contains(blockData.getSfId())) {
Slimefun.getTickerTask().disableTicker(l);
}
Slimefun.getNetworkManager().updateAllNetworks(l);

var scopeKey = new LocationKey(DataScope.NONE, l);
removeDelayedBlockDataUpdates(scopeKey);
abortScopeTask(scopeKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,16 @@ Set<SlimefunBlockData> getAllCacheInternal() {
return re;
}

void removeAllCacheInternal() {
sfBlocks.clear();
}

boolean hasBlockCache(String lKey) {
return sfBlocks.containsKey(lKey);
}

SlimefunBlockData removeBlockDataCacheInternal(String lKey) {
var re = sfBlocks.put(lKey, INVALID_BLOCK_DATA);
var re = isDataLoaded() ? sfBlocks.remove(lKey) : sfBlocks.put(lKey, INVALID_BLOCK_DATA);
return re == INVALID_BLOCK_DATA ? null : re;
}

Expand All @@ -120,4 +124,12 @@ public void removeData(String key) {
public Set<SlimefunBlockData> getAllBlockData() {
return getAllCacheInternal();
}

@Override
protected void setIsDataLoaded(boolean isDataLoaded) {
super.setIsDataLoaded(isDataLoaded);
if (isDataLoaded) {
sfBlocks.entrySet().removeIf(entry -> entry.getValue() == INVALID_BLOCK_DATA);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ public class QueuedWriteTask implements Runnable {
private final Queue<RecordKey> queue = new LinkedList<>();
private final Map<RecordKey, Runnable> tasks = new HashMap<>();
private volatile boolean done = false;
private volatile boolean aborted = false;

@Override
public final void run() {
if (aborted) {
return;
}

var task = next();
while (task != null) {
while (!aborted && task != null) {
try {
task.run();
} catch (Throwable e) {
Expand All @@ -35,7 +40,7 @@ protected void onSuccess() {}
protected void onError(Throwable e) {}

public synchronized boolean queue(RecordKey key, Runnable next) {
if (done) {
if (done || aborted) {
return false;
}

Expand All @@ -45,6 +50,10 @@ public synchronized boolean queue(RecordKey key, Runnable next) {
return true;
}

public void abort() {
aborted = true;
}

private synchronized Runnable next() {
var key = queue.poll();
if (key == null) {
Expand Down

0 comments on commit 26d13ad

Please sign in to comment.