Mercurial Hosting > luan
changeset 785:d69d3c51c44e
more work on incremental cloning
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 01 Sep 2016 21:32:28 -0600 |
parents | 6a7c6879158d |
children | fe63c508a177 |
files | src/luan/LuanCloner.java src/luan/LuanState.java src/luan/LuanTable.java src/luan/impl/Closure.java src/luan/impl/LuanParser.java src/luan/modules/ThreadLuan.java src/luan/modules/http/HttpServicer.java src/luan/modules/http/LuanHandler.java |
diffstat | 8 files changed, 85 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/LuanCloner.java --- a/src/luan/LuanCloner.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/LuanCloner.java Thu Sep 01 21:32:28 2016 -0600 @@ -6,11 +6,13 @@ public final class LuanCloner { - public final boolean deep; + public enum Type { COMPLETE, INCREMENTAL } + + public final Type type; private final Map cloned = new IdentityHashMap(); - public LuanCloner(boolean deep) { - this.deep = deep; + public LuanCloner(Type type) { + this.type = type; } public LuanCloneable clone(LuanCloneable obj) { @@ -62,14 +64,4 @@ 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); - } -*/ }
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/LuanState.java --- a/src/luan/LuanState.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/LuanState.java Thu Sep 01 21:32:28 2016 -0600 @@ -33,6 +33,13 @@ LuanState clone = (LuanState)dc; clone.registry = cloner.clone(registry); clone.java = (LuanJava)cloner.clone(java); +/* + if( !cloner.deep ) { + LuanCloner myCloner = new LuanCloner(false); + registry = myCloner.clone(registry); + java = (LuanJava)myCloner.clone(java); + } +*/ } public final Map registry() {
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/LuanTable.java --- a/src/luan/LuanTable.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/LuanTable.java Thu Sep 01 21:32:28 2016 -0600 @@ -61,24 +61,44 @@ } @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { + check(); LuanTable clone = (LuanTable)dc; + switch( cloner.type ) { + case COMPLETE: + deepenClone(clone,cloner); + return; + case INCREMENTAL: + clone.cloner = cloner; + clone.map = map; + clone.list = list; + clone.metatable = metatable; + clone.java = java; + return; + } + } + + private void check() { + if( cloner != null ) { + deepenClone(this,cloner); + cloner = null; + } + } + + private void deepenClone(LuanTable clone,LuanCloner cloner) { if( map != null ) { - clone.map = newMap(); + Map newMap = newMap(); for( Object stupid : map.entrySet() ) { Map.Entry entry = (Map.Entry)stupid; - Object val = entry.getValue(); - if( cloner.deep || !(val instanceof LuanTable) ) - val = cloner.get(val); - clone.map.put( cloner.get(entry.getKey()), val ); + newMap.put( cloner.get(entry.getKey()), cloner.get(entry.getValue()) ); } + clone.map = newMap; } if( list != null ) { - clone.list = new ArrayList<Object>(); + List newList = new ArrayList<Object>(); for( Object obj : list ) { - if( cloner.deep || !(obj instanceof LuanTable) ) - obj = cloner.get(obj); - clone.list.add(obj); + newList.add(cloner.get(obj)); } + clone.list = newList; } clone.metatable = (LuanTable)cloner.clone(metatable); clone.java = (LuanJava)cloner.clone(java); @@ -89,6 +109,7 @@ } public List<Object> asList() { + check(); return list!=null ? list : Collections.emptyList(); } @@ -127,6 +148,7 @@ } public Object rawGet(Object key) { + check(); if( list != null ) { Integer iT = Luan.asInteger(key); if( iT != null ) { @@ -169,6 +191,7 @@ } public void rawPut(Object key,Object val) { + check(); Integer iT = Luan.asInteger(key); if( iT != null ) { int i = iT - 1; @@ -235,6 +258,7 @@ } public void rawInsert(int pos,Object value) { + check(); if( value==null ) throw new IllegalArgumentException("can't insert a nil value"); list().add(pos-1,value); @@ -242,10 +266,12 @@ } public Object rawRemove(int pos) { + check(); return list().remove(pos-1); } public void rawSort(Comparator<Object> cmp) { + check(); Collections.sort(list(),cmp); } @@ -259,6 +285,7 @@ } public int rawLength() { + check(); return list==null ? 0 : list.size(); } @@ -350,6 +377,7 @@ } public Iterator<Map.Entry<Object,Object>> rawIterator() { + check(); if( list == null ) { if( map == null ) return Collections.<Map.Entry<Object,Object>>emptyList().iterator(); @@ -403,20 +431,24 @@ } public LuanTable rawSubList(int from,int to) { + check(); LuanTable tbl = new LuanTable(); tbl.list = new ArrayList<Object>(list().subList(from-1,to-1)); return tbl; } public LuanTable getMetatable() { + check(); return metatable; } public void setMetatable(LuanTable metatable) { + check(); this.metatable = metatable; } public Object getHandler(String op) { + check(); return metatable==null ? null : metatable.rawGet(op); } @@ -449,6 +481,7 @@ } public void rawClear() { + check(); map = null; list = null; }
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/impl/Closure.java --- a/src/luan/impl/Closure.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/impl/Closure.java Thu Sep 01 21:32:28 2016 -0600 @@ -11,11 +11,12 @@ public abstract class Closure extends LuanFunction implements LuanCloneable, Cloneable { public Pointer[] upValues; - public LuanJava java; + public LuanJava ljava; + private LuanCloner cloner; public Closure(int nUpValues,LuanJava java) throws LuanException { this.upValues = new Pointer[nUpValues]; - this.java = java; + this.ljava = java; } @Override public Closure shallowClone() { @@ -27,14 +28,33 @@ } @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { + check(); Closure clone = (Closure)dc; - clone.upValues = (Pointer[])cloner.clone(upValues); - clone.java = (LuanJava)cloner.clone(java); + switch( cloner.type ) { + case COMPLETE: + clone.upValues = (Pointer[])cloner.clone(upValues); + clone.ljava = (LuanJava)cloner.clone(ljava); + return; + case INCREMENTAL: + clone.cloner = cloner; + clone.upValues = upValues; + clone.ljava = ljava; + return; + } + } + + private void check() { + if( cloner != null ) { + upValues = (Pointer[])cloner.clone(upValues); + ljava = (LuanJava)cloner.clone(ljava); + cloner = null; + } } @Override public final Object call(LuanState luan,Object[] args) throws LuanException { + check(); LuanJava old = luan.java; - luan.java = java; + luan.java = ljava; try { return doCall(luan,args); } catch(StackOverflowError e) {
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/impl/LuanParser.java --- a/src/luan/impl/LuanParser.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/impl/LuanParser.java Thu Sep 01 21:32:28 2016 -0600 @@ -1967,7 +1967,7 @@ stmt.add( "return LuanFunction.NOTHING; " ); Expr exp = new Expr(Val.SINGLE,false); exp.add( "" - +"new Closure("+upValueSymbols.size()+",java) { " + +"new Closure("+upValueSymbols.size()+",ljava) { " +"{ " + init(upValueSymbols) +"} "
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/modules/ThreadLuan.java --- a/src/luan/modules/ThreadLuan.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/modules/ThreadLuan.java Thu Sep 01 21:32:28 2016 -0600 @@ -19,7 +19,7 @@ private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); public static void fork(LuanState luan,LuanFunction fn,Object... args) { - LuanCloner cloner = new LuanCloner(true); + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); final LuanState newLuan = (LuanState)cloner.clone(luan); final LuanFunction newFn = (LuanFunction)cloner.get(fn); final Object[] newArgs = cloner.clone(args); @@ -44,7 +44,7 @@ } public static void schedule(LuanState luan,long delay,boolean repeat,LuanFunction fn,Object... args) { - LuanCloner cloner = new LuanCloner(true); + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); final LuanState newLuan = (LuanState)cloner.clone(luan); final LuanFunction newFn = (LuanFunction)cloner.get(fn); final Object[] newArgs = cloner.clone(args);
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/modules/http/HttpServicer.java --- a/src/luan/modules/http/HttpServicer.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/modules/http/HttpServicer.java Thu Sep 01 21:32:28 2016 -0600 @@ -59,13 +59,13 @@ if( sessionLuan!=null ) { luan = sessionLuan; } else { - LuanCloner cloner = new LuanCloner(true); + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); luan = (LuanState)cloner.clone(luan); session.setAttribute("luan",luan); } fn = (LuanFunction)PackageLuan.require(luan,modName); } else { - LuanCloner cloner = new LuanCloner(true); + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); luan = (LuanState)cloner.clone(luan); fn = (LuanFunction)cloner.get(mod); }
diff -r 6a7c6879158d -r d69d3c51c44e src/luan/modules/http/LuanHandler.java --- a/src/luan/modules/http/LuanHandler.java Tue Aug 30 12:08:49 2016 -0600 +++ b/src/luan/modules/http/LuanHandler.java Thu Sep 01 21:32:28 2016 -0600 @@ -70,7 +70,7 @@ public static Object callRpc(LuanState luan,String fnName,Object... args) throws LuanException { synchronized(luan) { - LuanCloner cloner = new LuanCloner(true); + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); luan = (LuanState)cloner.clone(luan); } LuanTable rpc = (LuanTable)PackageLuan.require(luan,"luan:Rpc.luan");