Refactor table implementation.

This commit is contained in:
Ian Farmer
2013-07-05 06:24:46 +00:00
parent 49fc8ec7ec
commit f3aeb69d30
11 changed files with 1387 additions and 432 deletions

View File

@@ -50,7 +50,7 @@ public class TableHashTest extends TestCase {
String[] keys = { "abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "wxy", "z01",
"cd", "ef", "g", "hi", "jk", "lm", "no", "pq", "rs", };
int[] capacities = { 0, 2, 4, 4, 7, 7, 7, 10, 10, 14, 14, 14, 14, 19, 19, 19, 19, 25, 25, 25 };
int[] capacities = { 0, 2, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32 };
for ( int i = 0; i < keys.length; ++i ) {
assertEquals( capacities[i], t.getHashLength() );
String si = "Test Value! "+i;
@@ -242,4 +242,79 @@ public class TableHashTest extends TestCase {
assertEquals( LuaValue.valueOf("bbb"), t.next(LuaValue.valueOf("aa")).arg(2) );
assertEquals( LuaValue.NIL, t.next(LuaValue.valueOf("bb")) );
}
public void testLoopWithRemoval() {
final LuaTable t = new_Table();
t.set( LuaValue.valueOf(1), LuaValue.valueOf("1") );
t.set( LuaValue.valueOf(3), LuaValue.valueOf("3") );
t.set( LuaValue.valueOf(8), LuaValue.valueOf("4") );
t.set( LuaValue.valueOf(17), LuaValue.valueOf("5") );
t.set( LuaValue.valueOf(26), LuaValue.valueOf("6") );
t.set( LuaValue.valueOf(35), LuaValue.valueOf("7") );
t.set( LuaValue.valueOf(42), LuaValue.valueOf("8") );
t.set( LuaValue.valueOf(60), LuaValue.valueOf("10") );
t.set( LuaValue.valueOf(63), LuaValue.valueOf("11") );
Varargs entry = t.next(LuaValue.NIL);
while ( !entry.isnil(1) ) {
LuaValue k = entry.arg1();
LuaValue v = entry.arg(2);
if ( ( k.toint() & 1 ) == 0 ) {
t.set( k, LuaValue.NIL );
}
entry = t.next(k);
}
int numEntries = 0;
entry = t.next(LuaValue.NIL);
while ( !entry.isnil(1) ) {
LuaValue k = entry.arg1();
// Only odd keys should remain
assertTrue( ( k.toint() & 1 ) == 1 );
numEntries++;
entry = t.next(k);
}
assertEquals( 5, numEntries );
}
public void testLoopWithRemovalAndSet() {
final LuaTable t = new_Table();
t.set( LuaValue.valueOf(1), LuaValue.valueOf("1") );
t.set( LuaValue.valueOf(3), LuaValue.valueOf("3") );
t.set( LuaValue.valueOf(8), LuaValue.valueOf("4") );
t.set( LuaValue.valueOf(17), LuaValue.valueOf("5") );
t.set( LuaValue.valueOf(26), LuaValue.valueOf("6") );
t.set( LuaValue.valueOf(35), LuaValue.valueOf("7") );
t.set( LuaValue.valueOf(42), LuaValue.valueOf("8") );
t.set( LuaValue.valueOf(60), LuaValue.valueOf("10") );
t.set( LuaValue.valueOf(63), LuaValue.valueOf("11") );
Varargs entry = t.next(LuaValue.NIL);
Varargs entry2 = entry;
while ( !entry.isnil(1) ) {
LuaValue k = entry.arg1();
LuaValue v = entry.arg(2);
if ( ( k.toint() & 1 ) == 0 ) {
t.set( k, LuaValue.NIL );
} else {
t.set( k, v.tonumber() );
entry2 = t.next(entry2.arg1());
}
entry = t.next(k);
}
int numEntries = 0;
entry = t.next(LuaValue.NIL);
while ( !entry.isnil(1) ) {
LuaValue k = entry.arg1();
// Only odd keys should remain
assertTrue( ( k.toint() & 1 ) == 1 );
assertTrue( entry.arg(2).type() == LuaValue.TNUMBER );
numEntries++;
entry = t.next(k);
}
assertEquals( 5, numEntries );
}
}

View File

@@ -37,7 +37,7 @@ public class TableTest extends TestCase {
}
private int keyCount(LuaTable t) {
return keys(t).length;
return keys(t).length;
}
private LuaValue[] keys(LuaTable t) {
@@ -88,8 +88,9 @@ public class TableTest extends TestCase {
assertEquals(LuaInteger.valueOf(i), t.get(i));
}
assertTrue( t.getArrayLength() >= 0 && t.getArrayLength() <= 2 );
assertTrue( t.getHashLength() >= 4 );
assertTrue( t.getArrayLength() >= 3 );
assertTrue( t.getArrayLength() <= 12 );
assertTrue( t.getHashLength() <= 3 );
}
public void testOutOfOrderIntegerKeyInsertion() {
@@ -105,12 +106,8 @@ public class TableTest extends TestCase {
}
// Ensure capacities make sense
assertTrue( t.getArrayLength() >= 0 );
assertTrue( t.getArrayLength() <= 6 );
assertTrue( t.getHashLength() >= 16 );
assertTrue( t.getHashLength() <= 64 );
assertEquals( 32, t.getArrayLength() );
assertEquals( 0, t.getHashLength() );
}
public void testStringAndIntegerKeys() {
@@ -122,8 +119,8 @@ public class TableTest extends TestCase {
t.set( str, LuaInteger.valueOf( i ) );
}
assertTrue( t.getArrayLength() >= 9 ); // 1, 2, ..., 9
assertTrue( t.getArrayLength() <= 18 );
assertTrue( t.getArrayLength() >= 8 ); // 1, 2, ..., 9
assertTrue( t.getArrayLength() <= 16 );
assertTrue( t.getHashLength() >= 11 ); // 0, "0", "1", ..., "9"
assertTrue( t.getHashLength() <= 33 );
@@ -222,6 +219,41 @@ public class TableTest extends TestCase {
assertEquals( 0, keyCount(t) );
}
public void testShrinkNonPowerOfTwoArray() {
LuaTable t = new_Table(6, 2);
t.set(1, "one");
t.set(2, "two");
t.set(3, "three");
t.set(4, "four");
t.set(5, "five");
t.set(6, "six");
t.set("aa", "aaa");
t.set("bb", "bbb");
t.set(3, LuaValue.NIL);
t.set(4, LuaValue.NIL);
t.set(6, LuaValue.NIL);
t.set("cc", "ccc");
t.set("dd", "ddd");
assertEquals(4, t.getArrayLength());
assertTrue(t.getHashLength() < 10);
assertEquals(5, t.hashEntries);
assertEquals("one", t.get(1).tojstring());
assertEquals("two", t.get(2).tojstring());
assertEquals(LuaValue.NIL, t.get(3));
assertEquals(LuaValue.NIL, t.get(4));
assertEquals("five", t.get(5).tojstring());
assertEquals(LuaValue.NIL, t.get(6));
assertEquals("aaa", t.get("aa").tojstring());
assertEquals("bbb", t.get("bb").tojstring());
assertEquals("ccc", t.get("cc").tojstring());
assertEquals("ddd", t.get("dd").tojstring());
}
public void testInOrderLuaLength() {
LuaTable t = new_Table();
@@ -350,5 +382,4 @@ public class TableTest extends TestCase {
compareLists(t,v);
}
}
}

View File

@@ -55,8 +55,8 @@ abstract public class WeakTableTest extends TableTest {
}
public static class WeakValueTableTest extends WeakTableTest {
protected LuaTable new_Table() { return new WeakTable(false, true); }
protected LuaTable new_Table(int n,int m) { return new WeakTable(false, true); }
protected LuaTable new_Table() { return WeakTable.make(false, true); }
protected LuaTable new_Table(int n,int m) { return WeakTable.make(false, true); }
public void testWeakValuesTable() {
LuaTable t = new_Table();
@@ -64,17 +64,21 @@ abstract public class WeakTableTest extends TableTest {
Object obj = new Object();
LuaTable tableValue = new LuaTable();
LuaString stringValue = LuaString.valueOf("this is a test");
LuaTable tableValue2 = new LuaTable();
t.set("table", tableValue);
t.set("userdata", LuaValue.userdataOf(obj, null));
t.set("string", stringValue);
t.set("string2", LuaString.valueOf("another string"));
assertTrue("table must have at least 4 elements", t.getHashLength() > 4);
t.set("string2", LuaValue.valueOf("another string"));
t.set(1, tableValue2);
assertTrue("table must have at least 4 elements", t.getHashLength() >= 4);
assertTrue("array part must have 1 element", t.getArrayLength() >= 1);
// check that table can be used to get elements
assertEquals(tableValue, t.get("table"));
assertEquals(stringValue, t.get("string"));
assertEquals(obj, t.get("userdata").checkuserdata());
assertEquals(tableValue2, t.get(1));
// nothing should be collected, since we have strong references here
collectGarbage();
@@ -83,10 +87,12 @@ abstract public class WeakTableTest extends TableTest {
assertEquals(tableValue, t.get("table"));
assertEquals(stringValue, t.get("string"));
assertEquals(obj, t.get("userdata").checkuserdata());
assertEquals(tableValue2, t.get(1));
// drop our strong references
obj = null;
tableValue = null;
tableValue2 = null;
stringValue = null;
// Garbage collection should cause weak entries to be dropped.
@@ -95,16 +101,17 @@ abstract public class WeakTableTest extends TableTest {
// check that they are dropped
assertEquals(LuaValue.NIL, t.get("table"));
assertEquals(LuaValue.NIL, t.get("userdata"));
assertEquals(LuaValue.NIL, t.get(1));
assertFalse("strings should not be in weak references", t.get("string").isnil());
}
}
public static class WeakKeyTableTest extends WeakTableTest {
protected LuaTable new_Table() { return new WeakTable(true, false); }
protected LuaTable new_Table(int n,int m) { return new WeakTable(true, false); }
protected LuaTable new_Table() { return WeakTable.make(true, false); }
protected LuaTable new_Table(int n,int m) { return WeakTable.make(true, false); }
public void testWeakKeysTable() {
LuaTable t = new WeakTable(true, false);
LuaTable t = WeakTable.make(true, false);
LuaValue key = LuaValue.userdataOf(new MyData(111));
LuaValue val = LuaValue.userdataOf(new MyData(222));
@@ -137,7 +144,7 @@ abstract public class WeakTableTest extends TableTest {
}
public void testNext() {
LuaTable t = new WeakTable(true, true);
LuaTable t = WeakTable.make(true, true);
LuaValue key = LuaValue.userdataOf(new MyData(111));
LuaValue val = LuaValue.userdataOf(new MyData(222));
@@ -167,11 +174,11 @@ abstract public class WeakTableTest extends TableTest {
}
public static class WeakKeyValueTableTest extends WeakTableTest {
protected LuaTable new_Table() { return new WeakTable(true, true); }
protected LuaTable new_Table(int n,int m) { return new WeakTable(true, true); }
protected LuaTable new_Table() { return WeakTable.make(true, true); }
protected LuaTable new_Table(int n,int m) { return WeakTable.make(true, true); }
public void testWeakKeysValuesTable() {
LuaTable t = new WeakTable(true, true);
LuaTable t = WeakTable.make(true, true);
LuaValue key = LuaValue.userdataOf(new MyData(111));
LuaValue val = LuaValue.userdataOf(new MyData(222));
@@ -224,7 +231,7 @@ abstract public class WeakTableTest extends TableTest {
}
public void testReplace() {
LuaTable t = new WeakTable(true, true);
LuaTable t = WeakTable.make(true, true);
LuaValue key = LuaValue.userdataOf(new MyData(111));
LuaValue val = LuaValue.userdataOf(new MyData(222));