RiftRegistry partial parallelization of serialization
This commit is contained in:
parent
b45632b466
commit
a2704a165a
2 changed files with 60 additions and 49 deletions
|
@ -40,7 +40,7 @@ public class SchematicGenerator extends LazyPocketGenerator{
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private Identifier templateID;
|
private Identifier templateID;
|
||||||
BlockPlacementType placementType = BlockPlacementType.SECTION_NO_UPDATE;
|
private BlockPlacementType placementType = BlockPlacementType.SECTION_NO_UPDATE;
|
||||||
|
|
||||||
private final List<RiftBlockEntity> rifts = new ArrayList<>();
|
private final List<RiftBlockEntity> rifts = new ArrayList<>();
|
||||||
private BlockPos origin;
|
private BlockPos origin;
|
||||||
|
@ -84,7 +84,7 @@ public class SchematicGenerator extends LazyPocketGenerator{
|
||||||
int[] originInts = tag.getIntArray("origin");
|
int[] originInts = tag.getIntArray("origin");
|
||||||
this.origin = new BlockPos(originInts[0], originInts[1], originInts[2]);
|
this.origin = new BlockPos(originInts[0], originInts[1], originInts[2]);
|
||||||
}
|
}
|
||||||
if (tag.contains("placement_type")) placementType = BlockPlacementType.getFromId(tag.getString("placement_type"));
|
if (tag.contains("placement_type", NbtType.STRING)) placementType = BlockPlacementType.getFromId(tag.getString("placement_type"));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package org.dimdev.dimdoors.rift.registry;
|
package org.dimdev.dimdoors.rift.registry;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.util.NbtType;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dimdev.dimdoors.util.GraphUtils;
|
import org.dimdev.dimdoors.util.GraphUtils;
|
||||||
|
@ -37,30 +35,31 @@ public class RiftRegistry {
|
||||||
protected Map<UUID, PlayerRiftPointer> lastPrivatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
|
protected Map<UUID, PlayerRiftPointer> lastPrivatePocketExits = new HashMap<>(); // Player UUID -> last rift used to enter pocket
|
||||||
protected Map<UUID, PlayerRiftPointer> overworldRifts = new HashMap<>(); // Player UUID -> rift used to exit the overworld
|
protected Map<UUID, PlayerRiftPointer> overworldRifts = new HashMap<>(); // Player UUID -> rift used to exit the overworld
|
||||||
|
|
||||||
// TODO: async
|
|
||||||
public static RiftRegistry fromTag(Map<RegistryKey<World>, PocketDirectory> pocketRegistry, CompoundTag nbt) {
|
public static RiftRegistry fromTag(Map<RegistryKey<World>, PocketDirectory> pocketRegistry, CompoundTag nbt) {
|
||||||
// Read rifts in this dimension
|
// Read rifts in this dimension
|
||||||
|
|
||||||
RiftRegistry riftRegistry = new RiftRegistry();
|
RiftRegistry riftRegistry = new RiftRegistry();
|
||||||
|
|
||||||
ListTag riftsNBT = (ListTag) nbt.get("rifts");
|
ListTag riftsNBT = nbt.getList("rifts", NbtType.COMPOUND);
|
||||||
for (Tag riftNBT : riftsNBT) {
|
CompletableFuture<List<Rift>> futureRifts = CompletableFuture.supplyAsync(() -> riftsNBT.parallelStream().unordered().map(CompoundTag.class::cast).map(Rift::fromTag).collect(Collectors.toList()));
|
||||||
Rift rift = Rift.fromTag((CompoundTag) riftNBT);
|
|
||||||
|
ListTag pocketsNBT = nbt.getList("pockets", NbtType.COMPOUND);
|
||||||
|
CompletableFuture<List<PocketEntrancePointer>> futurePockets = CompletableFuture.supplyAsync(() -> pocketsNBT.stream().map(CompoundTag.class::cast).map(PocketEntrancePointer::fromTag).collect(Collectors.toList()));
|
||||||
|
|
||||||
|
futureRifts.join().forEach(rift -> {
|
||||||
riftRegistry.graph.addVertex(rift);
|
riftRegistry.graph.addVertex(rift);
|
||||||
riftRegistry.uuidMap.put(rift.id, rift);
|
riftRegistry.uuidMap.put(rift.id, rift);
|
||||||
riftRegistry.locationMap.put(rift.location, rift);
|
riftRegistry.locationMap.put(rift.location, rift);
|
||||||
}
|
});
|
||||||
|
|
||||||
ListTag pocketsNBT = (ListTag) nbt.get("pockets");
|
futurePockets.join().forEach(pocket -> {
|
||||||
for (Tag pocketNBT : pocketsNBT) {
|
|
||||||
PocketEntrancePointer pocket = PocketEntrancePointer.fromTag((CompoundTag) pocketNBT);
|
|
||||||
riftRegistry.graph.addVertex(pocket);
|
riftRegistry.graph.addVertex(pocket);
|
||||||
riftRegistry.uuidMap.put(pocket.id, pocket);
|
riftRegistry.uuidMap.put(pocket.id, pocket);
|
||||||
riftRegistry.pocketEntranceMap.put(pocketRegistry.get(pocket.world).getPocket(pocket.pocketId), pocket);
|
riftRegistry.pocketEntranceMap.put(pocketRegistry.get(pocket.world).getPocket(pocket.pocketId), pocket);
|
||||||
}
|
});
|
||||||
|
|
||||||
// Read the connections between links that have a source or destination in this dimension
|
// Read the connections between links that have a source or destination in this dimension
|
||||||
ListTag linksNBT = (ListTag) nbt.get("links");
|
ListTag linksNBT = nbt.getList("links", NbtType.COMPOUND);
|
||||||
for (Tag linkNBT : linksNBT) {
|
for (Tag linkNBT : linksNBT) {
|
||||||
RegistryVertex from = riftRegistry.uuidMap.get(((CompoundTag) linkNBT).getUuid("from"));
|
RegistryVertex from = riftRegistry.uuidMap.get(((CompoundTag) linkNBT).getUuid("from"));
|
||||||
RegistryVertex to = riftRegistry.uuidMap.get(((CompoundTag) linkNBT).getUuid("to"));
|
RegistryVertex to = riftRegistry.uuidMap.get(((CompoundTag) linkNBT).getUuid("to"));
|
||||||
|
@ -70,51 +69,62 @@ public class RiftRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
riftRegistry.lastPrivatePocketEntrances = riftRegistry.readPlayerRiftPointers((ListTag) nbt.get("lastPrivatePocketEntrances"));
|
riftRegistry.lastPrivatePocketEntrances = riftRegistry.readPlayerRiftPointers(nbt.getList("last_private_pocket_entrances", NbtType.COMPOUND));
|
||||||
riftRegistry.lastPrivatePocketExits = riftRegistry.readPlayerRiftPointers((ListTag) nbt.get("lastPrivatePocketExits"));
|
riftRegistry.lastPrivatePocketExits = riftRegistry.readPlayerRiftPointers(nbt.getList("last_private_pocket_exits", NbtType.COMPOUND));
|
||||||
riftRegistry.overworldRifts = riftRegistry.readPlayerRiftPointers((ListTag) nbt.get("overworldRifts"));
|
riftRegistry.overworldRifts = riftRegistry.readPlayerRiftPointers(nbt.getList("overworld_rifts", NbtType.COMPOUND));
|
||||||
return riftRegistry;
|
return riftRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: async
|
|
||||||
public CompoundTag toTag() {
|
public CompoundTag toTag() {
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
// Write rifts in this dimension
|
// Write rifts in this dimension
|
||||||
ListTag riftsNBT = new ListTag();
|
CompletableFuture<Pair<ListTag, ListTag>> futureRiftsAndPocketsNBT = CompletableFuture.supplyAsync(() -> {
|
||||||
ListTag pocketsNBT = new ListTag();
|
Map<Boolean, List<RegistryVertex>> vertices = this.graph.vertexSet().parallelStream().unordered().filter(vertex -> vertex instanceof Rift || vertex instanceof PocketEntrancePointer)
|
||||||
for (RegistryVertex vertex : this.graph.vertexSet()) {
|
.collect(Collectors.partitioningBy(Rift.class::isInstance));
|
||||||
CompoundTag vertexNBT = RegistryVertex.toTag(vertex);
|
|
||||||
if (vertex instanceof Rift) {
|
CompletableFuture<List<CompoundTag>> futureRiftsNBT = CompletableFuture.supplyAsync(() -> vertices.get(true).parallelStream().map(RegistryVertex::toTag).collect(Collectors.toList()));
|
||||||
riftsNBT.add(vertexNBT);
|
CompletableFuture<List<CompoundTag>> futurePocketsNBT = CompletableFuture.supplyAsync(() -> vertices.get(false).parallelStream().map(RegistryVertex::toTag).collect(Collectors.toList()));
|
||||||
} else if (vertex instanceof PocketEntrancePointer) {
|
|
||||||
pocketsNBT.add(vertexNBT);
|
ListTag riftsNBT = new ListTag();
|
||||||
} else if (!(vertex instanceof PlayerRiftPointer)) {
|
ListTag pocketsNBT = new ListTag();
|
||||||
throw new RuntimeException("Unsupported registry vertex type " + vertex.getClass().getName());
|
|
||||||
}
|
riftsNBT.addAll(futureRiftsNBT.join());
|
||||||
}
|
pocketsNBT.addAll(futurePocketsNBT.join());
|
||||||
tag.put("rifts", riftsNBT);
|
|
||||||
tag.put("pockets", pocketsNBT);
|
return new Pair<>(riftsNBT, pocketsNBT);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Write the connections between links that have a source or destination in this dimension
|
// Write the connections between links that have a source or destination in this dimension
|
||||||
ListTag linksNBT = new ListTag();
|
CompletableFuture<ListTag> futureLinksNBT = CompletableFuture.supplyAsync(() -> {
|
||||||
for (DefaultEdge edge : this.graph.edgeSet()) {
|
ListTag linksNBT = new ListTag();
|
||||||
RegistryVertex from = this.graph.getEdgeSource(edge);
|
for (DefaultEdge edge : this.graph.edgeSet()) {
|
||||||
RegistryVertex to = this.graph.getEdgeTarget(edge);
|
RegistryVertex from = this.graph.getEdgeSource(edge);
|
||||||
CompoundTag linkNBT = new CompoundTag();
|
RegistryVertex to = this.graph.getEdgeTarget(edge);
|
||||||
linkNBT.putUuid("from", from.id);
|
CompoundTag linkNBT = new CompoundTag();
|
||||||
linkNBT.putUuid("to", to.id);
|
linkNBT.putUuid("from", from.id);
|
||||||
linksNBT.add(linkNBT);
|
linkNBT.putUuid("to", to.id);
|
||||||
}
|
linksNBT.add(linkNBT);
|
||||||
tag.put("links", linksNBT);
|
}
|
||||||
|
return linksNBT;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Subregistries are written automatically when the worlds are saved.
|
// Subregistries are written automatically when the worlds are saved.
|
||||||
tag.put("lastPrivatePocketEntrances", this.writePlayerRiftPointers(this.lastPrivatePocketEntrances));
|
tag.put("last_private_pocket_entrances", this.writePlayerRiftPointers(this.lastPrivatePocketEntrances));
|
||||||
tag.put("lastPrivatePocketExits", this.writePlayerRiftPointers(this.lastPrivatePocketExits));
|
tag.put("last_private_pocket_exits", this.writePlayerRiftPointers(this.lastPrivatePocketExits));
|
||||||
tag.put("overworldRifts", this.writePlayerRiftPointers(this.overworldRifts));
|
tag.put("overworld_rifts", this.writePlayerRiftPointers(this.overworldRifts));
|
||||||
|
|
||||||
|
Pair<ListTag, ListTag> riftsAndPocketsNBT = futureRiftsAndPocketsNBT.join();
|
||||||
|
tag.put("rifts", riftsAndPocketsNBT.getLeft());
|
||||||
|
tag.put("pockets", riftsAndPocketsNBT.getRight());
|
||||||
|
|
||||||
|
tag.put("links", futureLinksNBT.join());
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: parallelization
|
||||||
private Map<UUID, PlayerRiftPointer> readPlayerRiftPointers(ListTag tag) {
|
private Map<UUID, PlayerRiftPointer> readPlayerRiftPointers(ListTag tag) {
|
||||||
Map<UUID, PlayerRiftPointer> pointerMap = new HashMap<>();
|
Map<UUID, PlayerRiftPointer> pointerMap = new HashMap<>();
|
||||||
for (Tag entryNBT : tag) {
|
for (Tag entryNBT : tag) {
|
||||||
|
@ -129,6 +139,7 @@ public class RiftRegistry {
|
||||||
return pointerMap;
|
return pointerMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: parallelization
|
||||||
private ListTag writePlayerRiftPointers(Map<UUID, PlayerRiftPointer> playerRiftPointerMap) {
|
private ListTag writePlayerRiftPointers(Map<UUID, PlayerRiftPointer> playerRiftPointerMap) {
|
||||||
ListTag pointers = new ListTag();
|
ListTag pointers = new ListTag();
|
||||||
for (Map.Entry<UUID, PlayerRiftPointer> entry : playerRiftPointerMap.entrySet()) {
|
for (Map.Entry<UUID, PlayerRiftPointer> entry : playerRiftPointerMap.entrySet()) {
|
||||||
|
|
Loading…
Reference in a new issue