Mercurial Hosting > luan
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");