Added option clipboard on disk

This commit is contained in:
Jesse Boyd 2016-04-25 06:59:25 +10:00
parent 912ea44cc8
commit 362490938c
3 changed files with 127 additions and 10 deletions

View File

@ -21,6 +21,8 @@ public class Settings {
public static long MEM_FREE = 95;
public static boolean ENABLE_HARD_LIMIT = true;
public static boolean STORE_HISTORY_ON_DISK = false;
public static boolean STORE_CLIPBOARD_ON_DISK = false;
public static int DELETE_HISTORY_AFTER_DAYS = 7;
public static int COMPRESSION_LEVEL = 0;
public static int BUFFER_SIZE = 531441;
@ -83,6 +85,7 @@ public class Settings {
options.put("crash-mitigation", ENABLE_HARD_LIMIT);
options.put("lighting.fix-all", FIX_ALL_LIGHTING);
options.put("lighting.async", ASYNC_LIGHTING);
options.put("clipboard.use-disk", STORE_CLIPBOARD_ON_DISK);
options.put("history.use-disk", STORE_HISTORY_ON_DISK);
options.put("history.compress", false);
options.put("history.chunk-wait-ms", CHUNK_WAIT);
@ -132,7 +135,7 @@ public class Settings {
QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms");
ALLOWED_3RDPARTY_EXTENTS = config.getStringList("extent.allowed-plugins");
EXTENT_DEBUG = config.getBoolean("extent.debug");
STORE_CLIPBOARD_ON_DISK = config.getBoolean("clipboard.use-disk");
if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) {
LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE;

View File

@ -1,54 +1,166 @@
package com.boydti.fawe.object.clipboard;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.IntegerTrio;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
/**
* // TODO
* A clipboard with disk backed storage. (lower memory + loads on crash)
* - Uses an auto closable RandomAccessFile for getting / setting id / data
* - I don't know how to reduce nbt / entities to O(1) complexity, so it is stored in memory.
*
* TODO load on join
*/
public class DiskOptimizedClipboard extends FaweClipboard {
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
private final HashSet<ClipboardEntity> entities;
private final File file;
private final byte[] buffer;
public DiskOptimizedClipboard(int width, int height, int length) {
private volatile RandomAccessFile raf;
private long lastAccessed;
private int last;
public DiskOptimizedClipboard(int width, int height, int length, File file) {
super(width, height, length);
nbtMap = new HashMap<>();
entities = new HashSet<ClipboardEntity>();
entities = new HashSet<>();
this.file = file;
this.buffer = new byte[2];
this.lastAccessed = System.currentTimeMillis();
try {
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public DiskOptimizedClipboard(int width, int height, int length) {
this(width, height, length, new File(Fawe.imp().getDirectory(), "clipboard" + File.separator + UUID.randomUUID()));
}
public void open() throws IOException {
this.raf = new RandomAccessFile(file, "rw");
long size = width * height * length * 2l;
if (raf.length() != size) {
raf.setLength(size);
}
TaskManager.IMP.laterAsync(new Runnable() {
@Override
public void run() {
if (raf != null && System.currentTimeMillis() - lastAccessed > 10000) {
try {
RandomAccessFile tmp = raf;
raf = null;
tmp.close();
} catch (IOException e) {
e.printStackTrace();
}
} else if (raf == null) {
return;
} else {
TaskManager.IMP.laterAsync(this, 200);
}
}
}, 200);
}
@Override
public BaseBlock getBlock(int x, int y, int z) {
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
try {
if (raf == null) {
open();
}
lastAccessed = System.currentTimeMillis();
int i = x + z * width + y * area;
if (i != last + 1) {
raf.seek(i << 1);
}
raf.read(buffer);
last = i;
int id = ((buffer[1] << 4) + (buffer[0] >> 4));
BaseBlock block;
if (!FaweCache.hasData(id)) {
block = FaweCache.CACHE_BLOCK[id << 4];
} else {
block = FaweCache.CACHE_BLOCK[(id << 4) + (buffer[0] & 0xf)];
}
if (FaweCache.hasNBT(id)) {
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
if (nbt != null) {
block = new BaseBlock(block.getId(), block.getData());
block.setNbtData(nbt);
}
}
return block;
} catch (Exception e) {
e.printStackTrace();
}
return EditSession.nullBlock;
}
@Override
public boolean setBlock(int x, int y, int z, BaseBlock block) {
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
try {
if (raf == null) {
open();
}
lastAccessed = System.currentTimeMillis();
int i = x + z * width + y * area;
if (i != last + 1) {
raf.seek(i << 1);
}
final int id = block.getId();
final int data = block.getData();
int combined = (id << 4) + data;
buffer[0] = (byte) ((combined) & 0xff);
buffer[1] = (byte) (((combined) >> 8) & 0xff);
raf.write(buffer);
if (FaweCache.hasNBT(id)) {
nbtMap.put(new IntegerTrio(x, y, z), block.getNbtData());
}
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
@Override
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity);
entities.add(ret);
return ret;
}
@Override
public List<? extends Entity> getEntities() {
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
return new ArrayList<>(entities);
}
@Override
public boolean remove(ClipboardEntity clipboardEntity) {
throw new UnsupportedOperationException("NOT IMPLEMENTED / WIP");
return entities.remove(clipboardEntity);
}
}

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.extent.clipboard;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
import com.boydti.fawe.object.clipboard.FaweClipboard;
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
import com.sk89q.worldedit.EditSession;
@ -73,7 +75,7 @@ public class BlockArrayClipboard implements Clipboard {
checkNotNull(region);
this.region = region.clone();
this.size = getDimensions();
this.IMP = new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
this.IMP = Settings.STORE_CLIPBOARD_ON_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
this.origin = region.getMinimumPoint();
this.mx = origin.getBlockX();
this.my = origin.getBlockY();