*Kinda* working now. Async the updateCache to io thread, and fix stream close issue
This commit is contained in:
@@ -22,12 +22,8 @@ public class ColumnRenderLoader extends RenderSourceLoader {
|
||||
|
||||
@Override
|
||||
public LodRenderSource loadRender(RenderMetaFile dataFile, InputStream data, ILevel level) throws IOException {
|
||||
try (
|
||||
//TODO: Add decompressor here
|
||||
DataInputStream dis = new DataInputStream(data);
|
||||
) {
|
||||
return new ColumnRenderSource(dataFile.pos, dis, dataFile.metaData.loaderVersion, level);
|
||||
}
|
||||
DataInputStream dis = new DataInputStream(data); // DO NOT CLOSE
|
||||
return new ColumnRenderSource(dataFile.pos, dis, dataFile.metaData.loaderVersion, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -369,9 +369,8 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
|
||||
@Override
|
||||
public void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException {
|
||||
try (DataOutputStream dos = new DataOutputStream(dataStream)) {
|
||||
writeData(dos);
|
||||
}
|
||||
DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE
|
||||
writeData(dos);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,11 +16,7 @@ public class FullDataLoader extends DataSourceLoader {
|
||||
|
||||
@Override
|
||||
public LodDataSource loadData(DataMetaFile dataFile, InputStream data, ILevel level) throws IOException {
|
||||
try (
|
||||
//TODO: Add decompressor here
|
||||
DataInputStream dis = new DataInputStream(data);
|
||||
) {
|
||||
return FullDataSource.loadData(dataFile, dis, level);
|
||||
}
|
||||
//TODO: Add decompressor here
|
||||
return FullDataSource.loadData(dataFile, data, level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.seibel.lod.core.a7.save.io.file.DataMetaFile;
|
||||
import com.seibel.lod.core.a7.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.a7.util.IdMappingUtil;
|
||||
import com.seibel.lod.core.a7.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.a7.util.UnclosableInputStream;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.objects.DHChunkPos;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
@@ -102,7 +103,8 @@ public class FullDataSource extends FullArrayView implements LodDataSource { //
|
||||
|
||||
@Override
|
||||
public void saveData(ILevel level, DataMetaFile file, OutputStream dataStream) throws IOException {
|
||||
try (DataOutputStream dos = new DataOutputStream(dataStream)) {
|
||||
DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE
|
||||
{
|
||||
dos.writeInt(getDataDetail());
|
||||
dos.writeInt(size);
|
||||
dos.writeInt(level.getMinY());
|
||||
@@ -138,7 +140,8 @@ public class FullDataSource extends FullArrayView implements LodDataSource { //
|
||||
|
||||
|
||||
public static FullDataSource loadData(DataMetaFile dataFile, InputStream dataStream, ILevel level) throws IOException {
|
||||
try (DataInputStream dos = new DataInputStream(dataStream)) {
|
||||
DataInputStream dos = new DataInputStream(dataStream); // DO NOT CLOSE
|
||||
{
|
||||
int dataDetail = dos.readInt();
|
||||
if(dataDetail != dataFile.metaData.dataLevel)
|
||||
throw new IOException(LodUtil.formatLog("Data level mismatch: {} != {}", dataDetail, dataFile.metaData.dataLevel));
|
||||
@@ -175,7 +178,7 @@ public class FullDataSource extends FullArrayView implements LodDataSource { //
|
||||
// Id mapping
|
||||
end = dos.readInt();
|
||||
if (end != 0xFFFFFFFF) throw new IOException("invalid data content end guard");
|
||||
IdBiomeBlockStateMap mapping = IdBiomeBlockStateMap.deserialize(dos);
|
||||
IdBiomeBlockStateMap mapping = IdBiomeBlockStateMap.deserialize(new UnclosableInputStream(dos));
|
||||
end = dos.readInt();
|
||||
if (end != 0xFFFFFFFF) throw new IOException("invalid id mapping end guard");
|
||||
return new FullDataSource(dataFile.pos, mapping, data);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.seibel.lod.core.a7.datatype.full;
|
||||
|
||||
import com.seibel.lod.core.a7.util.UnclosableInputStream;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
@@ -77,28 +78,21 @@ public class IdBiomeBlockStateMap {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
void serialize(OutputStream os) {
|
||||
try (DataOutputStream dos = new DataOutputStream(os)) {
|
||||
dos.writeInt(entries.size());
|
||||
for (Entry e : entries) {
|
||||
dos.writeUTF(e.serialize());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
void serialize(OutputStream os) throws IOException {
|
||||
DataOutputStream dos = new DataOutputStream(os); // DO NOT CLOSE!
|
||||
dos.writeInt(entries.size());
|
||||
for (Entry e : entries) {
|
||||
dos.writeUTF(e.serialize());
|
||||
}
|
||||
}
|
||||
static IdBiomeBlockStateMap deserialize(InputStream is) {
|
||||
try (DataInputStream dis = new DataInputStream(is)) {
|
||||
int size = dis.readInt();
|
||||
IdBiomeBlockStateMap map = new IdBiomeBlockStateMap();
|
||||
for (int i = 0; i < size; i++) {
|
||||
map.entries.add(Entry.deserialize(dis.readUTF()));
|
||||
}
|
||||
return map;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
static IdBiomeBlockStateMap deserialize(InputStream is) throws IOException {
|
||||
DataInputStream dis = new DataInputStream(is); // DO NOT CLOSE!
|
||||
int size = dis.readInt();
|
||||
IdBiomeBlockStateMap map = new IdBiomeBlockStateMap();
|
||||
for (int i = 0; i < size; i++) {
|
||||
map.entries.add(Entry.deserialize(dis.readUTF()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,11 +16,6 @@ public class SparseDataLoader extends DataSourceLoader {
|
||||
|
||||
@Override
|
||||
public LodDataSource loadData(DataMetaFile dataFile, InputStream data, ILevel level) throws IOException {
|
||||
try (
|
||||
//TODO: Add decompressor here
|
||||
DataInputStream dis = new DataInputStream(data);
|
||||
) {
|
||||
return SparseDataSource.loadData(dataFile, dis, level);
|
||||
}
|
||||
return SparseDataSource.loadData(dataFile, data, level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.seibel.lod.core.a7.level.ILevel;
|
||||
import com.seibel.lod.core.a7.pos.DhLodPos;
|
||||
import com.seibel.lod.core.a7.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.a7.save.io.file.DataMetaFile;
|
||||
import com.seibel.lod.core.a7.util.UnclosableInputStream;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -205,7 +206,8 @@ public class SparseDataSource implements LodDataSource {
|
||||
public static SparseDataSource loadData(DataMetaFile dataFile, InputStream dataStream, ILevel level) throws IOException {
|
||||
LodUtil.assertTrue(dataFile.pos.sectionDetail > SPARSE_UNIT_DETAIL);
|
||||
LodUtil.assertTrue(dataFile.pos.sectionDetail <= MAX_SECTION_DETAIL);
|
||||
try (DataInputStream dos = new DataInputStream(dataStream)) {
|
||||
DataInputStream dos = new DataInputStream(dataStream); // DO NOT CLOSE!
|
||||
{
|
||||
int dataDetail = dos.readShort();
|
||||
if(dataDetail != dataFile.metaData.dataLevel)
|
||||
throw new IOException(LodUtil.formatLog("Data level mismatch: {} != {}", dataDetail, dataFile.metaData.dataLevel));
|
||||
|
||||
@@ -301,10 +301,12 @@ public class DataFileHandler implements IDataSourceProvider {
|
||||
return source;
|
||||
}
|
||||
@Override
|
||||
public LodDataSource onDataFileRefresh(LodDataSource source, Consumer<LodDataSource> updater) {
|
||||
updater.accept(source);
|
||||
if (source instanceof SparseDataSource) return ((SparseDataSource) source).trySelfPromote();
|
||||
return source;
|
||||
public CompletableFuture<LodDataSource> onDataFileRefresh(LodDataSource source, Consumer<LodDataSource> updater) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
updater.accept(source);
|
||||
if (source instanceof SparseDataSource) return ((SparseDataSource) source).trySelfPromote();
|
||||
return source;
|
||||
}, fileReaderThread);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -230,16 +230,20 @@ public class DataMetaFile extends MetaFile
|
||||
// For now, I'll go for the latter option and just hope nothing goes wrong...
|
||||
if (inCacheWriteAccessAsserter.getAndSet(true) == false) {
|
||||
try {
|
||||
inner = handler.onDataFileRefresh((LodDataSource) inner, this::applyWriteQueue);
|
||||
return handler.onDataFileRefresh((LodDataSource) inner, this::applyWriteQueue);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error while applying changes to LodDataSource at {}: ", pos, e);
|
||||
} finally {
|
||||
inCacheWriteAccessAsserter.set(false);
|
||||
}
|
||||
} else {
|
||||
// or, return the cached data. FIXME: See above.
|
||||
return CompletableFuture.completedFuture((LodDataSource) inner);
|
||||
}
|
||||
} else {
|
||||
// or, return the cached data.
|
||||
return CompletableFuture.completedFuture((LodDataSource) inner);
|
||||
}
|
||||
// Finally, return the cached data.
|
||||
return CompletableFuture.completedFuture((LodDataSource)inner);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
@@ -26,7 +27,7 @@ public interface IDataSourceProvider extends AutoCloseable {
|
||||
|
||||
CompletableFuture<LodDataSource> onCreateDataFile(DataMetaFile file);
|
||||
LodDataSource onDataFileLoaded(LodDataSource source, Consumer<LodDataSource> updater);
|
||||
LodDataSource onDataFileRefresh(LodDataSource source, Consumer<LodDataSource> updater);
|
||||
CompletableFuture<LodDataSource> onDataFileRefresh(LodDataSource source, Consumer<LodDataSource> updater);
|
||||
File computeDataFilePath(DhSectionPos pos);
|
||||
Executor getIOExecutor();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user