Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 106 additions & 6 deletions src/main/java/cr0s/warpdrive/data/GlobalRegionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public class GlobalRegionManager {
public static String GALAXY_UNDEFINED = "???";

private static final HashMap<Integer, CopyOnWriteArraySet<GlobalRegion>> registry = new HashMap<>();
private static final HashMap<Integer, HashMap<EnumGlobalRegionType, CopyOnWriteArraySet<GlobalRegion>>> cache_registryByType = new HashMap<>();
private static final HashMap<Integer, HashMap<Long, CopyOnWriteArraySet<GlobalRegion>>> cache_registryByChunk = new HashMap<>();
private static final HashMap<UUID, GlobalRegion> cache_registryByUUID = new HashMap<>();
private static final HashMap<String, CopyOnWriteArraySet<GlobalRegion>> cache_registryByName = new HashMap<>();
private static int countAdd = 0;
private static int countRemove = 0;
private static int countRead = 0;
Expand All @@ -68,6 +72,11 @@ public static void updateInRegistry(@Nonnull final IGlobalRegionProvider globalR
globalRegionProvider ));
return;
}
if (globalRegionProvider.getGlobalRegionType() == null) {
WarpDrive.logger.error(String.format("Ignoring invalid IGlobalRegionProvider with no region type %s",
globalRegionProvider ));
return;
}

