/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2007 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package javolution.context;
/**
* <p> This class holds factories to produces arrays of variable length.
* It allows for object recycling, pre-allocation and {@link StackContext
* stack} allocations:[code]
* // Primitive types.
* char[] buffer = ArrayFactory.CHARS_FACTORY.array(1024); // Possibly recycled.
* for (int i = reader.read(buffer, 0, buffer.length); i > 0;) {
* ...
* }
* ArrayFactory.CHARS_FACTORY.recycle(buffer); //
*
* // Custom types.
* static ArrayFactory<Vertex[]> VERTICES_FACTORY = new ArrayFactory<Vertex[]> {
* protected Vertex[] create(int size) {
* return new Vertex[size];
* }
* };
* ...
* Vertex[] vertices = VERTICES_FACTORY.array(256);
* [/code]</p>
*
* @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
* @version 5.0, May 5, 2007
*/
public abstract class ArrayFactory <T> {
/**
* Holds factory for <code>boolean</code> arrays.
*/
public static final ArrayFactory <boolean[]> BOOLEANS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new boolean[size];
}
public void recycle(Object array) {
recycle(array, ((boolean[]) array).length);
}
};
/**
* Holds factory for <code>byte</code> arrays.
*/
public static final ArrayFactory <byte[]> BYTES_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new byte[size];
}
public void recycle(Object array) {
recycle(array, ((byte[]) array).length);
}
};
/**
* Holds factory for <code>char</code> arrays.
*/
public static final ArrayFactory <char[]> CHARS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new char[size];
}
public void recycle(Object array) {
recycle(array, ((char[]) array).length);
}
};
/**
* Holds factory for <code>short</code> arrays.
*/
public static final ArrayFactory <short[]> SHORTS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new short[size];
}
public void recycle(Object array) {
recycle(array, ((short[]) array).length);
}
};
/**
* Holds factory for <code>int</code> arrays.
*/
public static final ArrayFactory <int[]> INTS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new int[size];
}
public void recycle(Object array) {
recycle(array, ((int[]) array).length);
}
};
/**
* Holds factory for <code>long</code> arrays.
*/
public static final ArrayFactory <long[]> LONGS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new long[size];
}
public void recycle(Object array) {
recycle(array, ((long[]) array).length);
}
};
/**
* Holds factory for <code>float</code> arrays.
*/
public static final ArrayFactory <float[]> FLOATS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new float[size];
}
public void recycle(Object array) {
recycle(array, ((float[]) array).length);
}
};
/**
* Holds factory for <code>double</code> arrays.
*/
public static final ArrayFactory <double[]> DOUBLES_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new double[size];
}
public void recycle(Object array) {
recycle(array, ((double[]) array).length);
}
};
/**
* Holds factory for generic <code>Object</code> arrays.
*/
public static final ArrayFactory <Object[]> OBJECTS_FACTORY = new ArrayFactory() {
protected Object create(int size) {
return new Object[size];
}
public void recycle(Object array) {
recycle(array, ((Object[]) array).length);
}
};
/**
* Holds factory for arrays up to size 4.
*/
private final ObjectFactory _factory4 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(4);
}
};
/**
* Holds factory for arrays up to size 8.
*/
private final ObjectFactory _factory8 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(8);
}
};
/**
* Holds factory for arrays up to size 16.
*/
private final ObjectFactory _factory16 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(16);
}
};
/**
* Holds factory for arrays up to size 32.
*/
private final ObjectFactory _factory32 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(32);
}
};
/**
* Holds factory for arrays up to size 64.
*/
private final ObjectFactory _factory64 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(64);
}
};
/**
* Holds factory for arrays up to size 128.
*/
private final ObjectFactory _factory128 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(128);
}
};
/**
* Holds factory for arrays up to size 256.
*/
private final ObjectFactory _factory256 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(256);
}
};
/**
* Holds factory for arrays up to size 512.
*/
private final ObjectFactory _factory512 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(512);
}
};
/**
* Holds factory for arrays up to size 1024.
*/
private final ObjectFactory _factory1024 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(1024);
}
};
/**
* Holds factory for arrays up to size 2048.
*/
private final ObjectFactory _factory2048 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(2048);
}
};
/**
* Holds factory for arrays up to size 4096.
*/
private final ObjectFactory _factory4096 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(4096);
}
};
/**
* Holds factory for arrays up to size 8192.
*/
private final ObjectFactory _factory8192 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(8192);
}
};
/**
* Holds factory for arrays up to size 16384.
*/
private final ObjectFactory _factory16384 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(16384);
}
};
/**
* Holds factory for arrays up to size 32768.
*/
private final ObjectFactory _factory32768 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(32768);
}
};
/**
* Holds factory for arrays up to size 65536.
*/
private final ObjectFactory _factory65536 = new ObjectFactory() {
protected Object create() {
return ArrayFactory.this.create(65536);
}
};
// Above 65536 we use the heap exclusively.
/**
* Default constructor.
*/
public ArrayFactory() {
}
/**
* Returns an array possibly recycled or preallocated of specified
* minimum size.
*
* @param capacity the minimum size of the array to be returned.
* @return a recycled, pre-allocated or new factory array.
*/
public final T array(int capacity) { // Short to be inlined.
return (capacity <= 4) ? ( T ) _factory4.object()
: largeArray(capacity);
}
private final T largeArray(int capacity) {
if (capacity <= 8) {
return ( T ) _factory8.object();
} else if (capacity <= 16) {
return ( T ) _factory16.object();
} else if (capacity <= 32) {
return ( T ) _factory32.object();
} else if (capacity <= 64) {
return ( T ) _factory64.object();
} else if (capacity <= 128) {
return ( T ) _factory128.object();
} else if (capacity <= 256) {
return ( T ) _factory256.object();
} else if (capacity <= 512) {
return ( T ) _factory512.object();
} else if (capacity <= 1024) {
return ( T ) _factory1024.object();
} else if (capacity <= 2048) {
return ( T ) _factory2048.object();
} else if (capacity <= 4096) {
return ( T ) _factory4096.object();
} else if (capacity <= 8192) {
return ( T ) _factory8192.object();
} else if (capacity <= 16384) {
return ( T ) _factory16384.object();
} else if (capacity <= 32768) {
return ( T ) _factory32768.object();
} else if (capacity <= 65536) {
return ( T ) _factory65536.object();
} else {
return create(capacity); // Default allocation for very large arrays.
}
}
/**
* Recycles the specified arrays.
*
* @param array the array to be recycled.
*/
public void recycle( T array) { // Short to be inlined.
int length = ((Object[]) array).length;
if (length <= 4) {
_factory4.recycle(array);
} else {
recycle(array, length);
}
}
final void recycle(Object array, int length) {
if (length <= 8) {
_factory8.recycle(array);
} else if (length <= 16) {
_factory16.recycle(array);
} else if (length <= 32) {
_factory32.recycle(array);
} else if (length <= 64) {
_factory64.recycle(array);
} else if (length <= 128) {
_factory128.recycle(array);
} else if (length <= 256) {
_factory256.recycle(array);
} else if (length <= 512) {
_factory512.recycle(array);
} else if (length <= 1024) {
_factory1024.recycle(array);
} else if (length <= 2048) {
_factory2048.recycle(array);
} else if (length <= 4096) {
_factory4096.recycle(array);
} else if (length <= 8192) {
_factory8192.recycle(array);
} else if (length <= 16384) {
_factory16384.recycle(array);
} else if (length <= 32768) {
_factory32768.recycle(array);
} else if (length <= 65536) {
_factory65536.recycle(array);
}
}
/**
* Constructs a new array of specified size from this factory
* (using the <code>new</code> keyword).
*
* @param size the size of the array.
* @return a new factory array.
*/
protected abstract T create(int size);
}