changeset 782:655280eab1e2

start limited cloning
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 30 Aug 2016 01:29:33 -0600
parents fbbdd369a13a
children 4083f5a67c63
files src/luan/LuanCloneable.java src/luan/LuanCloner.java src/luan/LuanException.java src/luan/LuanJava.java src/luan/LuanState.java src/luan/LuanTable.java src/luan/impl/Closure.java src/luan/impl/Pointer.java src/luan/modules/ThreadLuan.java src/luan/modules/http/HttpServicer.java src/luan/modules/http/LuanHandler.java
diffstat 11 files changed, 62 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuanCloneable.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/LuanCloneable.java	Tue Aug 30 01:29:33 2016 -0600
@@ -2,6 +2,6 @@
 
 
 public interface LuanCloneable {
-	public LuanCloneable shallowClone();
+	public LuanCloneable shallowClone(LuanCloner cloner);
 	public void deepenClone(LuanCloneable clone,LuanCloner cloner);
 }
--- a/src/luan/LuanCloner.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/LuanCloner.java	Tue Aug 30 01:29:33 2016 -0600
@@ -6,21 +6,26 @@
 
 
 public final class LuanCloner {
+	public final boolean deep;
 	private final Map cloned = new IdentityHashMap();
 
-	public LuanCloneable deepClone(LuanCloneable obj) {
+	public LuanCloner(boolean deep) {
+		this.deep = deep;
+	}
+
+	public LuanCloneable clone(LuanCloneable obj) {
 		if( obj==null )
 			return null;
 		LuanCloneable rtn = (LuanCloneable)cloned.get(obj);
 		if( rtn == null ) {
-			rtn = obj.shallowClone();
+			rtn = obj.shallowClone(this);
 			cloned.put(obj,rtn);
 			obj.deepenClone(rtn,this);
 		}
 		return rtn;
 	}
 
-	public Object[] deepClone(Object[] obj) {
+	public Object[] clone(Object[] obj) {
 		if( obj.length == 0 )
 			return obj;
 		Object[] rtn = (Object[])cloned.get(obj);
@@ -34,7 +39,7 @@
 		return rtn;
 	}
 
-	public Map deepClone(Map obj) {
+	public Map clone(Map obj) {
 		if( !obj.getClass().equals(HashMap.class) )
 			throw new RuntimeException("can only clone HashMap");
 		Map rtn = (Map)cloned.get(obj);
@@ -50,11 +55,21 @@
 
 	public Object get(Object obj) {
 		if( obj instanceof LuanCloneable )
-			return deepClone((LuanCloneable)obj);
+			return clone((LuanCloneable)obj);
 		if( obj instanceof Object[] )
-			return deepClone((Object[])obj);
+			return clone((Object[])obj);
 		if( obj instanceof Map )
-			return deepClone((Map)obj);
+			return clone((Map)obj);
 		return obj;
 	}
+/*
+	public Object check(Object obj) {
+		if( deep )
+			throw new RuntimeException();
+		if( !(obj instanceof LuanCloneable) )
+			return obj;
+		LuanCloneable lc = (LuanCloneable)obj;
+		return lc.getCloner() == this ? lc : clone(lc);
+	}
+*/
 }
--- a/src/luan/LuanException.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/LuanException.java	Tue Aug 30 01:29:33 2016 -0600
@@ -28,13 +28,13 @@
 		super(msg,cause);
 	}
 
-	@Override public LuanException shallowClone() {
+	@Override public LuanException shallowClone(LuanCloner cloner) {
 		return new LuanException(getMessage(),getCause(),99);
 	}
 
 	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
 		LuanException clone = (LuanException)dc;
-		clone.table = (LuanTable)cloner.get(table);
+		clone.table = (LuanTable)cloner.clone(table);
 	}
 
 	public LuanTable table() {
--- a/src/luan/LuanJava.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/LuanJava.java	Tue Aug 30 01:29:33 2016 -0600
@@ -4,7 +4,7 @@
 public final class LuanJava implements LuanCloneable {
 	public boolean ok = false;
 
-	@Override public LuanJava shallowClone() {
+	@Override public LuanJava shallowClone(LuanCloner cloner) {
 		LuanJava java = new LuanJava();
 		java.ok = ok;
 		return java;
--- a/src/luan/LuanState.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/LuanState.java	Tue Aug 30 01:29:33 2016 -0600
@@ -14,7 +14,6 @@
 
 
 public final class LuanState implements LuanCloneable {
-
 	public LuanJava java;
 	private Map registry;
 	private final List<Reference<Closeable>> onClose = new ArrayList<Reference<Closeable>>();
@@ -26,14 +25,14 @@
 
 	private LuanState(LuanState luan) {}
 
-	@Override public LuanState shallowClone() {
+	@Override public LuanState shallowClone(LuanCloner cloner) {
 		return new LuanState(this);
 	}
 
 	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
 		LuanState clone = (LuanState)dc;
-		clone.registry = cloner.deepClone(registry);
-		clone.java = (LuanJava)cloner.deepClone(java);
+		clone.registry = cloner.clone(registry);
+		clone.java = (LuanJava)cloner.clone(java);
 	}
 
 	public final Map registry() {
--- a/src/luan/LuanTable.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/LuanTable.java	Tue Aug 30 01:29:33 2016 -0600
@@ -18,6 +18,11 @@
 	private List list = null;
 	private LuanTable metatable = null;
 	public LuanJava java;
+	private LuanCloner cloner;
+
+	private LuanTable(LuanCloner cloner) {
+		this.cloner = cloner;
+	}
 
 	public LuanTable() {}
 
@@ -55,8 +60,8 @@
 		this.metatable = tbl.metatable;
 	}
 
-	@Override public LuanTable shallowClone() {
-		return new LuanTable();
+	@Override public LuanTable shallowClone(LuanCloner cloner) {
+		return new LuanTable(cloner.deep ? null : cloner);
 	}
 
 	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
@@ -65,18 +70,22 @@
 			clone.map = newMap();
 			for( Object stupid : map.entrySet() ) {
 				Map.Entry entry = (Map.Entry)stupid;
-				clone.map.put( cloner.get(entry.getKey()), cloner.get(entry.getValue()) );
+				Object val = entry.getValue();
+				if( cloner.deep || !(val instanceof LuanTable) )
+					val = cloner.get(val);
+				clone.map.put( cloner.get(entry.getKey()), val );
 			}
 		}
 		if( list != null ) {
 			clone.list = new ArrayList<Object>();
 			for( Object obj : list ) {
-				clone.list.add( cloner.get(obj) );
+				if( cloner.deep || !(obj instanceof LuanTable) )
+					obj = cloner.get(obj);
+				clone.list.add(obj);
 			}
 		}
-		if( metatable != null )
-			clone.metatable = (LuanTable)cloner.get(metatable);
-		clone.java = (LuanJava)cloner.deepClone(java);
+		clone.metatable = (LuanTable)cloner.clone(metatable);
+		clone.java = (LuanJava)cloner.clone(java);
 	}
 
 	public boolean isList() {
@@ -398,7 +407,7 @@
 	}
 
 	public LuanTable rawSubList(int from,int to) {
-		LuanTable tbl = shallowClone();
+		LuanTable tbl = new LuanTable(cloner);
 		tbl.list = new ArrayList<Object>(list().subList(from-1,to-1));
 		return tbl;
 	}
--- a/src/luan/impl/Closure.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/impl/Closure.java	Tue Aug 30 01:29:33 2016 -0600
@@ -18,7 +18,7 @@
 		this.java = java;
 	}
 
-	@Override public Closure shallowClone() {
+	@Override public Closure shallowClone(LuanCloner cloner) {
 		try {
 			return (Closure)clone();
 		} catch(CloneNotSupportedException e) {
@@ -28,8 +28,8 @@
 
 	@Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
 		Closure clone = (Closure)dc;
-		clone.upValues = (Pointer[])cloner.deepClone(upValues);
-		clone.java = (LuanJava)cloner.deepClone(java);
+		clone.upValues = (Pointer[])cloner.clone(upValues);
+		clone.java = (LuanJava)cloner.clone(java);
 	}
 
 	@Override public final Object call(LuanState luan,Object[] args) throws LuanException {
--- a/src/luan/impl/Pointer.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/impl/Pointer.java	Tue Aug 30 01:29:33 2016 -0600
@@ -13,7 +13,7 @@
 		this.o = o;
 	}
 
-	@Override public Pointer shallowClone() {
+	@Override public Pointer shallowClone(LuanCloner cloner) {
 		return new Pointer();
 	}
 
--- a/src/luan/modules/ThreadLuan.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/modules/ThreadLuan.java	Tue Aug 30 01:29:33 2016 -0600
@@ -19,10 +19,10 @@
 	private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
 
 	public static void fork(LuanState luan,LuanFunction fn,Object... args) {
-		LuanCloner cloner = new LuanCloner();
-		final LuanState newLuan = (LuanState)cloner.deepClone(luan);
+		LuanCloner cloner = new LuanCloner(true);
+		final LuanState newLuan = (LuanState)cloner.clone(luan);
 		final LuanFunction newFn = (LuanFunction)cloner.get(fn);
-		final Object[] newArgs = cloner.deepClone(args);
+		final Object[] newArgs = cloner.clone(args);
 		exec.execute(new Runnable(){public void run() {
 			try {
 				newFn.call(newLuan,newArgs);
@@ -44,10 +44,10 @@
 	}
 
 	public static void schedule(LuanState luan,long delay,boolean repeat,LuanFunction fn,Object... args) {
-		LuanCloner cloner = new LuanCloner();
-		final LuanState newLuan = (LuanState)cloner.deepClone(luan);
+		LuanCloner cloner = new LuanCloner(true);
+		final LuanState newLuan = (LuanState)cloner.clone(luan);
 		final LuanFunction newFn = (LuanFunction)cloner.get(fn);
-		final Object[] newArgs = cloner.deepClone(args);
+		final Object[] newArgs = cloner.clone(args);
 		Runnable r = new Runnable(){public void run() {
 			try {
 				newFn.call(newLuan,newArgs);
--- a/src/luan/modules/http/HttpServicer.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/modules/http/HttpServicer.java	Tue Aug 30 01:29:33 2016 -0600
@@ -59,14 +59,14 @@
 				if( sessionLuan!=null ) {
 					luan = sessionLuan;
 				} else {
-					LuanCloner cloner = new LuanCloner();
-					luan = (LuanState)cloner.deepClone(luan);
+					LuanCloner cloner = new LuanCloner(true);
+					luan = (LuanState)cloner.clone(luan);
 					session.setAttribute("luan",luan);
 				}
 				fn = (LuanFunction)PackageLuan.require(luan,modName);
 			} else {
-				LuanCloner cloner = new LuanCloner();
-				luan = (LuanState)cloner.deepClone(luan);
+				LuanCloner cloner = new LuanCloner(true);
+				luan = (LuanState)cloner.clone(luan);
 				fn = (LuanFunction)cloner.get(mod);
 			}
 		}
--- a/src/luan/modules/http/LuanHandler.java	Mon Aug 29 22:49:32 2016 -0600
+++ b/src/luan/modules/http/LuanHandler.java	Tue Aug 30 01:29:33 2016 -0600
@@ -70,8 +70,8 @@
 
 	public static Object callRpc(LuanState luan,String fnName,Object... args) throws LuanException {
 		synchronized(luan) {
-			LuanCloner cloner = new LuanCloner();
-			luan = (LuanState)cloner.deepClone(luan);
+			LuanCloner cloner = new LuanCloner(true);
+			luan = (LuanState)cloner.clone(luan);
 		}
 		LuanTable rpc = (LuanTable)PackageLuan.require(luan,"luan:Rpc.luan");
 		LuanTable fns = (LuanTable)rpc.get(luan,"functions");