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