Skip to content

Commit 47a89ac

Browse files
committed
Fix graph-chunk node population
1 parent aa66b7d commit 47a89ac

3 files changed

Lines changed: 56 additions & 26 deletions

File tree

modules/core-xplat/src/main/java/com/kneelawk/graphlib/impl/graph/simple/SimpleBlockGraphChunk.java

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ private record SerialNode(long id, BlockNode node) {
8282
private final Short2ObjectMap<LongSet> graphsInPos = new Short2ObjectLinkedOpenHashMap<>();
8383
private final LongSet graphsInChunk = new LongLinkedOpenHashSet();
8484
private final Short2ObjectMap<Object2LongMap<BlockNode>> blockNodes = new Short2ObjectLinkedOpenHashMap<>();
85+
private boolean blockNodesPopulated;
8586

8687
private SimpleBlockGraphChunk(@NotNull SimpleServerGraphWorld world, @NotNull SectionPos chunkPos,
8788
@NotNull Runnable markDirty, @NotNull Serial serial) {
@@ -93,7 +94,6 @@ private SimpleBlockGraphChunk(@NotNull SimpleServerGraphWorld world, @NotNull Se
9394
for (SerialInPos serialInPos : serial.inPos()) {
9495
BlockPos pos = serialInPos.pos();
9596
short shortPos = SectionPos.sectionRelativePos(pos);
96-
BlockPos keyPos = pos.offset(chunkPos.minBlockX(), chunkPos.minBlockY(), chunkPos.minBlockZ());
9797

9898
LongSet inPos = graphsInPos.computeIfAbsent(shortPos, pos1 -> new LongLinkedOpenHashSet());
9999
Object2LongMap<BlockNode> nodes =
@@ -105,24 +105,14 @@ private SimpleBlockGraphChunk(@NotNull SimpleServerGraphWorld world, @NotNull Se
105105
inPos.add(serialNode.id());
106106
nodes.put(serialNode.node(), serialNode.id());
107107
}
108+
blockNodesPopulated = true;
108109
});
109110

110111
// Legacy route
111112
serialInPos.either().ifRight(longs -> {
112113
inPos.addAll(longs);
113114

114-
// build missing node->graphId map
115-
for (LongIterator it = longs.iterator(); it.hasNext(); ) {
116-
long graphId = it.nextLong();
117-
118-
SimpleBlockGraph graph = world.getGraph(graphId);
119-
if (graph != null) {
120-
for (var iter = graph.getNodesAt(keyPos).iterator(); iter.hasNext(); ) {
121-
var holder = iter.next();
122-
nodes.put(holder.getNode(), graphId);
123-
}
124-
}
125-
}
115+
blockNodesPopulated = false;
126116
});
127117
}
128118
}
@@ -135,18 +125,29 @@ public SimpleBlockGraphChunk(@NotNull SectionPos chunkPos, @NotNull Runnable mar
135125
private @NotNull Serial toSerial() {
136126
List<SerialInPos> inPosList = new ObjectArrayList<>();
137127

138-
for (ShortIterator keyIter = blockNodes.keySet().iterator(); keyIter.hasNext(); ) {
139-
short shortPos = keyIter.nextShort();
140-
BlockPos localPos =
141-
new BlockPos(SectionPos.sectionRelativeX(shortPos), SectionPos.sectionRelativeY(shortPos),
142-
SectionPos.sectionRelativeZ(shortPos));
128+
if (blockNodesPopulated) {
129+
for (ShortIterator keyIter = blockNodes.keySet().iterator(); keyIter.hasNext(); ) {
130+
short shortPos = keyIter.nextShort();
131+
BlockPos localPos =
132+
new BlockPos(SectionPos.sectionRelativeX(shortPos), SectionPos.sectionRelativeY(shortPos),
133+
SectionPos.sectionRelativeZ(shortPos));
143134

144-
List<SerialNode> serialNodes = new ObjectArrayList<>();
145-
for (Object2LongMap.Entry<BlockNode> nodeEntry : blockNodes.get(shortPos).object2LongEntrySet()) {
146-
serialNodes.add(new SerialNode(nodeEntry.getLongValue(), nodeEntry.getKey()));
147-
}
135+
List<SerialNode> serialNodes = new ObjectArrayList<>();
136+
for (Object2LongMap.Entry<BlockNode> nodeEntry : blockNodes.get(shortPos).object2LongEntrySet()) {
137+
serialNodes.add(new SerialNode(nodeEntry.getLongValue(), nodeEntry.getKey()));
138+
}
148139

149-
inPosList.add(new SerialInPos(localPos, Either.left(serialNodes)));
140+
inPosList.add(new SerialInPos(localPos, Either.left(serialNodes)));
141+
}
142+
} else {
143+
for (ShortIterator keyIter = graphsInPos.keySet().iterator(); keyIter.hasNext(); ) {
144+
short shortPos = keyIter.nextShort();
145+
BlockPos localPos =
146+
new BlockPos(SectionPos.sectionRelativeX(shortPos), SectionPos.sectionRelativeY(shortPos),
147+
SectionPos.sectionRelativeZ(shortPos));
148+
149+
inPosList.add(new SerialInPos(localPos, Either.right(graphsInPos.get(shortPos))));
150+
}
150151
}
151152

152153
return new Serial(graphsInChunk, inPosList);
@@ -158,6 +159,33 @@ public void clear() {
158159
blockNodes.clear();
159160
}
160161

162+
public void ensureBlockNodesPopulated(@NotNull Long2ObjectFunction<SimpleBlockGraph> graphGetter) {
163+
if (blockNodesPopulated) return;
164+
165+
// build missing node->graphId map
166+
for (LongIterator it = graphsInChunk.iterator(); it.hasNext(); ) {
167+
long graphId = it.nextLong();
168+
169+
SimpleBlockGraph graph = graphGetter.get(graphId);
170+
if (graph != null) {
171+
for (var iter = graph.getNodes().iterator(); iter.hasNext(); ) {
172+
var holder = iter.next();
173+
174+
BlockPos keyPos = holder.getBlockPos();
175+
if (chunkPos.minBlockX() <= keyPos.getX() && keyPos.getX() <= chunkPos.maxBlockX() &&
176+
chunkPos.minBlockY() <= keyPos.getY() && keyPos.getY() <= chunkPos.maxBlockY() &&
177+
chunkPos.minBlockZ() <= keyPos.getZ() && keyPos.getZ() <= chunkPos.maxBlockZ()) {
178+
179+
blockNodes.computeIfAbsent(SectionPos.sectionRelativePos(keyPos),
180+
pos1 -> new Object2LongLinkedOpenHashMap<>()).put(holder.getNode(), graphId);
181+
}
182+
}
183+
}
184+
}
185+
186+
blockNodesPopulated = true;
187+
}
188+
161189
public void putGraphWithNode(long id, @NotNull NodePos key) {
162190
markDirty.run();
163191

@@ -198,14 +226,16 @@ public void removeGraph(long id) {
198226
}
199227

200228
public @Nullable SimpleBlockGraph getGraphForNode(NodePos key, Long2ObjectFunction<SimpleBlockGraph> graphGetter) {
229+
ensureBlockNodesPopulated(graphGetter);
201230
Object2LongMap<BlockNode> uNodes = blockNodes.get(SectionPos.sectionRelativePos(key.pos()));
202231
if (uNodes == null) return null;
203232
if (!uNodes.containsKey(key.node())) return null;
204233

205234
return graphGetter.get(uNodes.getLong(key.node()));
206235
}
207236

208-
public boolean containsNode(NodePos key) {
237+
public boolean containsNode(NodePos key, Long2ObjectFunction<SimpleBlockGraph> graphGetter) {
238+
ensureBlockNodesPopulated(graphGetter);
209239
Object2LongMap<BlockNode> uNodes = blockNodes.get(SectionPos.sectionRelativePos(key.pos()));
210240
if (uNodes == null) return false;
211241
return uNodes.containsKey(key.node());

modules/core-xplat/src/main/java/com/kneelawk/graphlib/impl/graph/simple/SimpleServerGraphWorld.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ public void close() throws Exception {
308308
public boolean nodeExistsAt(@NotNull NodePos pos) {
309309
SimpleBlockGraphChunk chunk = chunks.getIfExists(SectionPos.of(pos.pos()));
310310
if (chunk != null) {
311-
return chunk.containsNode(pos);
311+
return chunk.containsNode(pos, this::getGraph);
312312
}
313313
return false;
314314
}

modules/syncing-core-xplat/src/main/java/com/kneelawk/graphlib/syncing/impl/graph/simple/SimpleClientGraphWorld.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public boolean nodeExistsAt(@NotNull NodePos pos) {
143143
SimpleBlockGraphChunk chunk = manager.getIfExists(SectionPos.of(pos.pos()));
144144
if (chunk == null) return false;
145145

146-
return chunk.containsNode(pos);
146+
return chunk.containsNode(pos, graphs);
147147
}
148148

149149
@Override

0 commit comments

Comments
 (0)