WorldEdit in transaction. (Better WE Performance with BlockState)

A special cookie for LordSaad, yummi.
This commit is contained in:
Jascha Starke 2013-11-08 11:57:36 +01:00
parent aba6bf354d
commit 8c9be4f1f4
7 changed files with 258 additions and 23 deletions

View file

@ -87,8 +87,10 @@ public class BlockStateConfig extends Configuration implements IConfigurationSub
* BlockStateThreading
*
* Uses Threading to minimize lag. This fully relies on Bukkit metadata implementation. You only should need this,
* if there are often plays more then 10 players at once on your server. Be aware that this requires more memory,
* to increase the performance
* if there are often plays more then 10 players at once on your server, or you're about to use huge WorldEdits often.
* Be aware that this requires more memory, to increase the performance
*
* Without threading, huge WorldEdits becomes much noticeable slower.
*
* default: false
*/

View file

@ -133,7 +133,7 @@ public class DBQueries {
"WHERE x = ? AND y = ? AND z = ? AND world = ? ");
}
if (s.getGameMode() == null)
update.setNull(5, Types.INTEGER);
update.setNull(1, Types.INTEGER);
else if (db.getType() == Type.MySQL)
update.setString(1, s.getGameMode().name());
else

View file

@ -18,7 +18,7 @@ import de.jaschastarke.minecraft.limitedcreative.blockstate.DBQueries;
import de.jaschastarke.minecraft.limitedcreative.blockstate.ThreadedModel;
public class ThreadLink {
private static final int BATCH_ACTION_LENGTH = 10;
private static final int BATCH_ACTION_LENGTH = 25;
private static final int QUEUE_ACCESS_WARNING_DURATION = 5; // ms
private static final int COUNT_WARNING_QUEUE = 5;
private static final int COUNT_ERROR_QUEUE = 20;
@ -83,8 +83,11 @@ public class ThreadLink {
acts.add(updateQueue.pop());
}
}
if (getModule().isDebug())
long t = 0;
if (getModule().isDebug()) {
t = System.currentTimeMillis();
log.debug("DB-Thread '" + Thread.currentThread().getName() + "' run: " + acts.size());
}
for (Action act : acts) {
if (!shutdown || !(act instanceof CacheChunkAction)) {
if (act instanceof CallableAction) {
@ -97,6 +100,8 @@ public class ThreadLink {
}
}
}
if (getModule().isDebug())
log.debug("DB-Thread '" + Thread.currentThread().getName() + "' execution time: " + (System.currentTimeMillis() - t) + "ms");
} catch (InterruptedException e) {
e.printStackTrace();
log.severe("DB-Thread '" + Thread.currentThread().getName() + "' was harmfull interupted");

View file

@ -3,9 +3,14 @@ package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.regions.Region;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
public class LCEditSession extends EditSession {
private LCEditSessionFactory factory;
@ -23,11 +28,70 @@ public class LCEditSession extends EditSession {
this.player = player;
}
private DBTransaction transaction;
@Override
public void flushQueue() {
transaction = factory.getModel().groupUpdate();
super.flushQueue();
if (transaction != null) {
transaction.finish();
transaction = null;
}
}
@Override
public int setBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
boolean useTransaction = false;
if (transaction == null) {
transaction = factory.getModel().groupUpdate();
useTransaction = true;
}
int ret;
try {
ret = super.setBlocks(region, block);
} catch (MaxChangedBlocksException e) {
transaction = null;
throw e;
}
if (transaction != null && useTransaction) {
transaction.finish();
transaction = null;
}
return ret;
}
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
boolean useTransaction = false;
if (transaction == null) {
transaction = factory.getModel().groupUpdate();
useTransaction = true;
}
int ret;
try {
ret = super.setBlocks(region, pattern);
} catch (MaxChangedBlocksException e) {
transaction = null;
throw e;
}
if (transaction != null && useTransaction) {
transaction.finish();
transaction = null;
}
return ret;
}
@Override
public boolean rawSetBlock(Vector pt, BaseBlock block) {
boolean success = super.rawSetBlock(pt, block);
if (success)
factory.onBlockEdit(player, pt, block);
if (success) {
if (transaction != null) {
factory.onTransactionBlockEdit(transaction, player, pt, block);
} else {
factory.onBlockEdit(player, pt, block);
}
}
return success;
}
}

View file

