Speed up table.sort.
This commit is contained in:
@@ -25,23 +25,23 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass of {@link LuaValue} for representing lua tables.
|
* Subclass of {@link LuaValue} for representing lua tables.
|
||||||
* <p>
|
* <p>
|
||||||
* Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}.
|
* Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}.
|
||||||
* <p>
|
* <p>
|
||||||
* If a table is needed, the one of the type-checking functions can be used such as
|
* If a table is needed, the one of the type-checking functions can be used such as
|
||||||
* {@link #istable()},
|
* {@link #istable()},
|
||||||
* {@link #checktable()}, or
|
* {@link #checktable()}, or
|
||||||
* {@link #opttable(LuaTable)}
|
* {@link #opttable(LuaTable)}
|
||||||
* <p>
|
* <p>
|
||||||
* The main table operations are defined on {@link LuaValue}
|
* The main table operations are defined on {@link LuaValue}
|
||||||
* for getting and setting values with and without metatag processing:
|
* for getting and setting values with and without metatag processing:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link #get(LuaValue)}</li>
|
* <li>{@link #get(LuaValue)}</li>
|
||||||
* <li>{@link #set(LuaValue,LuaValue)}</li>
|
* <li>{@link #set(LuaValue,LuaValue)}</li>
|
||||||
* <li>{@link #rawget(LuaValue)}</li>
|
* <li>{@link #rawget(LuaValue)}</li>
|
||||||
* <li>{@link #rawset(LuaValue,LuaValue)}</li>
|
* <li>{@link #rawset(LuaValue,LuaValue)}</li>
|
||||||
* <li>plus overloads such as {@link #get(String)}, {@link #get(int)}, and so on</li>
|
* <li>plus overloads such as {@link #get(String)}, {@link #get(int)}, and so on</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* To iterate over key-value pairs from Java, use
|
* To iterate over key-value pairs from Java, use
|
||||||
@@ -56,7 +56,7 @@ import java.util.Vector;
|
|||||||
* }}</pre>
|
* }}</pre>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* As with other types, {@link LuaTable} instances should be constructed via one of the table constructor
|
* As with other types, {@link LuaTable} instances should be constructed via one of the table constructor
|
||||||
* methods on {@link LuaValue}:
|
* methods on {@link LuaValue}:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link LuaValue#tableOf()} empty table</li>
|
* <li>{@link LuaValue#tableOf()} empty table</li>
|
||||||
@@ -92,7 +92,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
hash = NOBUCKETS;
|
hash = NOBUCKETS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct table with preset capacity.
|
* Construct table with preset capacity.
|
||||||
* @param narray capacity of array part
|
* @param narray capacity of array part
|
||||||
* @param nhash capacity of hash part
|
* @param nhash capacity of hash part
|
||||||
@@ -102,9 +102,9 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct table with named and unnamed parts.
|
* Construct table with named and unnamed parts.
|
||||||
* @param named Named elements in order {@code key-a, value-a, key-b, value-b, ... }
|
* @param named Named elements in order {@code key-a, value-a, key-b, value-b, ... }
|
||||||
* @param unnamed Unnamed elements in order {@code value-1, value-2, ... }
|
* @param unnamed Unnamed elements in order {@code value-1, value-2, ... }
|
||||||
* @param lastarg Additional unnamed values beyond {@code unnamed.length}
|
* @param lastarg Additional unnamed values beyond {@code unnamed.length}
|
||||||
*/
|
*/
|
||||||
public LuaTable(LuaValue[] named, LuaValue[] unnamed, Varargs lastarg) {
|
public LuaTable(LuaValue[] named, LuaValue[] unnamed, Varargs lastarg) {
|
||||||
@@ -123,17 +123,17 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct table of unnamed elements.
|
* Construct table of unnamed elements.
|
||||||
* @param varargs Unnamed elements in order {@code value-1, value-2, ... }
|
* @param varargs Unnamed elements in order {@code value-1, value-2, ... }
|
||||||
*/
|
*/
|
||||||
public LuaTable(Varargs varargs) {
|
public LuaTable(Varargs varargs) {
|
||||||
this(varargs,1);
|
this(varargs,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct table of unnamed elements.
|
* Construct table of unnamed elements.
|
||||||
* @param varargs Unnamed elements in order {@code value-1, value-2, ... }
|
* @param varargs Unnamed elements in order {@code value-1, value-2, ... }
|
||||||
* @param firstarg the index in varargs of the first argument to include in the table
|
* @param firstarg the index in varargs of the first argument to include in the table
|
||||||
*/
|
*/
|
||||||
public LuaTable(Varargs varargs, int firstarg) {
|
public LuaTable(Varargs varargs, int firstarg) {
|
||||||
int nskip = firstarg-1;
|
int nskip = firstarg-1;
|
||||||
@@ -152,8 +152,8 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
return "table";
|
return "table";
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean istable() {
|
public boolean istable() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaTable checktable() {
|
public LuaTable checktable() {
|
||||||
@@ -185,17 +185,17 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the length of the array part of the table.
|
* Get the length of the array part of the table.
|
||||||
* @return length of the array part, does not relate to count of objects in the table.
|
* @return length of the array part, does not relate to count of objects in the table.
|
||||||
*/
|
*/
|
||||||
protected int getArrayLength() {
|
protected int getArrayLength() {
|
||||||
return array.length;
|
return array.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the length of the hash part of the table.
|
* Get the length of the hash part of the table.
|
||||||
* @return length of the hash part, does not relate to count of objects in the table.
|
* @return length of the hash part, does not relate to count of objects in the table.
|
||||||
*/
|
*/
|
||||||
protected int getHashLength() {
|
protected int getHashLength() {
|
||||||
return hash.length;
|
return hash.length;
|
||||||
@@ -294,7 +294,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Remove the element at a position in a list-table
|
/** Remove the element at a position in a list-table
|
||||||
*
|
*
|
||||||
* @param pos the position to remove
|
* @param pos the position to remove
|
||||||
* @return The removed item, or {@link #NONE} if not removed
|
* @return The removed item, or {@link #NONE} if not removed
|
||||||
*/
|
*/
|
||||||
@@ -313,7 +313,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Insert an element at a position in a list-table
|
/** Insert an element at a position in a list-table
|
||||||
*
|
*
|
||||||
* @param pos the position to remove
|
* @param pos the position to remove
|
||||||
* @param value The value to insert
|
* @param value The value to insert
|
||||||
*/
|
*/
|
||||||
@@ -355,14 +355,14 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
return rawlen();
|
return rawlen();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaValue len() {
|
public LuaValue len() {
|
||||||
final LuaValue h = metatag(LEN);
|
final LuaValue h = metatag(LEN);
|
||||||
if (h.toboolean())
|
if (h.toboolean())
|
||||||
return h.call(this);
|
return h.call(this);
|
||||||
return LuaInteger.valueOf(rawlen());
|
return LuaInteger.valueOf(rawlen());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int rawlen() {
|
public int rawlen() {
|
||||||
int a = getArrayLength();
|
int a = getArrayLength();
|
||||||
int n = a+1,m=0;
|
int n = a+1,m=0;
|
||||||
while ( !rawget(n).isnil() ) {
|
while ( !rawget(n).isnil() ) {
|
||||||
@@ -380,7 +380,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next element after a particular key in the table
|
* Get the next element after a particular key in the table
|
||||||
* @return key,value or nil
|
* @return key,value or nil
|
||||||
*/
|
*/
|
||||||
public Varargs next( LuaValue key ) {
|
public Varargs next( LuaValue key ) {
|
||||||
@@ -441,8 +441,8 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next element after a particular key in the
|
* Get the next element after a particular key in the
|
||||||
* contiguous array part of a table
|
* contiguous array part of a table
|
||||||
* @return key,value or none
|
* @return key,value or none
|
||||||
*/
|
*/
|
||||||
public Varargs inext(LuaValue key) {
|
public Varargs inext(LuaValue key) {
|
||||||
@@ -517,7 +517,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the hashtable slot to use
|
* Find the hashtable slot to use
|
||||||
* @param key key to look for
|
* @param key key to look for
|
||||||
* @return slot to use
|
* @return slot to use
|
||||||
@@ -779,7 +779,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
//
|
//
|
||||||
// implemented heap sort from wikipedia
|
// implemented heap sort from wikipedia
|
||||||
//
|
//
|
||||||
// Only sorts the contiguous array part.
|
// Only sorts the contiguous array part.
|
||||||
//
|
//
|
||||||
/** Sort the table using a comparator.
|
/** Sort the table using a comparator.
|
||||||
* @param comparator {@link LuaValue} to be called to compare elements.
|
* @param comparator {@link LuaValue} to be called to compare elements.
|
||||||
@@ -789,17 +789,21 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
if (m_metatable != null && m_metatable.useWeakValues()) {
|
if (m_metatable != null && m_metatable.useWeakValues()) {
|
||||||
dropWeakArrayValues();
|
dropWeakArrayValues();
|
||||||
}
|
}
|
||||||
|
LuaValue[] array = this.array;
|
||||||
int n = array.length;
|
int n = array.length;
|
||||||
while ( n > 0 && array[n-1] == null )
|
while ( n > 0 && array[n-1] == null )
|
||||||
--n;
|
--n;
|
||||||
if ( n > 1 )
|
if ( n > 1 )
|
||||||
heapSort(n, comparator);
|
heapSort(n, comparator.isnil() ? null : comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void heapSort(int count, LuaValue cmpfunc) {
|
private void heapSort(int count, LuaValue cmpfunc) {
|
||||||
heapify(count, cmpfunc);
|
heapify(count, cmpfunc);
|
||||||
|
LuaValue[] array = this.array;
|
||||||
for ( int end=count-1; end>0; ) {
|
for ( int end=count-1; end>0; ) {
|
||||||
swap(end, 0);
|
LuaValue a = array[end]; // swap(end, 0)
|
||||||
|
array[end] = array[0];
|
||||||
|
array[0] = a;
|
||||||
siftDown(0, --end, cmpfunc);
|
siftDown(0, --end, cmpfunc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -810,12 +814,15 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void siftDown(int start, int end, LuaValue cmpfunc) {
|
private void siftDown(int start, int end, LuaValue cmpfunc) {
|
||||||
for ( int root=start; root*2+1 <= end; ) {
|
LuaValue[] array = this.array;
|
||||||
int child = root*2+1;
|
for ( int root=start; root*2+1 <= end; ) {
|
||||||
|
int child = root*2+1;
|
||||||
if (child < end && compare(child, child + 1, cmpfunc))
|
if (child < end && compare(child, child + 1, cmpfunc))
|
||||||
++child;
|
++child;
|
||||||
if (compare(root, child, cmpfunc)) {
|
if (compare(root, child, cmpfunc)) {
|
||||||
swap(root, child);
|
LuaValue a = array[root]; // swap(root, child)
|
||||||
|
array[root] = array[child];
|
||||||
|
array[child] = a;
|
||||||
root = child;
|
root = child;
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
@@ -824,6 +831,8 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
|
|
||||||
private boolean compare(int i, int j, LuaValue cmpfunc) {
|
private boolean compare(int i, int j, LuaValue cmpfunc) {
|
||||||
LuaValue a, b;
|
LuaValue a, b;
|
||||||
|
LuaValue[] array = this.array;
|
||||||
|
Metatable m_metatable = this.m_metatable;
|
||||||
if (m_metatable == null) {
|
if (m_metatable == null) {
|
||||||
a = array[i];
|
a = array[i];
|
||||||
b = array[j];
|
b = array[j];
|
||||||
@@ -833,22 +842,16 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
if ( a == null || b == null )
|
if ( a == null || b == null )
|
||||||
return false;
|
return false;
|
||||||
if ( ! cmpfunc.isnil() ) {
|
if ( cmpfunc != null ) {
|
||||||
return cmpfunc.call(a,b).toboolean();
|
return cmpfunc.call(a,b).toboolean();
|
||||||
} else {
|
} else {
|
||||||
return a.lt_b(b);
|
return a.lt_b(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void swap(int i, int j) {
|
/** This may be deprecated in a future release.
|
||||||
LuaValue a = array[i];
|
|
||||||
array[i] = array[j];
|
|
||||||
array[j] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This may be deprecated in a future release.
|
|
||||||
* It is recommended to count via iteration over next() instead
|
* It is recommended to count via iteration over next() instead
|
||||||
* @return count of keys in the table
|
* @return count of keys in the table
|
||||||
* */
|
* */
|
||||||
public int keyCount() {
|
public int keyCount() {
|
||||||
LuaValue k = LuaValue.NIL;
|
LuaValue k = LuaValue.NIL;
|
||||||
@@ -859,9 +862,9 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This may be deprecated in a future release.
|
/** This may be deprecated in a future release.
|
||||||
* It is recommended to use next() instead
|
* It is recommended to use next() instead
|
||||||
* @return array of keys in the table
|
* @return array of keys in the table
|
||||||
* */
|
* */
|
||||||
public LuaValue[] keys() {
|
public LuaValue[] keys() {
|
||||||
Vector l = new Vector();
|
Vector l = new Vector();
|
||||||
|
|||||||
Reference in New Issue
Block a user