// update statistics
countRead++;
Expand Down Expand Up @@ -101,6 +110,7 @@ public static void updateInRegistry(@Nonnull final IGlobalRegionProvider globalR
// note: in-place update only works as long as hashcode remains unchanged, that means same position, same type, same UUID
registryItem.update(globalRegionProvider);
setRegistryItems.removeAll(listToRemove);
rebuildIndexes();
if (WarpDriveConfig.LOGGING_GLOBAL_REGION_REGISTRY) {
printRegistry("updated");
}
Expand All @@ -116,6 +126,7 @@ public static void updateInRegistry(@Nonnull final IGlobalRegionProvider globalR
countAdd++;
setRegistryItems.add(new GlobalRegion(globalRegionProvider));
registry.put(globalRegionProvider.getDimension(), setRegistryItems);
rebuildIndexes();
if (WarpDriveConfig.LOGGING_GLOBAL_REGION_REGISTRY) {
printRegistry("added");
}
Expand All @@ -135,6 +146,7 @@ public static void removeFromRegistry(@Nonnull final IGlobalRegionProvider globa
// found it, remove and exit
countRemove++;
setRegistryItems.remove(registryItem);
rebuildIndexes();
return;
}
}
Expand All @@ -143,6 +155,15 @@ public static void removeFromRegistry(@Nonnull final IGlobalRegionProvider globa

@Nullable
public static GlobalRegion getByName(final EnumGlobalRegionType enumGlobalRegionType, final String name) {
final Set<GlobalRegion> setByName = cache_registryByName.get(name == null ? "" : name);
if (setByName != null) {
for (final GlobalRegion globalRegion : setByName) {
if ( enumGlobalRegionType == null
|| globalRegion.type == enumGlobalRegionType ) {
return globalRegion;
}
}
}
for (final Integer dimensionId : registry.keySet()) {
final CopyOnWriteArraySet<GlobalRegion> setGlobalRegions = registry.get(dimensionId);
if (setGlobalRegions == null) {
Expand All @@ -165,6 +186,12 @@ public static GlobalRegion getByUUID(final EnumGlobalRegionType enumGlobalRegion
if (uuid == null) {
return null;
}
final GlobalRegion globalRegionCached = cache_registryByUUID.get(uuid);
if ( globalRegionCached != null
&& ( enumGlobalRegionType == null
|| globalRegionCached.type == enumGlobalRegionType ) ) {
return globalRegionCached;
}
for (final Integer dimensionId : registry.keySet()) {
final CopyOnWriteArraySet<GlobalRegion> setGlobalRegions = registry.get(dimensionId);
if (setGlobalRegions == null) {
Expand Down Expand Up @@ -251,7 +278,7 @@ public static String listByKeyword(final EnumGlobalRegionType enumGlobalRegionTy

@Nullable
public static GlobalRegion getNearest(final EnumGlobalRegionType enumGlobalRegionType, @Nonnull final World world, @Nonnull final BlockPos blockPos) {
final CopyOnWriteArraySet<GlobalRegion> setGlobalRegions = registry.get(world.provider.getDimension());
final Set<GlobalRegion> setGlobalRegions = getRegionsByType(world.provider.getDimension(), enumGlobalRegionType);
if (setGlobalRegions == null) {
return null;
}
Expand Down Expand Up @@ -280,7 +307,7 @@ public static GlobalRegion getNearest(final EnumGlobalRegionType enumGlobalRegio

@Nonnull
public static ArrayList<GlobalRegion> getContainers(final EnumGlobalRegionType enumGlobalRegionType, @Nonnull final World world, @Nonnull final BlockPos blockPos) {
final CopyOnWriteArraySet<GlobalRegion> setGlobalRegions = registry.get(world.provider.getDimension());
final Set<GlobalRegion> setGlobalRegions = getRegionsByChunk(world.provider.getDimension(), blockPos);
if (setGlobalRegions == null) {
return new ArrayList<>(0);
}
Expand Down Expand Up @@ -316,7 +343,7 @@ public static boolean onBlockUpdating(@Nullable final Entity entity, @Nonnull fi
blockState, Commons.format(world, blockPos) ));
return false;
}
final CopyOnWriteArraySet<GlobalRegion> setGlobalRegions = registry.get(world.provider.getDimension());
final Set<GlobalRegion> setGlobalRegions = getRegionsByChunk(world.provider.getDimension(), blockPos);
if (setGlobalRegions == null) {
return true;
}
Expand All @@ -339,11 +366,11 @@ public static boolean onChatReceived(@Nonnull final EntityPlayer entityPlayer, @
entityPlayer, message ));
return false;
}
final CopyOnWriteArraySet<GlobalRegion> setGlobalRegions = registry.get(entityPlayer.world.provider.getDimension());
final BlockPos blockPos = entityPlayer.getPosition();
final Set<GlobalRegion> setGlobalRegions = getRegionsByChunk(entityPlayer.world.provider.getDimension(), blockPos);
if (setGlobalRegions == null) {
return true;
}
final BlockPos blockPos = entityPlayer.getPosition();
boolean isCancelled = false;
for (final GlobalRegion registryItem : setGlobalRegions) {
if (registryItem.type == EnumGlobalRegionType.VIRTUAL_ASSISTANT
Expand Down Expand Up @@ -431,6 +458,68 @@ public static Vector3 getUniversalCoordinates(final CelestialObject celestialObj
}
return hasHyperspace ? vec3Result : null;
}

@Nullable
private static Set<GlobalRegion> getRegionsByType(final int dimensionId, @Nullable final EnumGlobalRegionType enumGlobalRegionType) {
if (enumGlobalRegionType == null) {
return registry.get(dimensionId);
}
final HashMap<EnumGlobalRegionType, CopyOnWriteArraySet<GlobalRegion>> mapByType = cache_registryByType.get(dimensionId);
return mapByType == null ? null : mapByType.get(enumGlobalRegionType);
}

@Nullable
private static Set<GlobalRegion> getRegionsByChunk(final int dimensionId, @Nonnull final BlockPos blockPos) {
final HashMap<Long, CopyOnWriteArraySet<GlobalRegion>> mapByChunk = cache_registryByChunk.get(dimensionId);
return mapByChunk == null ? null : mapByChunk.get(ChunkPos.asLong(blockPos.getX() >> 4, blockPos.getZ() >> 4));
}

private static void rebuildIndexes() {
cache_registryByType.clear();
cache_registryByChunk.clear();
cache_registryByUUID.clear();
cache_registryByName.clear();
for (final Map.Entry<Integer, CopyOnWriteArraySet<GlobalRegion>> entryDimension : registry.entrySet()) {
final int dimensionId = entryDimension.getKey();
final HashMap<EnumGlobalRegionType, CopyOnWriteArraySet<GlobalRegion>> mapByType = new HashMap<>();
final HashMap<Long, CopyOnWriteArraySet<GlobalRegion>> mapByChunk = new HashMap<>();
for (final GlobalRegion globalRegion : entryDimension.getValue()) {
if ( globalRegion == null
|| globalRegion.type == null ) {
continue;
}
CopyOnWriteArraySet<GlobalRegion> setByType = mapByType.get(globalRegion.type);
if (setByType == null) {
setByType = new CopyOnWriteArraySet<>();
mapByType.put(globalRegion.type, setByType);
}
setByType.add(globalRegion);
if (globalRegion.uuid != null) {
cache_registryByUUID.put(globalRegion.uuid, globalRegion);
}
final String name = globalRegion.name == null ? "" : globalRegion.name;
CopyOnWriteArraySet<GlobalRegion> setByName = cache_registryByName.get(name);
if (setByName == null) {
setByName = new CopyOnWriteArraySet<>();
cache_registryByName.put(name, setByName);
}
setByName.add(globalRegion);
for (int xChunk = globalRegion.minX >> 4; xChunk <= globalRegion.maxX >> 4; xChunk++) {
for (int zChunk = globalRegion.minZ >> 4; zChunk <= globalRegion.maxZ >> 4; zChunk++) {
final Long keyChunk = ChunkPos.asLong(xChunk, zChunk);
CopyOnWriteArraySet<GlobalRegion> setByChunk = mapByChunk.get(keyChunk);
if (setByChunk == null) {
setByChunk = new CopyOnWriteArraySet<>();
mapByChunk.put(keyChunk, setByChunk);
}
setByChunk.add(globalRegion);
}
}
}
cache_registryByType.put(dimensionId, mapByType);
cache_registryByChunk.put(dimensionId, mapByChunk);
}
}

public static void printRegistry(final String trigger) {
WarpDrive.logger.info(String.format("Global region registry after %s:", trigger));
Expand Down Expand Up @@ -564,7 +653,9 @@ private static void cleanup() {

final TileEntity tileEntity = world.getTileEntity(registryItem.getBlockPos());
isValid = true;
switch (registryItem.type) {
if (registryItem.type == null) {
isValid = false;
} else switch (registryItem.type) {
case UNDEFINED:
break;
case SHIP:
Expand Down Expand Up @@ -608,6 +699,7 @@ private static void cleanup() {
}
}
}
rebuildIndexes();

LocalProfiler.stop();
}
Expand All @@ -617,6 +709,7 @@ public static void readFromNBT(@Nullable final NBTTagCompound tagCompound) {
|| ( !tagCompound.hasKey("starMapRegistryItems")
&& !tagCompound.hasKey("globalRegions") ) ) {
registry.clear();
rebuildIndexes();
return;
}

Expand All @@ -631,6 +724,9 @@ public static void readFromNBT(@Nullable final NBTTagCompound tagCompound) {
final HashMap<Integer, Integer> sizeDimensions = new HashMap<>();
for (int index = 0; index < tagList.tagCount(); index++) {
final GlobalRegion globalRegion = new GlobalRegion(tagList.getCompoundTagAt(index));
if (globalRegion.type == null) {
continue;
}
registryFlat[index] = globalRegion;

// update stats
Expand All @@ -647,6 +743,9 @@ public static void readFromNBT(@Nullable final NBTTagCompound tagCompound) {

// fill the local collections
for (final GlobalRegion globalRegion : registryFlat) {
if (globalRegion == null) {
continue;
}
registryLocal.get(globalRegion.dimensionId).add(globalRegion);
}

Expand All @@ -655,6 +754,7 @@ public static void readFromNBT(@Nullable final NBTTagCompound tagCompound) {
for (final Entry<Integer, ArrayList<GlobalRegion>> entry : registryLocal.entrySet()) {
registry.put(entry.getKey(), new CopyOnWriteArraySet<>(entry.getValue()));
}
rebuildIndexes();
}

public static void writeToNBT(@Nonnull final NBTTagCompound tagCompound) {
Expand Down