diff src/luan/LuanTable.java @ 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 6b8ea0a9b7c9
line wrap: on
line diff
--- 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;
 	}