|
|
|
@ -173,6 +173,16 @@ public class kelondroRowCollection {
|
|
|
|
|
return this.rowdef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private final void ensureSize(int elements) {
|
|
|
|
|
int needed = elements * rowdef.objectsize();
|
|
|
|
|
if (chunkcache.length >= needed) return;
|
|
|
|
|
byte[] newChunkcache = new byte[(int) (needed * growfactor)]; // increase space
|
|
|
|
|
System.arraycopy(chunkcache, 0, newChunkcache, 0, chunkcache.length);
|
|
|
|
|
chunkcache = newChunkcache;
|
|
|
|
|
newChunkcache = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
private static final Object[] arraydepot = new Object[]{new byte[0]};
|
|
|
|
|
|
|
|
|
|
private final void ensureSize(int elements) {
|
|
|
|
@ -233,68 +243,8 @@ public class kelondroRowCollection {
|
|
|
|
|
newChunkcache = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
private static final Object[] arraydepot = new Object[]{new byte[0]};
|
|
|
|
|
|
|
|
|
|
private final void ensureSize(int elements) {
|
|
|
|
|
int needed = elements * rowdef.objectsize();
|
|
|
|
|
if (chunkcache.length >= needed) return;
|
|
|
|
|
long neededRAM = (long) (needed * growfactor);
|
|
|
|
|
long availableRAM = serverMemory.available();
|
|
|
|
|
//if ((safemode) && (neededRAM > availableRAM)) throw new kelondroMemoryProtectionException("rowCollection temporary chunkcache", neededRAM, availableRAM);
|
|
|
|
|
|
|
|
|
|
if (neededRAM > availableRAM) {
|
|
|
|
|
// go into safe mode: use the arraydepot
|
|
|
|
|
synchronized (arraydepot) {
|
|
|
|
|
if (((byte[]) arraydepot[0]).length >= neededRAM) {
|
|
|
|
|
System.out.println("ensureSize case 1");
|
|
|
|
|
// use the depot to increase the chunkcache
|
|
|
|
|
byte[] newChunkcache = (byte[]) arraydepot[0];
|
|
|
|
|
System.arraycopy(chunkcache, 0, newChunkcache, 0, chunkcache.length);
|
|
|
|
|
// safe the chunkcache for later use in arraydepot
|
|
|
|
|
arraydepot[0] = chunkcache;
|
|
|
|
|
chunkcache = newChunkcache;
|
|
|
|
|
newChunkcache = null;
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("ensureSize case 2");
|
|
|
|
|
// this is the critical part: we need more RAM.
|
|
|
|
|
// do a buffering using the arraydepot
|
|
|
|
|
byte[] buffer0 = (byte[]) arraydepot[0];
|
|
|
|
|
byte[] buffer1 = new byte[chunkcache.length - buffer0.length];
|
|
|
|
|
// first copy the previous chunkcache to the two buffers
|
|
|
|
|
System.arraycopy(chunkcache, 0, buffer0, 0, buffer0.length);
|
|
|
|
|
System.arraycopy(chunkcache, buffer0.length, buffer1, 0, buffer1.length);
|
|
|
|
|
// then free the previous chunkcache and replace it with a new array at target size
|
|
|
|
|
chunkcache = null; // hand this over to GC
|
|
|
|
|
chunkcache = new byte[(int) neededRAM];
|
|
|
|
|
System.arraycopy(buffer0, 0, chunkcache, 0, buffer0.length);
|
|
|
|
|
System.arraycopy(buffer1, 0, chunkcache, buffer0.length, buffer1.length);
|
|
|
|
|
// then move the bigger buffer into the arraydepot
|
|
|
|
|
if (buffer0.length > buffer1.length) {
|
|
|
|
|
arraydepot[0] = buffer0;
|
|
|
|
|
} else {
|
|
|
|
|
arraydepot[1] = buffer1;
|
|
|
|
|
}
|
|
|
|
|
buffer0 = null;
|
|
|
|
|
buffer1 = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// there is enough memory available
|
|
|
|
|
byte[] newChunkcache = new byte[(int) neededRAM]; // increase space
|
|
|
|
|
System.arraycopy(chunkcache, 0, newChunkcache, 0, chunkcache.length);
|
|
|
|
|
// safe the chunkcache for later use in arraydepot
|
|
|
|
|
synchronized (arraydepot) {
|
|
|
|
|
if (((byte[]) arraydepot[0]).length < chunkcache.length) {
|
|
|
|
|
System.out.println("ensureSize case 0");
|
|
|
|
|
arraydepot[0] = chunkcache;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
chunkcache = newChunkcache;
|
|
|
|
|
newChunkcache = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
public final long memoryNeededForGrow() {
|
|
|
|
|
return (long) ((((long) (chunkcount + 1)) * ((long) rowdef.objectsize())) * growfactor);
|
|
|
|
|
}
|
|
|
|
|