Prevent re-saving unmodified full data

This commit is contained in:
James Seibel
2024-03-02 16:21:32 -06:00
parent b8e03a2144
commit 47391028d8
5 changed files with 62 additions and 24 deletions
@@ -99,7 +99,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IDa
@Deprecated
@Override
public void update(NewFullDataSource dataSource, IDhLevel level) { throw new UnsupportedOperationException("Deprecated"); }
public boolean update(NewFullDataSource dataSource, IDhLevel level) { throw new UnsupportedOperationException("Deprecated"); }
@@ -37,6 +37,7 @@ import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -150,8 +151,8 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
public SingleColumnFullDataAccessor get(int relX, int relZ) { return new SingleColumnFullDataAccessor(this.mapping, this.dataPoints, relativePosToIndex(relX, relZ)); }
@Override
public void update(NewFullDataSource inputDataSource, @Nullable IDhLevel level) { this.update(inputDataSource); }
public void update(NewFullDataSource inputDataSource)
public boolean update(NewFullDataSource inputDataSource, @Nullable IDhLevel level) { return this.update(inputDataSource); }
public boolean update(NewFullDataSource inputDataSource)
{
byte thisDetailLevel = this.pos.getDetailLevel();
byte inputDetailLevel = inputDataSource.pos.getDetailLevel();
@@ -160,7 +161,7 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
// determine the mapping changes necessary for the input to map onto this datasource
int[] remappedIds = this.mapping.mergeAndReturnRemappedEntityIds(inputDataSource.mapping);
boolean dataChanged = false;
boolean dataChanged;
if (inputDetailLevel == thisDetailLevel)
{
dataChanged = this.updateFromSameDetailLevel(inputDataSource, remappedIds);
@@ -171,13 +172,11 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
}
else
{
// TODO what should happen here?
// other detail levels aren't supported since it would be more difficult to maintain
// and would lead to edge cases that don't necessarily need to be supported
// (IE what do you do when the input is smaller than a single datapoint in the receiving data source?)
// instead it's better to just percolate the updates up
//throw new UnsupportedOperationException("Unsupported data source update. Expected input detail level of ["+thisDetailLevel+"] or ["+(thisDetailLevel+1)+"], received detail level ["+inputDetailLevel+"].");
throw new UnsupportedOperationException("Unsupported data source update. Expected input detail level of ["+thisDetailLevel+"] or ["+(thisDetailLevel+1)+"], received detail level ["+inputDetailLevel+"].");
}
if (dataChanged && this.pos.getDetailLevel() < NewFullDataFileHandler.TOP_SECTION_DETAIL_LEVEL)
@@ -185,6 +184,8 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
// mark that this data source should be applied to its parent
this.applyToParent = true;
}
return dataChanged;
}
public boolean updateFromSameDetailLevel(NewFullDataSource inputDataSource, int[] remappedIds)
{
@@ -212,13 +213,22 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
if (inputGenState != EDhApiWorldGenerationStep.EMPTY.value
&& thisGenState <= inputGenState)
{
long[] oldDataArray = this.dataPoints[index];
// copy over the new data
this.dataPoints[index] = new long[newDataArray.length];
System.arraycopy(newDataArray, 0, this.dataPoints[index], 0, newDataArray.length);
this.remapDataColumn(index, remappedIds);
this.columnGenerationSteps[index] = inputGenState;
// we only need to see if the data was changed in one column
if (!dataChanged)
{
// needs to be done after the ID's have been remapped otherwise the ID's won't match even if the data is the same
dataChanged = areDataColumnsDifferent(oldDataArray, this.dataPoints[index]);
}
dataChanged = true; // TODO contents of the arrays should be compared to prevent re-writing the same data
this.columnGenerationSteps[index] = inputGenState;
this.isEmpty = false;
}
}
}
@@ -265,13 +275,20 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
int recipientZ = (z / 2) + recipientOffsetZ;
int recipientIndex = relativePosToIndex(recipientX, recipientZ);
long[] oldDataArray = this.dataPoints[recipientIndex];
this.columnGenerationSteps[recipientIndex] = inputGenStep;
this.dataPoints[recipientIndex] = inputDataArray;
this.remapDataColumn(recipientIndex, remappedIds);
this.isEmpty = false;
// we only need to see if the data was changed in one column
if (!dataChanged)
{
// needs to be done after the ID's have been remapped otherwise the ID's won't match even if the data is the same
dataChanged = areDataColumnsDifferent(oldDataArray, this.dataPoints[recipientIndex]);
}
dataChanged = true; // TODO contents of the arrays should probably be compared or something
this.isEmpty = false;
}
}
}
@@ -291,6 +308,21 @@ public class NewFullDataSource implements IDataSource<IDhLevel>
dataColumn[i] = FullDataPointUtil.remap(remappedIds, dataColumn[i]);
}
}
private static boolean areDataColumnsDifferent(long[] oldDataArray, long[] newDataArray)
{
if (oldDataArray == null || oldDataArray.length != newDataArray.length)
{
// new data was added/removed
return true;
}
else
{
// check if the new column data is different
int oldArrayHash = Arrays.hashCode(oldDataArray);
int newArrayHash = Arrays.hashCode(newDataArray);
return (newArrayHash != oldArrayHash);
}
}
@@ -290,7 +290,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
}
@Override
public void update(NewFullDataSource inputDataSource, IDhClientLevel level)
public boolean update(NewFullDataSource inputDataSource, IDhClientLevel level)
{
final String errorMessagePrefix = "Unable to complete update for RenderSource pos: [" + this.sectionPos + "] and pos: [" + inputDataSource.getSectionPos() + "]. Error:";
@@ -302,7 +302,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
if (Thread.interrupted())
{
LOGGER.warn(errorMessagePrefix + "write interrupted.");
return;
return false;
}
@@ -340,11 +340,14 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
}
if (dataChanged)
{
this.localVersion.incrementAndGet();
this.markNotEmpty();
}
return dataChanged;
}
@@ -210,19 +210,21 @@ public abstract class AbstractNewDataSourceHandler
// get or create the data source
TDataSource dataSource = this.get(pos);
dataSource.update(inputData, this.level); // TODO only write to database and send update signal if data was changed
boolean dataModified = dataSource.update(inputData, this.level);
// save the updated data to the database
TDTO dto = this.createDtoFromDataSource(dataSource);
this.repo.save(dto);
for (IDataSourceUpdateFunc<TDataSource> listener : this.dateSourceUpdateListeners)
if (dataModified)
{
if (listener != null)
// save the updated data to the database
TDTO dto = this.createDtoFromDataSource(dataSource);
this.repo.save(dto);
for (IDataSourceUpdateFunc<TDataSource> listener : this.dateSourceUpdateListeners)
{
listener.OnDataSourceUpdated(dataSource);
if (listener != null)
{
listener.OnDataSourceUpdated(dataSource);
}
}
}
}
@@ -25,7 +25,8 @@ public interface IDataSource<TDhLevel extends IDhLevel> extends IBaseDTO<DhSecti
// file handling //
//===============//
void update(NewFullDataSource chunkData, TDhLevel level);
/** @return true if the data was changed */
boolean update(NewFullDataSource chunkData, TDhLevel level);
// still used by RenderSource, remove once that's been changed
@Deprecated