comparison 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
comparison
equal deleted inserted replaced
784:6a7c6879158d 785:d69d3c51c44e
59 @Override public LuanTable shallowClone() { 59 @Override public LuanTable shallowClone() {
60 return new LuanTable(); 60 return new LuanTable();
61 } 61 }
62 62
63 @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) { 63 @Override public void deepenClone(LuanCloneable dc,LuanCloner cloner) {
64 check();
64 LuanTable clone = (LuanTable)dc; 65 LuanTable clone = (LuanTable)dc;
66 switch( cloner.type ) {
67 case COMPLETE:
68 deepenClone(clone,cloner);
69 return;
70 case INCREMENTAL:
71 clone.cloner = cloner;
72 clone.map = map;
73 clone.list = list;
74 clone.metatable = metatable;
75 clone.java = java;
76 return;
77 }
78 }
79
80 private void check() {
81 if( cloner != null ) {
82 deepenClone(this,cloner);
83 cloner = null;
84 }
85 }
86
87 private void deepenClone(LuanTable clone,LuanCloner cloner) {
65 if( map != null ) { 88 if( map != null ) {
66 clone.map = newMap(); 89 Map newMap = newMap();
67 for( Object stupid : map.entrySet() ) { 90 for( Object stupid : map.entrySet() ) {
68 Map.Entry entry = (Map.Entry)stupid; 91 Map.Entry entry = (Map.Entry)stupid;
69 Object val = entry.getValue(); 92 newMap.put( cloner.get(entry.getKey()), cloner.get(entry.getValue()) );
70 if( cloner.deep || !(val instanceof LuanTable) ) 93 }
71 val = cloner.get(val); 94 clone.map = newMap;
72 clone.map.put( cloner.get(entry.getKey()), val );
73 }
74 } 95 }
75 if( list != null ) { 96 if( list != null ) {
76 clone.list = new ArrayList<Object>(); 97 List newList = new ArrayList<Object>();
77 for( Object obj : list ) { 98 for( Object obj : list ) {
78 if( cloner.deep || !(obj instanceof LuanTable) ) 99 newList.add(cloner.get(obj));
79 obj = cloner.get(obj); 100 }
80 clone.list.add(obj); 101 clone.list = newList;
81 }
82 } 102 }
83 clone.metatable = (LuanTable)cloner.clone(metatable); 103 clone.metatable = (LuanTable)cloner.clone(metatable);
84 clone.java = (LuanJava)cloner.clone(java); 104 clone.java = (LuanJava)cloner.clone(java);
85 } 105 }
86 106
87 public boolean isList() { 107 public boolean isList() {
88 return map==null || map.isEmpty(); 108 return map==null || map.isEmpty();
89 } 109 }
90 110
91 public List<Object> asList() { 111 public List<Object> asList() {
112 check();
92 return list!=null ? list : Collections.emptyList(); 113 return list!=null ? list : Collections.emptyList();
93 } 114 }
94 115
95 public String toString(LuanState luan) throws LuanException { 116 public String toString(LuanState luan) throws LuanException {
96 Object h = getHandler("__to_string"); 117 Object h = getHandler("__to_string");
125 } 146 }
126 return luan.index(h,key); 147 return luan.index(h,key);
127 } 148 }
128 149
129 public Object rawGet(Object key) { 150 public Object rawGet(Object key) {
151 check();
130 if( list != null ) { 152 if( list != null ) {
131 Integer iT = Luan.asInteger(key); 153 Integer iT = Luan.asInteger(key);
132 if( iT != null ) { 154 if( iT != null ) {
133 int i = iT - 1; 155 int i = iT - 1;
134 if( i>=0 && i<list.size() ) 156 if( i>=0 && i<list.size() )
167 } 189 }
168 throw new LuanException("invalid type "+Luan.type(h)+" for metamethod __new_index"); 190 throw new LuanException("invalid type "+Luan.type(h)+" for metamethod __new_index");
169 } 191 }
170 192
171 public void rawPut(Object key,Object val) { 193 public void rawPut(Object key,Object val) {
194 check();
172 Integer iT = Luan.asInteger(key); 195 Integer iT = Luan.asInteger(key);
173 if( iT != null ) { 196 if( iT != null ) {
174 int i = iT - 1; 197 int i = iT - 1;
175 if( list != null || i == 0 ) { 198 if( list != null || i == 0 ) {
176 if( i == list().size() ) { 199 if( i == list().size() ) {
233 } 256 }
234 return list; 257 return list;
235 } 258 }
236 259
237 public void rawInsert(int pos,Object value) { 260 public void rawInsert(int pos,Object value) {
261 check();
238 if( value==null ) 262 if( value==null )
239 throw new IllegalArgumentException("can't insert a nil value"); 263 throw new IllegalArgumentException("can't insert a nil value");
240 list().add(pos-1,value); 264 list().add(pos-1,value);
241 mapToList(); 265 mapToList();
242 } 266 }
243 267
244 public Object rawRemove(int pos) { 268 public Object rawRemove(int pos) {
269 check();
245 return list().remove(pos-1); 270 return list().remove(pos-1);
246 } 271 }
247 272
248 public void rawSort(Comparator<Object> cmp) { 273 public void rawSort(Comparator<Object> cmp) {
274 check();
249 Collections.sort(list(),cmp); 275 Collections.sort(list(),cmp);
250 } 276 }
251 277
252 public int length(LuanState luan) throws LuanException { 278 public int length(LuanState luan) throws LuanException {
253 Object h = getHandler("__len"); 279 Object h = getHandler("__len");
257 } 283 }
258 return rawLength(); 284 return rawLength();
259 } 285 }
260 286
261 public int rawLength() { 287 public int rawLength() {
288 check();
262 return list==null ? 0 : list.size(); 289 return list==null ? 0 : list.size();
263 } 290 }
264 291
265 public Iterable<Map.Entry<Object,Object>> iterable(LuanState luan) throws LuanException { 292 public Iterable<Map.Entry<Object,Object>> iterable(LuanState luan) throws LuanException {
266 final Iterator<Map.Entry<Object,Object>> iter = iterator(luan); 293 final Iterator<Map.Entry<Object,Object>> iter = iterator(luan);
348 } 375 }
349 }; 376 };
350 } 377 }
351 378
352 public Iterator<Map.Entry<Object,Object>> rawIterator() { 379 public Iterator<Map.Entry<Object,Object>> rawIterator() {
380 check();
353 if( list == null ) { 381 if( list == null ) {
354 if( map == null ) 382 if( map == null )
355 return Collections.<Map.Entry<Object,Object>>emptyList().iterator(); 383 return Collections.<Map.Entry<Object,Object>>emptyList().iterator();
356 return map.entrySet().iterator(); 384 return map.entrySet().iterator();
357 } 385 }
401 } 429 }
402 }; 430 };
403 } 431 }
404 432
405 public LuanTable rawSubList(int from,int to) { 433 public LuanTable rawSubList(int from,int to) {
434 check();
406 LuanTable tbl = new LuanTable(); 435 LuanTable tbl = new LuanTable();
407 tbl.list = new ArrayList<Object>(list().subList(from-1,to-1)); 436 tbl.list = new ArrayList<Object>(list().subList(from-1,to-1));
408 return tbl; 437 return tbl;
409 } 438 }
410 439
411 public LuanTable getMetatable() { 440 public LuanTable getMetatable() {
441 check();
412 return metatable; 442 return metatable;
413 } 443 }
414 444
415 public void setMetatable(LuanTable metatable) { 445 public void setMetatable(LuanTable metatable) {
446 check();
416 this.metatable = metatable; 447 this.metatable = metatable;
417 } 448 }
418 449
419 public Object getHandler(String op) { 450 public Object getHandler(String op) {
451 check();
420 return metatable==null ? null : metatable.rawGet(op); 452 return metatable==null ? null : metatable.rawGet(op);
421 } 453 }
422 454
423 private Map<Object,Object> newMap() { 455 private Map<Object,Object> newMap() {
424 return new LinkedHashMap<Object,Object>(); 456 return new LinkedHashMap<Object,Object>();
447 } 479 }
448 return map; 480 return map;
449 } 481 }
450 482
451 public void rawClear() { 483 public void rawClear() {
484 check();
452 map = null; 485 map = null;
453 list = null; 486 list = null;
454 } 487 }
455 488
456 } 489 }