Removed Warnings

This commit is contained in:
2026-07-31 10:17:39 +02:00
parent cdcbd92f73
commit 0c5e4ef976
6 changed files with 658 additions and 656 deletions
@@ -146,6 +146,7 @@ public class NewInputTest {
// Font font = fonts.createFont(1F); // Font font = fonts.createFont(1F);
TestModel model = new TestModel(builder.getBytes()); TestModel model = new TestModel(builder.getBytes());
builder.close();
// TestModel[] guiModel = new TestModel[1]; // TestModel[] guiModel = new TestModel[1];
// List<GLDraw> draws = new ObjectArrayList<>(); // List<GLDraw> draws = new ObjectArrayList<>();
// TexturedBuffer buffer = new TexturedBuffer((K, V) -> { // TexturedBuffer buffer = new TexturedBuffer((K, V) -> {
@@ -233,6 +234,7 @@ public class NewInputTest {
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex(); builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
TestModel model = new TestModel(builder.getBytes()); TestModel model = new TestModel(builder.getBytes());
builder.close();
while(!window.shouldClose()) { while(!window.shouldClose()) {
GLFW.glfwPollEvents(); GLFW.glfwPollEvents();
if(window.changed()) { if(window.changed()) {
@@ -68,7 +68,6 @@ public class NewRenderEngineTest {
GraphicsDevice device = window.device(); GraphicsDevice device = window.device();
int size = 512; int size = 512;
int half = size >> 1; int half = size >> 1;
int base = size >> 3;
Drawable drawer = new Drawable(GLTextureFormat.RGBA, size, size); Drawable drawer = new Drawable(GLTextureFormat.RGBA, size, size);
drawer.fill(0, 0, size, size, -1); drawer.fill(0, 0, size, size, -1);
drawer.fill(0, 0, half, half, 255, 0, 0, 255); drawer.fill(0, 0, half, half, 255, 0, 0, 255);
@@ -97,6 +96,7 @@ public class NewRenderEngineTest {
Mesh mesh = device.createMesh(Mesh.builder().layout(layout)); Mesh mesh = device.createMesh(Mesh.builder().layout(layout));
mesh.buffer(0, device.createBuffer(BufferType.ARRAY_BUFFER, BufferState.STATIC_DRAW).bind().set(builder.getBytes()).unbind()); mesh.buffer(0, device.createBuffer(BufferType.ARRAY_BUFFER, BufferState.STATIC_DRAW).bind().set(builder.getBytes()).unbind());
builder.close();
Sampler sampler = device.createSampler(SamplerSettings.builder().sampler(SampleMode.NEAREST).wrap(BorderMode.CLAMP_TO_EDGE).build()); Sampler sampler = device.createSampler(SamplerSettings.builder().sampler(SampleMode.NEAREST).wrap(BorderMode.CLAMP_TO_EDGE).build());
VertexBuffer buffer = device.createBuffer(BufferType.UNIFORM_BUFFER, BufferState.STATIC_DRAW); VertexBuffer buffer = device.createBuffer(BufferType.UNIFORM_BUFFER, BufferState.STATIC_DRAW);
@@ -55,7 +55,7 @@ public class ModelLoader
{ {
if(line.startsWith("{")) if(line.startsWith("{"))
{ {
if(currentName != null) if(currentName != null && buffer != null)
{ {
resultModels.add(new SimpleModelData(currentName, null, buffer.array(), indexes)); resultModels.add(new SimpleModelData(currentName, null, buffer.array(), indexes));
currentName = null; currentName = null;
@@ -70,7 +70,7 @@ public class ModelLoader
buffer = ByteBuffer.allocate(Integer.parseInt(bounds[0]) * 28).order(ByteOrder.nativeOrder()); buffer = ByteBuffer.allocate(Integer.parseInt(bounds[0]) * 28).order(ByteOrder.nativeOrder());
indexes = new int[Integer.parseInt(bounds[1])]; indexes = new int[Integer.parseInt(bounds[1])];
} }
else if(line.startsWith("<")) else if(line.startsWith("<") && buffer != null)
{ {
String[] data = line.substring(1, line.length() - 1).split(" "); String[] data = line.substring(1, line.length() - 1).split(" ");
String[] position = data[0].split(";"); String[] position = data[0].split(";");
@@ -79,7 +79,7 @@ public class ModelLoader
ColorUtils.write(Integer.parseInt(data[1]), true, buffer); ColorUtils.write(Integer.parseInt(data[1]), true, buffer);
buffer.putFloat(Float.parseFloat(normal[0])).putFloat(Float.parseFloat(normal[1])).putFloat(Float.parseFloat(normal[2])); buffer.putFloat(Float.parseFloat(normal[0])).putFloat(Float.parseFloat(normal[1])).putFloat(Float.parseFloat(normal[2]));
} }
else if(line.startsWith("[")) else if(line.startsWith("[") && indexes != null)
{ {
String[] data = line.substring(1, line.length() - 1).split(";"); String[] data = line.substring(1, line.length() - 1).split(";");
for(int j = 0;j<data.length;j++) for(int j = 0;j<data.length;j++)
@@ -88,7 +88,7 @@ public class ModelLoader
} }
} }
} }
if(currentName != null) if(currentName != null && buffer != null)
{ {
resultModels.add(new SimpleModelData(currentName, null, buffer.array(), indexes)); resultModels.add(new SimpleModelData(currentName, null, buffer.array(), indexes));
currentName = null; currentName = null;
@@ -1,80 +1,80 @@
package speiger.src.coreengine.utils.collections.collection; package speiger.src.coreengine.utils.collections.collection;
public class BitArray { public class BitArray {
long[] data; long[] data;
int size; int size;
int bits; int bits;
long maxValue; long maxValue;
public BitArray(int size, int bits) { public BitArray(int size, int bits) {
this.size = size; this.size = size;
this.bits = bits; this.bits = bits;
maxValue = (1L << bits) - 1L; maxValue = (1L << bits) - 1L;
data = new long[arraySize(size * bits)]; data = new long[arraySize(size * bits)];
} }
public BitArray(int size, int bits, long[] data) { public BitArray(int size, int bits, long[] data) {
this.size = size; this.size = size;
this.bits = bits; this.bits = bits;
maxValue = (1L << bits) - 1L; maxValue = (1L << bits) - 1L;
int arraySize = arraySize(size * bits); int arraySize = arraySize(size * bits);
if(data == null || data.length != arraySize) { if(data == null || data.length != arraySize) {
this.data = new long[arraySize]; this.data = new long[arraySize];
if(data.length < arraySize) System.arraycopy(data, 0, this.data, 0, Math.min(data.length, arraySize)); if(this.data.length < arraySize) System.arraycopy(data, 0, this.data, 0, Math.min(this.data.length, arraySize));
} }
else this.data = data; else this.data = data;
} }
private int arraySize(int entries) { private int arraySize(int entries) {
return entries % 64 == 0 ? entries / 64 : (entries / 64) + 1; return entries % 64 == 0 ? entries / 64 : (entries / 64) + 1;
} }
public void set(int index, long value) { public void set(int index, long value) {
if(index < 0 || index >= size) throw new IllegalStateException("Out ouf Bounds"); if(index < 0 || index >= size) throw new IllegalStateException("Out ouf Bounds");
int arrayIndex = (index * bits) / 64; int arrayIndex = (index * bits) / 64;
int bitIndex = (index * bits) % 64; int bitIndex = (index * bits) % 64;
data[arrayIndex] = data[arrayIndex] & ~(maxValue << bitIndex) | (value & maxValue) << bitIndex; data[arrayIndex] = data[arrayIndex] & ~(maxValue << bitIndex) | (value & maxValue) << bitIndex;
int left = 64 - bitIndex; int left = 64 - bitIndex;
if(left < bits) { if(left < bits) {
int leftover = bits - left; int leftover = bits - left;
data[arrayIndex + 1] = data[arrayIndex + 1] >>> leftover << leftover | (value & maxValue) >> left; data[arrayIndex + 1] = data[arrayIndex + 1] >>> leftover << leftover | (value & maxValue) >> left;
} }
} }
public void clear(int index) { public void clear(int index) {
set(index, 0L); set(index, 0L);
} }
public long get(int index) { public long get(int index) {
if(index < 0 || index >= size) throw new IllegalStateException("Out ouf Bounds"); if(index < 0 || index >= size) throw new IllegalStateException("Out ouf Bounds");
int arrayIndex = (index * bits) / 64; int arrayIndex = (index * bits) / 64;
int bitIndex = (index * bits) % 64; int bitIndex = (index * bits) % 64;
return (64 - bitIndex < bits ? (data[arrayIndex] >>> bitIndex | data[arrayIndex + 1] << (64 - bitIndex)) : (data[arrayIndex] >>> bitIndex)) & maxValue; return (64 - bitIndex < bits ? (data[arrayIndex] >>> bitIndex | data[arrayIndex + 1] << (64 - bitIndex)) : (data[arrayIndex] >>> bitIndex)) & maxValue;
} }
public int getInt(int index) { public int getInt(int index) {
return (int)get(index); return (int)get(index);
} }
public int swapInt(int index, int newValue) { public int swapInt(int index, int newValue) {
int value = getInt(index); int value = getInt(index);
if(newValue != value) set(index, newValue); if(newValue != value) set(index, newValue);
return value; return value;
} }
public long swap(int index, long newValue) { public long swap(int index, long newValue) {
long value = get(index); long value = get(index);
if(newValue != value) set(index, newValue); if(newValue != value) set(index, newValue);
return value; return value;
} }
public int size() { public int size() {
return size; return size;
} }
public int bits() { public int bits() {
return bits; return bits;
} }
public long[] getData() { return data; } public long[] getData() { return data; }
} }
@@ -1,215 +1,215 @@
package speiger.src.coreengine.utils.collections.managers.dynamic; package speiger.src.coreengine.utils.collections.managers.dynamic;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import speiger.src.collections.ints.collections.IntIterator; import speiger.src.collections.ints.collections.IntIterator;
import speiger.src.collections.ints.maps.abstracts.AbstractInt2IntMap.BasicEntry; import speiger.src.collections.ints.maps.abstracts.AbstractInt2IntMap.BasicEntry;
import speiger.src.collections.ints.maps.interfaces.Int2IntMap; import speiger.src.collections.ints.maps.interfaces.Int2IntMap;
import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap; import speiger.src.collections.ints.maps.interfaces.Int2ObjectMap;
import speiger.src.collections.ints.misc.pairs.IntObjectPair; import speiger.src.collections.ints.misc.pairs.IntObjectPair;
import speiger.src.collections.ints.sets.IntAVLTreeSet; import speiger.src.collections.ints.sets.IntAVLTreeSet;
import speiger.src.collections.ints.sets.IntSet; import speiger.src.collections.ints.sets.IntSet;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.sets.ObjectAVLTreeSet; import speiger.src.collections.objects.sets.ObjectAVLTreeSet;
import speiger.src.collections.objects.utils.ObjectLists; import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.utils.collections.pools.ThreadPool; import speiger.src.coreengine.utils.collections.pools.ThreadPool;
public class DynamicDataManager<T> public class DynamicDataManager<T>
{ {
static final ThreadPool<DataSlot> SLOTS = new ThreadPool<>(1000, DataSlot::new, DataSlot::clear); static final ThreadPool<DataSlot> SLOTS = new ThreadPool<>(1000, DataSlot::new, DataSlot::clear);
final IDynamicDataHandler<T> manager; final IDynamicDataHandler<T> manager;
Int2ObjectMap<DataSlot> slots = Int2ObjectMap.builder().linkedMap(); Int2ObjectMap<DataSlot> slots = Int2ObjectMap.builder().linkedMap();
Set<DataSlot> emptySlots = new ObjectAVLTreeSet<>(); Set<DataSlot> emptySlots = new ObjectAVLTreeSet<>();
IntSet changedSlots = new IntAVLTreeSet(); IntSet changedSlots = new IntAVLTreeSet();
DataSlot lastSlot = null; DataSlot lastSlot = null;
public DynamicDataManager(IDynamicDataHandler<T> manager) public DynamicDataManager(IDynamicDataHandler<T> manager)
{ {
this.manager = manager; this.manager = manager;
} }
public boolean add(int dataIndex, T value) public boolean add(int dataIndex, T value)
{ {
if(slots.containsKey(dataIndex)) return false; if(slots.containsKey(dataIndex)) return false;
return add(dataIndex, manager.toBytes(value)); return add(dataIndex, manager.toBytes(value));
} }
protected boolean add(int dataIndex, byte[] data) protected boolean add(int dataIndex, byte[] data)
{ {
if(!emptySlots.isEmpty()) if(!emptySlots.isEmpty())
{ {
for(Iterator<DataSlot> iter = emptySlots.iterator();iter.hasNext();) for(Iterator<DataSlot> iter = emptySlots.iterator();iter.hasNext();)
{ {
DataSlot slot = iter.next(); DataSlot slot = iter.next();
if(slot.getFreeBytes() >= data.length) if(slot.getFreeBytes() >= data.length)
{ {
slot.setData(dataIndex, data); slot.setData(dataIndex, data);
slots.put(dataIndex, slot); slots.put(dataIndex, slot);
changedSlots.add(dataIndex); changedSlots.add(dataIndex);
return true; return true;
} }
} }
} }
DataSlot next = SLOTS.get(); DataSlot next = SLOTS.get();
next.set(lastSlot, dataIndex, data); next.set(lastSlot, dataIndex, data);
slots.put(dataIndex, next); slots.put(dataIndex, next);
changedSlots.add(dataIndex); changedSlots.add(dataIndex);
lastSlot = next; lastSlot = next;
return true; return true;
} }
public boolean contains(int dataIndex) public boolean contains(int dataIndex)
{ {
return slots.containsKey(dataIndex); return slots.containsKey(dataIndex);
} }
public boolean update(int dataIndex, T value) public boolean update(int dataIndex, T value)
{ {
DataSlot slot = slots.get(dataIndex); DataSlot slot = slots.get(dataIndex);
if(slot != null) if(slot != null)
{ {
byte[] data = manager.toBytes(value); byte[] data = manager.toBytes(value);
if(slot.getFreeBytes() >= data.length) if(slot.getFreeBytes() >= data.length)
{ {
slot.setData(dataIndex, data); slot.setData(dataIndex, data);
changedSlots.add(dataIndex); changedSlots.add(dataIndex);
return true; return true;
} }
else else
{ {
slot.setData(-1, null); slot.setData(-1, null);
slots.remove(dataIndex); slots.remove(dataIndex);
add(dataIndex, data); add(dataIndex, data);
emptySlots.add(slot); emptySlots.add(slot);
return true; return true;
} }
} }
return false; return false;
} }
public Iterator<Int2IntMap.Entry> iterator(int byteOffset) public Iterator<Int2IntMap.Entry> iterator(int byteOffset)
{ {
return new Iterator<Int2IntMap.Entry>() { return new Iterator<Int2IntMap.Entry>() {
BasicEntry entry = new BasicEntry(); BasicEntry entry = new BasicEntry();
DataSlot current = findNextSlot(lastSlot); DataSlot current = findNextSlot(lastSlot);
@Override @Override
public boolean hasNext() public boolean hasNext()
{ {
return current != null; return current != null;
} }
DataSlot findNextSlot(DataSlot input) DataSlot findNextSlot(DataSlot input)
{ {
for(input = input.previous; input != null && input.value == null;input = input.previous); for(input = input.previous; input != null && input.value == null;input = input.previous);
return input; return input;
} }
@Override @Override
public Int2IntMap.Entry next() public Int2IntMap.Entry next()
{ {
if(!hasNext()) throw new IllegalStateException(); if(!hasNext()) throw new IllegalStateException();
entry.set(current.dataIndex, current.byteOffset / byteOffset); entry.set(current.dataIndex, current.byteOffset / byteOffset);
current = findNextSlot(current); current = findNextSlot(current);
return entry; return entry;
} }
}; };
} }
public boolean remove(int dataIndex) public boolean remove(int dataIndex)
{ {
DataSlot slot = slots.remove(dataIndex); DataSlot slot = slots.remove(dataIndex);
if(slot != null) if(slot != null)
{ {
slot.setData(-1, null); slot.setData(-1, null);
emptySlots.add(slot); emptySlots.add(slot);
return true; return true;
} }
return false; return false;
} }
protected void clearEmptySlots() protected void clearEmptySlots()
{ {
while(lastSlot != null && lastSlot.value == null) while(lastSlot != null && lastSlot.value == null)
{ {
DataSlot prev = lastSlot; DataSlot prev = lastSlot;
emptySlots.remove(prev); emptySlots.remove(prev);
lastSlot = prev.previous; lastSlot = prev.previous;
SLOTS.accept(prev); SLOTS.accept(prev);
} }
} }
public void clear() public void clear()
{ {
slots.clear(); slots.clear();
emptySlots.clear(); emptySlots.clear();
changedSlots.clear(); changedSlots.clear();
while(lastSlot != null) while(lastSlot != null)
{ {
DataSlot prev = lastSlot; DataSlot prev = lastSlot;
lastSlot = prev.previous; lastSlot = prev.previous;
SLOTS.accept(prev); SLOTS.accept(prev);
} }
} }
public void update() public void update()
{ {
int last = getEndSize(); int last = getEndSize();
clearEmptySlots(); clearEmptySlots();
if(changedSlots.isEmpty()) if(changedSlots.isEmpty())
{ {
if(last != getEndSize()) if(last != getEndSize())
{ {
manager.uploadBytes(ObjectLists.empty(), getEndSize()); manager.uploadBytes(ObjectLists.empty(), getEndSize());
} }
return; return;
} }
List<IntObjectPair<byte[]>> list = new ObjectArrayList<>(); List<IntObjectPair<byte[]>> list = new ObjectArrayList<>();
while(!changedSlots.isEmpty()) while(!changedSlots.isEmpty())
{ {
DataSlot start = null; DataSlot start = null;
DataSlot current = null; DataSlot current = null;
int bytesAllocated = 0; int bytesAllocated = 0;
for(IntIterator iter = changedSlots.iterator();iter.hasNext();) for(IntIterator iter = changedSlots.iterator();iter.hasNext();)
{ {
DataSlot slot = slots.get(iter.nextInt()); DataSlot slot = slots.get(iter.nextInt());
iter.remove(); iter.remove();
if(slot == null) break; if(slot == null) break;
if(current == null || current.next == slot) if(current == null || current.next == slot)
{ {
current = slot; current = slot;
if(start == null) start = slot; if(start == null) start = slot;
bytesAllocated += slot.getUsedBytes(); bytesAllocated += slot.getUsedBytes();
continue; continue;
} }
break; break;
} }
if(bytesAllocated <= 0) continue; if(bytesAllocated <= 0 || start == null || current == null) continue;
byte[] data = new byte[bytesAllocated]; byte[] data = new byte[bytesAllocated];
int byteOffset = start.byteOffset; int byteOffset = start.byteOffset;
bytesAllocated = 0; bytesAllocated = 0;
while(start.byteOffset <= current.byteOffset); while(start.byteOffset <= current.byteOffset);
{ {
System.arraycopy(start.value, 0, data, bytesAllocated, start.value.length); System.arraycopy(start.value, 0, data, bytesAllocated, start.value.length);
bytesAllocated += start.getUsedBytes(); bytesAllocated += start.getUsedBytes();
start = start.next; start = start.next;
} }
list.add(IntObjectPair.of(byteOffset, data)); list.add(IntObjectPair.of(byteOffset, data));
} }
if(!list.isEmpty()) if(!list.isEmpty())
{ {
manager.uploadBytes(list, getEndSize()); manager.uploadBytes(list, getEndSize());
} }
} }
private int getEndSize() private int getEndSize()
{ {
return lastSlot == null ? 0 : lastSlot.getNextByteOffset(); return lastSlot == null ? 0 : lastSlot.getNextByteOffset();
} }
public int size() public int size()
{ {
return slots.size(); return slots.size();
} }
} }
@@ -1,357 +1,357 @@
package speiger.src.coreengine.utils.collections.managers.fixed; package speiger.src.coreengine.utils.collections.managers.fixed;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import speiger.src.collections.ints.collections.IntCollection; import speiger.src.collections.ints.collections.IntCollection;
import speiger.src.collections.ints.collections.IntIterator; import speiger.src.collections.ints.collections.IntIterator;
import speiger.src.collections.ints.functions.IntComparator; import speiger.src.collections.ints.functions.IntComparator;
import speiger.src.collections.ints.lists.IntArrayList; import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.ints.lists.IntList; import speiger.src.collections.ints.lists.IntList;
import speiger.src.collections.ints.maps.impl.hash.Int2IntOpenHashMap; import speiger.src.collections.ints.maps.impl.hash.Int2IntOpenHashMap;
import speiger.src.collections.ints.maps.interfaces.Int2IntMap; import speiger.src.collections.ints.maps.interfaces.Int2IntMap;
import speiger.src.collections.ints.misc.pairs.IntObjectPair; import speiger.src.collections.ints.misc.pairs.IntObjectPair;
import speiger.src.collections.ints.sets.IntAVLTreeSet; import speiger.src.collections.ints.sets.IntAVLTreeSet;
import speiger.src.collections.ints.sets.IntLinkedOpenHashSet; import speiger.src.collections.ints.sets.IntLinkedOpenHashSet;
import speiger.src.collections.ints.sets.IntSet; import speiger.src.collections.ints.sets.IntSet;
import speiger.src.collections.ints.sets.IntSortedSet; import speiger.src.collections.ints.sets.IntSortedSet;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectArrays; import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.objects.utils.ObjectLists; import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.utils.collections.pools.ThreadPool; import speiger.src.coreengine.utils.collections.pools.ThreadPool;
public class FixedDataManager public class FixedDataManager
{ {
static final ThreadPool<FixedSlot> SLOTS = new ThreadPool<>(1000, FixedSlot::new); static final ThreadPool<FixedSlot> SLOTS = new ThreadPool<>(1000, FixedSlot::new);
final int bytesPerEntry; final int bytesPerEntry;
final IFixedDataHandler manager; final IFixedDataHandler manager;
Int2IntMap slots = new Int2IntOpenHashMap(); Int2IntMap slots = new Int2IntOpenHashMap();
IntArrayList slotData = new IntArrayList(); IntArrayList slotData = new IntArrayList();
IntSortedSet freeSlots = new IntAVLTreeSet(); IntSortedSet freeSlots = new IntAVLTreeSet();
IntSet changes = new IntLinkedOpenHashSet(); IntSet changes = new IntLinkedOpenHashSet();
public FixedDataManager(int bytesPerEntry, IFixedDataHandler manager) public FixedDataManager(int bytesPerEntry, IFixedDataHandler manager)
{ {
this.bytesPerEntry = bytesPerEntry; this.bytesPerEntry = bytesPerEntry;
this.manager = manager; this.manager = manager;
slots.setDefaultReturnValue(-1); slots.setDefaultReturnValue(-1);
} }
public boolean add(int dataIndex) public boolean add(int dataIndex)
{ {
if(dataIndex == -1) if(dataIndex == -1)
{ {
throw new IllegalStateException("-1 isnt allowed to be a dataIndex"); throw new IllegalStateException("-1 isnt allowed to be a dataIndex");
} }
if(slots.containsKey(dataIndex)) if(slots.containsKey(dataIndex))
{ {
return false; return false;
} }
if(freeSlots.isEmpty()) if(freeSlots.isEmpty())
{ {
slots.put(dataIndex, slotData.size()); slots.put(dataIndex, slotData.size());
slotData.add(dataIndex); slotData.add(dataIndex);
changes.add(dataIndex); changes.add(dataIndex);
return true; return true;
} }
int slot = freeSlots.pollFirstInt(); int slot = freeSlots.pollFirstInt();
slots.put(dataIndex, slot); slots.put(dataIndex, slot);
slotData.set(slot, dataIndex); slotData.set(slot, dataIndex);
changes.add(dataIndex); changes.add(dataIndex);
return true; return true;
} }
public void addAll(IntCollection indexes) public void addAll(IntCollection indexes)
{ {
for(int index : indexes) for(int index : indexes)
{ {
add(index); add(index);
} }
} }
public boolean contains(int dataIndex) public boolean contains(int dataIndex)
{ {
return slots.containsKey(dataIndex); return slots.containsKey(dataIndex);
} }
public boolean update(int dataIndex) public boolean update(int dataIndex)
{ {
if(slots.containsKey(dataIndex)) if(slots.containsKey(dataIndex))
{ {
changes.add(dataIndex); changes.add(dataIndex);
return true; return true;
} }
return false; return false;
} }
public void updateAll(IntCollection indexes) public void updateAll(IntCollection indexes)
{ {
for(int index : indexes) for(int index : indexes)
{ {
if(slots.containsKey(index)) if(slots.containsKey(index))
{ {
changes.add(index); changes.add(index);
} }
} }
} }
public boolean remove(int dataIndex) public boolean remove(int dataIndex)
{ {
int slot = slots.remove(dataIndex); int slot = slots.remove(dataIndex);
if(slot >= 0 && slot < slotData.size()) if(slot >= 0 && slot < slotData.size())
{ {
slotData.set(slot, -1); slotData.set(slot, -1);
freeSlots.add(slot); freeSlots.add(slot);
changes.remove(dataIndex); changes.remove(dataIndex);
return true; return true;
} }
return false; return false;
} }
public void removeAll(IntCollection indexes) public void removeAll(IntCollection indexes)
{ {
for(int index : indexes) for(int index : indexes)
{ {
remove(index); remove(index);
} }
} }
public void clear() public void clear()
{ {
changes.clear(); changes.clear();
slots.clear(); slots.clear();
freeSlots.clear(); freeSlots.clear();
slotData.clear(); slotData.clear();
} }
public void reload(boolean now) public void reload(boolean now)
{ {
if(slots.isEmpty()) if(slots.isEmpty())
{ {
return; return;
} }
changes.addAll(slots.keySet()); changes.addAll(slots.keySet());
if(now) if(now)
{ {
updateNow(); updateNow();
} }
} }
public int size() public int size()
{ {
return slots.size(); return slots.size();
} }
public IntIterator valueIterator() public IntIterator valueIterator()
{ {
return slotData.iterator(); return slotData.iterator();
} }
public void copy(FixedDataManager manager) public void copy(FixedDataManager manager)
{ {
IntList list = manager.slotData; IntList list = manager.slotData;
for(int i = 0,m=list.size();i<m;i++) for(int i = 0,m=list.size();i<m;i++)
{ {
int data = list.getInt(i); int data = list.getInt(i);
if(data == -1) if(data == -1)
{ {
continue; continue;
} }
add(data); add(data);
} }
} }
public boolean sort(IntComparator comparator) public boolean sort(IntComparator comparator)
{ {
clearEmptySlots(); clearEmptySlots();
if(slotData.isEmpty()) if(slotData.isEmpty())
{ {
return false; return false;
} }
int[] oldData = slotData.toIntArray(); int[] oldData = slotData.toIntArray();
slotData.sort(comparator); slotData.sort(comparator);
int[] newData = slotData.elements(); int[] newData = slotData.elements();
boolean changed = false; boolean changed = false;
for(int i = 0,m=slotData.size();i<m;i++) for(int i = 0,m=slotData.size();i<m;i++)
{ {
if(oldData[i] != newData[i]) if(oldData[i] != newData[i])
{ {
changes.add(newData[i]); changes.add(newData[i]);
slots.put(newData[i], i); slots.put(newData[i], i);
changed = true; changed = true;
} }
} }
return changed; return changed;
} }
public void updateNow() public void updateNow()
{ {
try try
{ {
Callable<Runnable> call = update(); Callable<Runnable> call = update();
if(call != null) if(call != null)
{ {
call.call().run(); call.call().run();
} }
} }
catch(Exception e){} catch(Exception e){}
} }
public Callable<Runnable> update() public Callable<Runnable> update()
{ {
int lastSize = slotData.size(); int lastSize = slotData.size();
clearEmptySlots(); clearEmptySlots();
if(changes.isEmpty()) if(changes.isEmpty())
{ {
if(slotData.size() != lastSize) if(slotData.size() != lastSize)
{ {
return new ShrinkTask(new FinishingTask(manager, ObjectLists.empty(), size())); return new ShrinkTask(new FinishingTask(manager, ObjectLists.empty(), size()));
} }
return null; return null;
} }
FixedSlot[] slots = SLOTS.get(new FixedSlot[changes.size()]); FixedSlot[] slots = SLOTS.get(new FixedSlot[changes.size()]);
int index = 0; int index = 0;
for(int dataIndex : changes) for(int dataIndex : changes)
{ {
slots[index++].set(dataIndex, this.slots.get(dataIndex)); slots[index++].set(dataIndex, this.slots.get(dataIndex));
} }
changes.clear(); changes.clear();
return new ProcessTask(slots, size(), bytesPerEntry, manager); return new ProcessTask(slots, size(), bytesPerEntry, manager);
} }
protected void clearEmptySlots() protected void clearEmptySlots()
{ {
if(freeSlots.isEmpty()) if(freeSlots.isEmpty())
{ {
return; return;
} }
if(slots.isEmpty()) if(slots.isEmpty())
{ {
freeSlots.clear(); freeSlots.clear();
slotData.clear(); slotData.clear();
changes.clear(); changes.clear();
return; return;
} }
int size = freeSlots.size(); int size = freeSlots.size();
while(size > 0) while(size > 0)
{ {
size -= ensureData(); size -= ensureData();
if(slotData.isEmpty() || freeSlots.isEmpty()) if(slotData.isEmpty() || freeSlots.isEmpty())
{ {
break; break;
} }
int index = freeSlots.pollFirstInt(); int index = freeSlots.pollFirstInt();
int dataIndex = slotData.pop(); int dataIndex = slotData.pop();
slotData.set(index, dataIndex); slotData.set(index, dataIndex);
slots.put(dataIndex, index); slots.put(dataIndex, index);
changes.add(dataIndex); changes.add(dataIndex);
} }
} }
protected int ensureData() protected int ensureData()
{ {
int cleared = 0; int cleared = 0;
while(slotData.top() == -1) while(slotData.top() == -1)
{ {
freeSlots.remove(slotData.size() - 1); freeSlots.remove(slotData.size() - 1);
slotData.pop(); slotData.pop();
cleared++; cleared++;
} }
return cleared; return cleared;
} }
static class ProcessTask implements Callable<Runnable> static class ProcessTask implements Callable<Runnable>
{ {
FixedSlot[] slots; FixedSlot[] slots;
int size; int size;
int bytes; int bytes;
IFixedDataHandler handler; IFixedDataHandler handler;
public ProcessTask(FixedSlot[] slots, int size, int bytes, IFixedDataHandler handler) public ProcessTask(FixedSlot[] slots, int size, int bytes, IFixedDataHandler handler)
{ {
this.slots = slots; this.slots = slots;
this.size = size; this.size = size;
this.bytes = bytes; this.bytes = bytes;
this.handler = handler; this.handler = handler;
} }
@Override @Override
public Runnable call() public Runnable call()
{ {
ObjectArrays.quickSort(slots); ObjectArrays.quickSort(slots);
List<FixedSlot> fixed = new ObjectArrayList<FixedSlot>(); List<FixedSlot> fixed = new ObjectArrayList<FixedSlot>();
List<IntObjectPair<byte[]>> data = new ObjectArrayList<>(); List<IntObjectPair<byte[]>> data = new ObjectArrayList<>();
FixedSlot first = null; FixedSlot first = null;
FixedSlot last = null; FixedSlot last = null;
for(int i = 0,m=slots.length;i<m;i++) for(int i = 0,m=slots.length;i<m;i++)
{ {
if(first == null) if(first == null)
{ {
first = last = slots[i]; first = last = slots[i];
fixed.add(first); fixed.add(first);
continue; continue;
} }
if(last.isNext(slots[i])) if(last != null && last.isNext(slots[i]))
{ {
last = slots[i]; last = slots[i];
fixed.add(last); fixed.add(last);
continue; continue;
} }
ByteBuffer buffer = ByteBuffer.allocate(fixed.size() * bytes).order(ByteOrder.nativeOrder()); ByteBuffer buffer = ByteBuffer.allocate(fixed.size() * bytes).order(ByteOrder.nativeOrder());
handler.createData(buffer, fixed.size(), fixed); handler.createData(buffer, fixed.size(), fixed);
fixed.clear(); fixed.clear();
data.add(IntObjectPair.of(first.index * bytes, buffer.array())); data.add(IntObjectPair.of(first.index * bytes, buffer.array()));
i--; i--;
first = last = null; first = last = null;
} }
if(first != null) if(first != null)
{ {
ByteBuffer buffer = ByteBuffer.allocate(fixed.size() * bytes).order(ByteOrder.nativeOrder()); ByteBuffer buffer = ByteBuffer.allocate(fixed.size() * bytes).order(ByteOrder.nativeOrder());
handler.createData(buffer, fixed.size(), fixed); handler.createData(buffer, fixed.size(), fixed);
fixed.clear(); fixed.clear();
data.add(IntObjectPair.of(first.index * bytes, buffer.array())); data.add(IntObjectPair.of(first.index * bytes, buffer.array()));
} }
SLOTS.accept(slots); SLOTS.accept(slots);
return new FinishingTask(handler, data, size); return new FinishingTask(handler, data, size);
} }
} }
static class ShrinkTask implements Callable<Runnable> static class ShrinkTask implements Callable<Runnable>
{ {
Runnable run; Runnable run;
public ShrinkTask(Runnable run) public ShrinkTask(Runnable run)
{ {
this.run = run; this.run = run;
} }
@Override @Override
public Runnable call() throws Exception public Runnable call() throws Exception
{ {
return run; return run;
} }
} }
static class FinishingTask implements Runnable static class FinishingTask implements Runnable
{ {
IFixedDataHandler handler; IFixedDataHandler handler;
List<IntObjectPair<byte[]>> data; List<IntObjectPair<byte[]>> data;
int size; int size;
public FinishingTask(IFixedDataHandler handler, List<IntObjectPair<byte[]>> data, int size) public FinishingTask(IFixedDataHandler handler, List<IntObjectPair<byte[]>> data, int size)
{ {
this.handler = handler; this.handler = handler;
this.data = data; this.data = data;
this.size = size; this.size = size;
} }
@Override @Override
public void run() public void run()
{ {
handler.updateData(data, size); handler.updateData(data, size);
} }
} }
} }