@ -18,6 +18,8 @@ import com.sk89q.worldedit.bukkit.BukkitWorld;
import de.jaschastarke.minecraft.limitedcreative.ModBlockStates;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState;
import de.jaschastarke.minecraft.limitedcreative.blockstate.BlockState.Source;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
public class LCEditSessionFactory extends EditSessionFactory {
private ModBlockStates mod;
@ -154,22 +156,57 @@ public class LCEditSessionFactory extends EditSessionFactory {
/*public void onBlockEdit(Vector pt, BaseBlock block) {
this.onBlockEdit(null, pt, block);
}*/
public DBModel getModel() {
return mod.getModel();
}
public boolean onBlockEdit(LocalPlayer player, Vector pt, BaseBlock block) {
if (player != null) {
Location loc = new Location(((BukkitWorld) player.getWorld()).getWorld(), pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
BlockState s = mod.getModel().getState(loc.getBlock());
if (s == null) {
s = new BlockState();
s.setLocation(loc);
}
s.setGameMode(null);
s.setPlayerName(player.getName());
s.setDate(new Date());
s.setSource(Source.EDIT);
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
if (block.getType() == 0) {
mod.getModel().removeState(loc.getBlock());
} else {
BlockState s = mod.getModel().getState(loc.getBlock());
if (s == null) {
s = new BlockState();
s.setLocation(loc);
}
s.setGameMode(null);
s.setPlayerName(player.getName());
s.setDate(new Date());
s.setSource(Source.EDIT);
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
mod.getModel().setState(s);
mod.getModel().setState(s);
}
return true;
} else {
return false;
}
}
public boolean onTransactionBlockEdit(DBTransaction transaction, LocalPlayer player, Vector pt, BaseBlock block) {
if (player != null) {
Location loc = new Location(((BukkitWorld) player.getWorld()).getWorld(), pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (block.getType() == 0) {
transaction.removeState(loc.getBlock());
} else {
BlockState s = mod.getModel().getState(loc.getBlock());
if (s == null) {
s = new BlockState();
s.setLocation(loc);
}
s.setGameMode(null);
s.setPlayerName(player.getName());
s.setDate(new Date());
s.setSource(Source.EDIT);
if (mod.isDebug())
mod.getLog().debug("Saving BlockState: " + s.toString());
transaction.setState(s);
}
return true;
} else {
return false;

View file

@ -5,9 +5,14 @@ import net.coreprotect.worldedit.CoreProtectEditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.regions.Region;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
public class LCEditSession_CoreProtect extends CoreProtectEditSession {
private LCEditSessionFactory factory;
@ -25,11 +30,70 @@ public class LCEditSession_CoreProtect extends CoreProtectEditSession {
this.player = player;
}
private DBTransaction transaction;
@Override
public void flushQueue() {
transaction = factory.getModel().groupUpdate();
super.flushQueue();
if (transaction != null) {
transaction.finish();
transaction = null;
}
}
@Override
public int setBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
boolean useTransaction = false;
if (transaction == null) {
transaction = factory.getModel().groupUpdate();
useTransaction = true;
}
int ret;
try {
ret = super.setBlocks(region, block);
} catch (MaxChangedBlocksException e) {
transaction = null;
throw e;
}
if (transaction != null && useTransaction) {
transaction.finish();
transaction = null;
}
return ret;
}
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
boolean useTransaction = false;
if (transaction == null) {
transaction = factory.getModel().groupUpdate();
useTransaction = true;
}
int ret;
try {
ret = super.setBlocks(region, pattern);
} catch (MaxChangedBlocksException e) {
transaction = null;
throw e;
}
if (transaction != null && useTransaction) {
transaction.finish();
transaction = null;
}
return ret;
}
@Override
public boolean rawSetBlock(Vector pt, BaseBlock block) {
boolean success = super.rawSetBlock(pt, block);
if (success)
factory.onBlockEdit(player, pt, block);
if (success) {
if (transaction != null) {
factory.onTransactionBlockEdit(transaction, player, pt, block);
} else {
factory.onBlockEdit(player, pt, block);
}
}
return success;
}
}

View file

@ -2,12 +2,16 @@ package de.jaschastarke.minecraft.limitedcreative.blockstate.worldedit;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.regions.Region;
import de.diddiz.LogBlock.LogBlock;
import de.diddiz.worldedit.LogBlockEditSession;
import de.jaschastarke.minecraft.limitedcreative.blockstate.DBModel.DBTransaction;
public class LCEditSession_LogBlock extends LogBlockEditSession {
private LCEditSessionFactory factory;
@ -25,11 +29,70 @@ public class LCEditSession_LogBlock extends LogBlockEditSession {
this.player = player;
}
private DBTransaction transaction;
@Override
public void flushQueue() {
transaction = factory.getModel().groupUpdate();
super.flushQueue();
if (transaction != null) {
transaction.finish();
transaction = null;
}
}
@Override
public int setBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
boolean useTransaction = false;
if (transaction == null) {
transaction = factory.getModel().groupUpdate();
useTransaction = true;
}
int ret;
try {
ret = super.setBlocks(region, block);
} catch (MaxChangedBlocksException e) {
transaction = null;
throw e;
}
if (transaction != null && useTransaction) {
transaction.finish();
transaction = null;
}
return ret;
}
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
boolean useTransaction = false;
if (transaction == null) {
transaction = factory.getModel().groupUpdate();
useTransaction = true;
}
int ret;
try {
ret = super.setBlocks(region, pattern);
} catch (MaxChangedBlocksException e) {
transaction = null;
throw e;
}
if (transaction != null && useTransaction) {
transaction.finish();
transaction = null;
}
return ret;
}
@Override
public boolean rawSetBlock(Vector pt, BaseBlock block) {
boolean success = super.rawSetBlock(pt, block);
if (success)
factory.onBlockEdit(player, pt, block);
if (success) {
if (transaction != null) {
factory.onTransactionBlockEdit(transaction, player, pt, block);
} else {
factory.onBlockEdit(player, pt, block);
}
}
return success;
}
}