Index all lua strings created from java strings.

This commit is contained in:
James Roseborough
2010-04-16 14:29:10 +00:00
parent e5cb343886
commit 118e2b3aaf
6 changed files with 38 additions and 45 deletions

View File

@@ -42,7 +42,7 @@ public final class Buffer {
} }
public final String toString() { public final String toString() {
return new LuaString(bytes, 0, length).toString(); return LuaString.valueOf(bytes, 0, length).toString();
} }
public final void append( byte b ) { public final void append( byte b ) {
@@ -75,7 +75,7 @@ public final class Buffer {
} }
public final LuaString tostring() { public final LuaString tostring() {
return new LuaString( realloc( bytes, length ) ); return LuaString.valueOf( realloc( bytes, length ) );
} }
public final void ensureCapacity( int minSize ) { public final void ensureCapacity( int minSize ) {

View File

@@ -157,7 +157,7 @@ public class LoadState {
return null; return null;
byte[] bytes = new byte[size]; byte[] bytes = new byte[size];
is.readFully( bytes, 0, size ); is.readFully( bytes, 0, size );
return new LuaString( bytes, 0, bytes.length - 1 ); return LuaString.valueOf( bytes, 0, bytes.length - 1 );
} }
public static LuaValue longBitsToLuaNumber( long bits ) { public static LuaValue longBitsToLuaNumber( long bits ) {

View File

@@ -26,6 +26,7 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Hashtable;
import org.luaj.vm2.lib.StringLib; import org.luaj.vm2.lib.StringLib;
@@ -37,48 +38,30 @@ public class LuaString extends LuaValue {
public final int m_offset; public final int m_offset;
public final int m_length; public final int m_length;
private static final int STRINGCACHE_POW2 = 10; private static final Hashtable index_java = new Hashtable();
private static final WeakReference[] stringcache
= new WeakReference[1<<STRINGCACHE_POW2];
private static class LuaJavaString extends LuaString { private final static LuaString index_get(Hashtable indextable, Object key) {
private final String string; WeakReference w = (WeakReference) indextable.get(key);
private LuaJavaString(String value, byte[] bytes) { return w!=null? (LuaString) w.get(): null;
super(bytes);
string = value.intern();
}
public String toString() {
return string;
} }
private final static void index_set(Hashtable indextable, Object key, LuaString value) {
indextable.put(key, new WeakReference(value));
} }
public static LuaString valueOf(String string) { public static LuaString valueOf(String string) {
int h = string.hashCode(); LuaString s = index_get( index_java, string );
int i = h & ((1<<STRINGCACHE_POW2)-1); if ( s != null ) return s;
if ( stringcache[i] != null ) {
LuaJavaString s = (LuaJavaString) stringcache[i].get();
if ( s != null && s.string == string ) {
return s;
}
}
char[] c = string.toCharArray(); char[] c = string.toCharArray();
byte[] b = new byte[lengthAsUtf8(c)]; byte[] b = new byte[lengthAsUtf8(c)];
encodeToUtf8(c, b, 0); encodeToUtf8(c, b, 0);
LuaJavaString s = new LuaJavaString(string,b); s = valueOf(b, 0, b.length);
stringcache[i] = new WeakReference(s); index_set( index_java, string, s );
return s; return s;
} }
public LuaString(byte[] bytes, int offset, int length) { public static LuaString valueOf(byte[] bytes, int off, int len) {
this.m_bytes = bytes; return new LuaString(bytes, off, len);
this.m_offset = offset;
this.m_length = length;
}
public LuaString(byte[] bytes) {
this.m_bytes = bytes;
this.m_offset = 0;
this.m_length = bytes.length;
} }
public static LuaString valueOf(char[] bytes) { public static LuaString valueOf(char[] bytes) {
@@ -86,7 +69,17 @@ public class LuaString extends LuaValue {
byte[] b = new byte[n]; byte[] b = new byte[n];
for ( int i=0; i<n; i++ ) for ( int i=0; i<n; i++ )
b[i] = (byte) bytes[i]; b[i] = (byte) bytes[i];
return new LuaString(b, 0, n); return valueOf(b, 0, n);
}
public static LuaString valueOf(byte[] bytes) {
return valueOf(bytes, 0, bytes.length);
}
private LuaString(byte[] bytes, int offset, int length) {
this.m_bytes = bytes;
this.m_offset = offset;
this.m_length = length;
} }
public boolean isstring() { public boolean isstring() {

View File

@@ -306,9 +306,9 @@ public class LuaValue extends Varargs {
public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); } public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); }
public static LuaNumber valueOf(double d) { return LuaDouble.valueOf(d); }; public static LuaNumber valueOf(double d) { return LuaDouble.valueOf(d); };
public static LuaString valueOf(String s) { return LuaString.valueOf(s); } public static LuaString valueOf(String s) { return LuaString.valueOf(s); }
public static LuaString valueOf(byte[] bytes) { return new LuaString(bytes); } public static LuaString valueOf(byte[] bytes) { return LuaString.valueOf(bytes); }
public static LuaString valueOf(byte[] bytes, int off, int len) { public static LuaString valueOf(byte[] bytes, int off, int len) {
return new LuaString(bytes,off,len); return LuaString.valueOf(bytes,off,len);
} }
// table initializers // table initializers

View File

@@ -398,7 +398,7 @@ public class IoLib extends OneArgFunction {
int r; int r;
if ( ( r = f.read(b,0,b.length) ) < 0 ) if ( ( r = f.read(b,0,b.length) ) < 0 )
return NIL; return NIL;
return valueOf(b, 0, r); return LuaString.valueOf(b, 0, r);
} }
public static LuaValue freaduntil(File f,int delim) throws IOException { public static LuaValue freaduntil(File f,int delim) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -415,7 +415,7 @@ public class IoLib extends OneArgFunction {
} }
return ( c < 0 && baos.size() == 0 )? return ( c < 0 && baos.size() == 0 )?
(LuaValue) NIL: (LuaValue) NIL:
(LuaValue) valueOf(baos.toByteArray()); (LuaValue) LuaString.valueOf(baos.toByteArray());
} }
public static LuaValue freadline(File f) throws IOException { public static LuaValue freadline(File f) throws IOException {
return freaduntil(f,'\n'); return freaduntil(f,'\n');

View File

@@ -127,7 +127,7 @@ public class StringLib extends OneArgFunction {
if (c<0 || c>=256) error(a, "invalid value"); if (c<0 || c>=256) error(a, "invalid value");
bytes[i] = (byte) c; bytes[i] = (byte) c;
} }
return valueOf( bytes ); return LuaString.valueOf( bytes );
} }
/** /**
@@ -144,7 +144,7 @@ public class StringLib extends OneArgFunction {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
try { try {
DumpState.dump( ((LuaClosure)f).p, baos, true ); DumpState.dump( ((LuaClosure)f).p, baos, true );
return valueOf(baos.toByteArray()); return LuaString.valueOf(baos.toByteArray());
} catch (IOException e) { } catch (IOException e) {
return error( e.getMessage() ); return error( e.getMessage() );
} }
@@ -625,7 +625,7 @@ public class StringLib extends OneArgFunction {
for ( int offset = 0; offset < bytes.length; offset += len ) { for ( int offset = 0; offset < bytes.length; offset += len ) {
s.copyInto( 0, bytes, offset, len ); s.copyInto( 0, bytes, offset, len );
} }
return valueOf( bytes ); return LuaString.valueOf( bytes );
} }
/** /**
@@ -639,7 +639,7 @@ public class StringLib extends OneArgFunction {
byte[] b = new byte[n]; byte[] b = new byte[n];
for ( int i=0, j=n-1; i<n; i++, j-- ) for ( int i=0, j=n-1; i<n; i++, j-- )
b[j] = (byte) s.luaByte(i); b[j] = (byte) s.luaByte(i);
return valueOf( b ); return LuaString.valueOf( b );
} }
/** /**