Mercurial > lasercutter
diff src/clojure/lang/PersistentTreeMap.java @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/clojure/lang/PersistentTreeMap.java Sat Aug 21 06:25:44 2010 -0400 1.3 @@ -0,0 +1,1003 @@ 1.4 +/** 1.5 + * Copyright (c) Rich Hickey. All rights reserved. 1.6 + * The use and distribution terms for this software are covered by the 1.7 + * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) 1.8 + * which can be found in the file epl-v10.html at the root of this distribution. 1.9 + * By using this software in any fashion, you are agreeing to be bound by 1.10 + * the terms of this license. 1.11 + * You must not remove this notice, or any other, from this software. 1.12 + **/ 1.13 + 1.14 +/* rich May 20, 2006 */ 1.15 + 1.16 +package clojure.lang; 1.17 + 1.18 +import java.util.*; 1.19 + 1.20 +/** 1.21 + * Persistent Red Black Tree 1.22 + * Note that instances of this class are constant values 1.23 + * i.e. add/remove etc return new values 1.24 + * <p/> 1.25 + * See Okasaki, Kahrs, Larsen et al 1.26 + */ 1.27 + 1.28 +public class PersistentTreeMap extends APersistentMap implements IObj, Reversible, Sorted{ 1.29 + 1.30 +public final Comparator comp; 1.31 +public final Node tree; 1.32 +public final int _count; 1.33 +final IPersistentMap _meta; 1.34 + 1.35 +final static public PersistentTreeMap EMPTY = new PersistentTreeMap(); 1.36 + 1.37 +static public IPersistentMap create(Map other){ 1.38 + IPersistentMap ret = EMPTY; 1.39 + for(Object o : other.entrySet()) 1.40 + { 1.41 + Map.Entry e = (Entry) o; 1.42 + ret = ret.assoc(e.getKey(), e.getValue()); 1.43 + } 1.44 + return ret; 1.45 +} 1.46 + 1.47 +public PersistentTreeMap(){ 1.48 + this(RT.DEFAULT_COMPARATOR); 1.49 +} 1.50 + 1.51 +public PersistentTreeMap withMeta(IPersistentMap meta){ 1.52 + return new PersistentTreeMap(meta, comp, tree, _count); 1.53 +} 1.54 + 1.55 +private PersistentTreeMap(Comparator comp){ 1.56 + this(null, comp); 1.57 +} 1.58 + 1.59 + 1.60 +public PersistentTreeMap(IPersistentMap meta, Comparator comp){ 1.61 + this.comp = comp; 1.62 + this._meta = meta; 1.63 + tree = null; 1.64 + _count = 0; 1.65 +} 1.66 + 1.67 +PersistentTreeMap(IPersistentMap meta, Comparator comp, Node tree, int _count){ 1.68 + this._meta = meta; 1.69 + this.comp = comp; 1.70 + this.tree = tree; 1.71 + this._count = _count; 1.72 +} 1.73 + 1.74 +static public PersistentTreeMap create(ISeq items){ 1.75 + IPersistentMap ret = EMPTY; 1.76 + for(; items != null; items = items.next().next()) 1.77 + { 1.78 + if(items.next() == null) 1.79 + throw new IllegalArgumentException(String.format("No value supplied for key: %s", items.first())); 1.80 + ret = ret.assoc(items.first(), RT.second(items)); 1.81 + } 1.82 + return (PersistentTreeMap) ret; 1.83 +} 1.84 + 1.85 +static public PersistentTreeMap create(Comparator comp, ISeq items){ 1.86 + IPersistentMap ret = new PersistentTreeMap(comp); 1.87 + for(; items != null; items = items.next().next()) 1.88 + { 1.89 + if(items.next() == null) 1.90 + throw new IllegalArgumentException(String.format("No value supplied for key: %s", items.first())); 1.91 + ret = ret.assoc(items.first(), RT.second(items)); 1.92 + } 1.93 + return (PersistentTreeMap) ret; 1.94 +} 1.95 + 1.96 +public boolean containsKey(Object key){ 1.97 + return entryAt(key) != null; 1.98 +} 1.99 + 1.100 +public PersistentTreeMap assocEx(Object key, Object val) throws Exception{ 1.101 + Box found = new Box(null); 1.102 + Node t = add(tree, key, val, found); 1.103 + if(t == null) //null == already contains key 1.104 + { 1.105 + throw new Exception("Key already present"); 1.106 + } 1.107 + return new PersistentTreeMap(comp, t.blacken(), _count + 1, meta()); 1.108 +} 1.109 + 1.110 +public PersistentTreeMap assoc(Object key, Object val){ 1.111 + Box found = new Box(null); 1.112 + Node t = add(tree, key, val, found); 1.113 + if(t == null) //null == already contains key 1.114 + { 1.115 + Node foundNode = (Node) found.val; 1.116 + if(foundNode.val() == val) //note only get same collection on identity of val, not equals() 1.117 + return this; 1.118 + return new PersistentTreeMap(comp, replace(tree, key, val), _count, meta()); 1.119 + } 1.120 + return new PersistentTreeMap(comp, t.blacken(), _count + 1, meta()); 1.121 +} 1.122 + 1.123 + 1.124 +public PersistentTreeMap without(Object key){ 1.125 + Box found = new Box(null); 1.126 + Node t = remove(tree, key, found); 1.127 + if(t == null) 1.128 + { 1.129 + if(found.val == null)//null == doesn't contain key 1.130 + return this; 1.131 + //empty 1.132 + return new PersistentTreeMap(meta(), comp); 1.133 + } 1.134 + return new PersistentTreeMap(comp, t.blacken(), _count - 1, meta()); 1.135 +} 1.136 + 1.137 +public ISeq seq(){ 1.138 + if(_count > 0) 1.139 + return Seq.create(tree, true, _count); 1.140 + return null; 1.141 +} 1.142 + 1.143 +public IPersistentCollection empty(){ 1.144 + return new PersistentTreeMap(meta(), comp); 1.145 +} 1.146 + 1.147 +public ISeq rseq() throws Exception{ 1.148 + if(_count > 0) 1.149 + return Seq.create(tree, false, _count); 1.150 + return null; 1.151 +} 1.152 + 1.153 +public Comparator comparator(){ 1.154 + return comp; 1.155 +} 1.156 + 1.157 +public Object entryKey(Object entry){ 1.158 + return ((IMapEntry) entry).key(); 1.159 +} 1.160 + 1.161 +public ISeq seq(boolean ascending){ 1.162 + if(_count > 0) 1.163 + return Seq.create(tree, ascending, _count); 1.164 + return null; 1.165 +} 1.166 + 1.167 +public ISeq seqFrom(Object key, boolean ascending){ 1.168 + if(_count > 0) 1.169 + { 1.170 + ISeq stack = null; 1.171 + Node t = tree; 1.172 + while(t != null) 1.173 + { 1.174 + int c = doCompare(key, t.key); 1.175 + if(c == 0) 1.176 + { 1.177 + stack = RT.cons(t, stack); 1.178 + return new Seq(stack, ascending); 1.179 + } 1.180 + else if(ascending) 1.181 + { 1.182 + if(c < 0) 1.183 + { 1.184 + stack = RT.cons(t, stack); 1.185 + t = t.left(); 1.186 + } 1.187 + else 1.188 + t = t.right(); 1.189 + } 1.190 + else 1.191 + { 1.192 + if(c > 0) 1.193 + { 1.194 + stack = RT.cons(t, stack); 1.195 + t = t.right(); 1.196 + } 1.197 + else 1.198 + t = t.left(); 1.199 + } 1.200 + } 1.201 + if(stack != null) 1.202 + return new Seq(stack, ascending); 1.203 + } 1.204 + return null; 1.205 +} 1.206 + 1.207 +public NodeIterator iterator(){ 1.208 + return new NodeIterator(tree, true); 1.209 +} 1.210 + 1.211 +public NodeIterator reverseIterator(){ 1.212 + return new NodeIterator(tree, false); 1.213 +} 1.214 + 1.215 +public Iterator keys(){ 1.216 + return keys(iterator()); 1.217 +} 1.218 + 1.219 +public Iterator vals(){ 1.220 + return vals(iterator()); 1.221 +} 1.222 + 1.223 +public Iterator keys(NodeIterator it){ 1.224 + return new KeyIterator(it); 1.225 +} 1.226 + 1.227 +public Iterator vals(NodeIterator it){ 1.228 + return new ValIterator(it); 1.229 +} 1.230 + 1.231 +public Object minKey(){ 1.232 + Node t = min(); 1.233 + return t != null ? t.key : null; 1.234 +} 1.235 + 1.236 +public Node min(){ 1.237 + Node t = tree; 1.238 + if(t != null) 1.239 + { 1.240 + while(t.left() != null) 1.241 + t = t.left(); 1.242 + } 1.243 + return t; 1.244 +} 1.245 + 1.246 +public Object maxKey(){ 1.247 + Node t = max(); 1.248 + return t != null ? t.key : null; 1.249 +} 1.250 + 1.251 +public Node max(){ 1.252 + Node t = tree; 1.253 + if(t != null) 1.254 + { 1.255 + while(t.right() != null) 1.256 + t = t.right(); 1.257 + } 1.258 + return t; 1.259 +} 1.260 + 1.261 +public int depth(){ 1.262 + return depth(tree); 1.263 +} 1.264 + 1.265 +int depth(Node t){ 1.266 + if(t == null) 1.267 + return 0; 1.268 + return 1 + Math.max(depth(t.left()), depth(t.right())); 1.269 +} 1.270 + 1.271 +public Object valAt(Object key, Object notFound){ 1.272 + Node n = entryAt(key); 1.273 + return (n != null) ? n.val() : notFound; 1.274 +} 1.275 + 1.276 +public Object valAt(Object key){ 1.277 + return valAt(key, null); 1.278 +} 1.279 + 1.280 +public int capacity(){ 1.281 + return _count; 1.282 +} 1.283 + 1.284 +public int count(){ 1.285 + return _count; 1.286 +} 1.287 + 1.288 +public Node entryAt(Object key){ 1.289 + Node t = tree; 1.290 + while(t != null) 1.291 + { 1.292 + int c = doCompare(key, t.key); 1.293 + if(c == 0) 1.294 + return t; 1.295 + else if(c < 0) 1.296 + t = t.left(); 1.297 + else 1.298 + t = t.right(); 1.299 + } 1.300 + return t; 1.301 +} 1.302 + 1.303 +public int doCompare(Object k1, Object k2){ 1.304 +// if(comp != null) 1.305 + return comp.compare(k1, k2); 1.306 +// return ((Comparable) k1).compareTo(k2); 1.307 +} 1.308 + 1.309 +Node add(Node t, Object key, Object val, Box found){ 1.310 + if(t == null) 1.311 + { 1.312 + if(val == null) 1.313 + return new Red(key); 1.314 + return new RedVal(key, val); 1.315 + } 1.316 + int c = doCompare(key, t.key); 1.317 + if(c == 0) 1.318 + { 1.319 + found.val = t; 1.320 + return null; 1.321 + } 1.322 + Node ins = c < 0 ? add(t.left(), key, val, found) : add(t.right(), key, val, found); 1.323 + if(ins == null) //found below 1.324 + return null; 1.325 + if(c < 0) 1.326 + return t.addLeft(ins); 1.327 + return t.addRight(ins); 1.328 +} 1.329 + 1.330 +Node remove(Node t, Object key, Box found){ 1.331 + if(t == null) 1.332 + return null; //not found indicator 1.333 + int c = doCompare(key, t.key); 1.334 + if(c == 0) 1.335 + { 1.336 + found.val = t; 1.337 + return append(t.left(), t.right()); 1.338 + } 1.339 + Node del = c < 0 ? remove(t.left(), key, found) : remove(t.right(), key, found); 1.340 + if(del == null && found.val == null) //not found below 1.341 + return null; 1.342 + if(c < 0) 1.343 + { 1.344 + if(t.left() instanceof Black) 1.345 + return balanceLeftDel(t.key, t.val(), del, t.right()); 1.346 + else 1.347 + return red(t.key, t.val(), del, t.right()); 1.348 + } 1.349 + if(t.right() instanceof Black) 1.350 + return balanceRightDel(t.key, t.val(), t.left(), del); 1.351 + return red(t.key, t.val(), t.left(), del); 1.352 +// return t.removeLeft(del); 1.353 +// return t.removeRight(del); 1.354 +} 1.355 + 1.356 +static Node append(Node left, Node right){ 1.357 + if(left == null) 1.358 + return right; 1.359 + else if(right == null) 1.360 + return left; 1.361 + else if(left instanceof Red) 1.362 + { 1.363 + if(right instanceof Red) 1.364 + { 1.365 + Node app = append(left.right(), right.left()); 1.366 + if(app instanceof Red) 1.367 + return red(app.key, app.val(), 1.368 + red(left.key, left.val(), left.left(), app.left()), 1.369 + red(right.key, right.val(), app.right(), right.right())); 1.370 + else 1.371 + return red(left.key, left.val(), left.left(), red(right.key, right.val(), app, right.right())); 1.372 + } 1.373 + else 1.374 + return red(left.key, left.val(), left.left(), append(left.right(), right)); 1.375 + } 1.376 + else if(right instanceof Red) 1.377 + return red(right.key, right.val(), append(left, right.left()), right.right()); 1.378 + else //black/black 1.379 + { 1.380 + Node app = append(left.right(), right.left()); 1.381 + if(app instanceof Red) 1.382 + return red(app.key, app.val(), 1.383 + black(left.key, left.val(), left.left(), app.left()), 1.384 + black(right.key, right.val(), app.right(), right.right())); 1.385 + else 1.386 + return balanceLeftDel(left.key, left.val(), left.left(), black(right.key, right.val(), app, right.right())); 1.387 + } 1.388 +} 1.389 + 1.390 +static Node balanceLeftDel(Object key, Object val, Node del, Node right){ 1.391 + if(del instanceof Red) 1.392 + return red(key, val, del.blacken(), right); 1.393 + else if(right instanceof Black) 1.394 + return rightBalance(key, val, del, right.redden()); 1.395 + else if(right instanceof Red && right.left() instanceof Black) 1.396 + return red(right.left().key, right.left().val(), 1.397 + black(key, val, del, right.left().left()), 1.398 + rightBalance(right.key, right.val(), right.left().right(), right.right().redden())); 1.399 + else 1.400 + throw new UnsupportedOperationException("Invariant violation"); 1.401 +} 1.402 + 1.403 +static Node balanceRightDel(Object key, Object val, Node left, Node del){ 1.404 + if(del instanceof Red) 1.405 + return red(key, val, left, del.blacken()); 1.406 + else if(left instanceof Black) 1.407 + return leftBalance(key, val, left.redden(), del); 1.408 + else if(left instanceof Red && left.right() instanceof Black) 1.409 + return red(left.right().key, left.right().val(), 1.410 + leftBalance(left.key, left.val(), left.left().redden(), left.right().left()), 1.411 + black(key, val, left.right().right(), del)); 1.412 + else 1.413 + throw new UnsupportedOperationException("Invariant violation"); 1.414 +} 1.415 + 1.416 +static Node leftBalance(Object key, Object val, Node ins, Node right){ 1.417 + if(ins instanceof Red && ins.left() instanceof Red) 1.418 + return red(ins.key, ins.val(), ins.left().blacken(), black(key, val, ins.right(), right)); 1.419 + else if(ins instanceof Red && ins.right() instanceof Red) 1.420 + return red(ins.right().key, ins.right().val(), 1.421 + black(ins.key, ins.val(), ins.left(), ins.right().left()), 1.422 + black(key, val, ins.right().right(), right)); 1.423 + else 1.424 + return black(key, val, ins, right); 1.425 +} 1.426 + 1.427 + 1.428 +static Node rightBalance(Object key, Object val, Node left, Node ins){ 1.429 + if(ins instanceof Red && ins.right() instanceof Red) 1.430 + return red(ins.key, ins.val(), black(key, val, left, ins.left()), ins.right().blacken()); 1.431 + else if(ins instanceof Red && ins.left() instanceof Red) 1.432 + return red(ins.left().key, ins.left().val(), 1.433 + black(key, val, left, ins.left().left()), 1.434 + black(ins.key, ins.val(), ins.left().right(), ins.right())); 1.435 + else 1.436 + return black(key, val, left, ins); 1.437 +} 1.438 + 1.439 +Node replace(Node t, Object key, Object val){ 1.440 + int c = doCompare(key, t.key); 1.441 + return t.replace(t.key, 1.442 + c == 0 ? val : t.val(), 1.443 + c < 0 ? replace(t.left(), key, val) : t.left(), 1.444 + c > 0 ? replace(t.right(), key, val) : t.right()); 1.445 +} 1.446 + 1.447 +PersistentTreeMap(Comparator comp, Node tree, int count, IPersistentMap meta){ 1.448 + this._meta = meta; 1.449 + this.comp = comp; 1.450 + this.tree = tree; 1.451 + this._count = count; 1.452 +} 1.453 + 1.454 +static Red red(Object key, Object val, Node left, Node right){ 1.455 + if(left == null && right == null) 1.456 + { 1.457 + if(val == null) 1.458 + return new Red(key); 1.459 + return new RedVal(key, val); 1.460 + } 1.461 + if(val == null) 1.462 + return new RedBranch(key, left, right); 1.463 + return new RedBranchVal(key, val, left, right); 1.464 +} 1.465 + 1.466 +static Black black(Object key, Object val, Node left, Node right){ 1.467 + if(left == null && right == null) 1.468 + { 1.469 + if(val == null) 1.470 + return new Black(key); 1.471 + return new BlackVal(key, val); 1.472 + } 1.473 + if(val == null) 1.474 + return new BlackBranch(key, left, right); 1.475 + return new BlackBranchVal(key, val, left, right); 1.476 +} 1.477 + 1.478 +public IPersistentMap meta(){ 1.479 + return _meta; 1.480 +} 1.481 + 1.482 +static abstract class Node extends AMapEntry{ 1.483 + final Object key; 1.484 + 1.485 + Node(Object key){ 1.486 + this.key = key; 1.487 + } 1.488 + 1.489 + public Object key(){ 1.490 + return key; 1.491 + } 1.492 + 1.493 + public Object val(){ 1.494 + return null; 1.495 + } 1.496 + 1.497 + public Object getKey(){ 1.498 + return key(); 1.499 + } 1.500 + 1.501 + public Object getValue(){ 1.502 + return val(); 1.503 + } 1.504 + 1.505 + Node left(){ 1.506 + return null; 1.507 + } 1.508 + 1.509 + Node right(){ 1.510 + return null; 1.511 + } 1.512 + 1.513 + abstract Node addLeft(Node ins); 1.514 + 1.515 + abstract Node addRight(Node ins); 1.516 + 1.517 + abstract Node removeLeft(Node del); 1.518 + 1.519 + abstract Node removeRight(Node del); 1.520 + 1.521 + abstract Node blacken(); 1.522 + 1.523 + abstract Node redden(); 1.524 + 1.525 + Node balanceLeft(Node parent){ 1.526 + return black(parent.key, parent.val(), this, parent.right()); 1.527 + } 1.528 + 1.529 + Node balanceRight(Node parent){ 1.530 + return black(parent.key, parent.val(), parent.left(), this); 1.531 + } 1.532 + 1.533 + abstract Node replace(Object key, Object val, Node left, Node right); 1.534 + 1.535 +} 1.536 + 1.537 +static class Black extends Node{ 1.538 + public Black(Object key){ 1.539 + super(key); 1.540 + } 1.541 + 1.542 + Node addLeft(Node ins){ 1.543 + return ins.balanceLeft(this); 1.544 + } 1.545 + 1.546 + Node addRight(Node ins){ 1.547 + return ins.balanceRight(this); 1.548 + } 1.549 + 1.550 + Node removeLeft(Node del){ 1.551 + return balanceLeftDel(key, val(), del, right()); 1.552 + } 1.553 + 1.554 + Node removeRight(Node del){ 1.555 + return balanceRightDel(key, val(), left(), del); 1.556 + } 1.557 + 1.558 + Node blacken(){ 1.559 + return this; 1.560 + } 1.561 + 1.562 + Node redden(){ 1.563 + return new Red(key); 1.564 + } 1.565 + 1.566 + Node replace(Object key, Object val, Node left, Node right){ 1.567 + return black(key, val, left, right); 1.568 + } 1.569 + 1.570 +} 1.571 + 1.572 +static class BlackVal extends Black{ 1.573 + final Object val; 1.574 + 1.575 + public BlackVal(Object key, Object val){ 1.576 + super(key); 1.577 + this.val = val; 1.578 + } 1.579 + 1.580 + public Object val(){ 1.581 + return val; 1.582 + } 1.583 + 1.584 + Node redden(){ 1.585 + return new RedVal(key, val); 1.586 + } 1.587 + 1.588 +} 1.589 + 1.590 +static class BlackBranch extends Black{ 1.591 + final Node left; 1.592 + 1.593 + final Node right; 1.594 + 1.595 + public BlackBranch(Object key, Node left, Node right){ 1.596 + super(key); 1.597 + this.left = left; 1.598 + this.right = right; 1.599 + } 1.600 + 1.601 + public Node left(){ 1.602 + return left; 1.603 + } 1.604 + 1.605 + public Node right(){ 1.606 + return right; 1.607 + } 1.608 + 1.609 + Node redden(){ 1.610 + return new RedBranch(key, left, right); 1.611 + } 1.612 + 1.613 +} 1.614 + 1.615 +static class BlackBranchVal extends BlackBranch{ 1.616 + final Object val; 1.617 + 1.618 + public BlackBranchVal(Object key, Object val, Node left, Node right){ 1.619 + super(key, left, right); 1.620 + this.val = val; 1.621 + } 1.622 + 1.623 + public Object val(){ 1.624 + return val; 1.625 + } 1.626 + 1.627 + Node redden(){ 1.628 + return new RedBranchVal(key, val, left, right); 1.629 + } 1.630 + 1.631 +} 1.632 + 1.633 +static class Red extends Node{ 1.634 + public Red(Object key){ 1.635 + super(key); 1.636 + } 1.637 + 1.638 + Node addLeft(Node ins){ 1.639 + return red(key, val(), ins, right()); 1.640 + } 1.641 + 1.642 + Node addRight(Node ins){ 1.643 + return red(key, val(), left(), ins); 1.644 + } 1.645 + 1.646 + Node removeLeft(Node del){ 1.647 + return red(key, val(), del, right()); 1.648 + } 1.649 + 1.650 + Node removeRight(Node del){ 1.651 + return red(key, val(), left(), del); 1.652 + } 1.653 + 1.654 + Node blacken(){ 1.655 + return new Black(key); 1.656 + } 1.657 + 1.658 + Node redden(){ 1.659 + throw new UnsupportedOperationException("Invariant violation"); 1.660 + } 1.661 + 1.662 + Node replace(Object key, Object val, Node left, Node right){ 1.663 + return red(key, val, left, right); 1.664 + } 1.665 + 1.666 +} 1.667 + 1.668 +static class RedVal extends Red{ 1.669 + final Object val; 1.670 + 1.671 + public RedVal(Object key, Object val){ 1.672 + super(key); 1.673 + this.val = val; 1.674 + } 1.675 + 1.676 + public Object val(){ 1.677 + return val; 1.678 + } 1.679 + 1.680 + Node blacken(){ 1.681 + return new BlackVal(key, val); 1.682 + } 1.683 + 1.684 +} 1.685 + 1.686 +static class RedBranch extends Red{ 1.687 + final Node left; 1.688 + 1.689 + final Node right; 1.690 + 1.691 + public RedBranch(Object key, Node left, Node right){ 1.692 + super(key); 1.693 + this.left = left; 1.694 + this.right = right; 1.695 + } 1.696 + 1.697 + public Node left(){ 1.698 + return left; 1.699 + } 1.700 + 1.701 + public Node right(){ 1.702 + return right; 1.703 + } 1.704 + 1.705 + Node balanceLeft(Node parent){ 1.706 + if(left instanceof Red) 1.707 + return red(key, val(), left.blacken(), black(parent.key, parent.val(), right, parent.right())); 1.708 + else if(right instanceof Red) 1.709 + return red(right.key, right.val(), black(key, val(), left, right.left()), 1.710 + black(parent.key, parent.val(), right.right(), parent.right())); 1.711 + else 1.712 + return super.balanceLeft(parent); 1.713 + 1.714 + } 1.715 + 1.716 + Node balanceRight(Node parent){ 1.717 + if(right instanceof Red) 1.718 + return red(key, val(), black(parent.key, parent.val(), parent.left(), left), right.blacken()); 1.719 + else if(left instanceof Red) 1.720 + return red(left.key, left.val(), black(parent.key, parent.val(), parent.left(), left.left()), 1.721 + black(key, val(), left.right(), right)); 1.722 + else 1.723 + return super.balanceRight(parent); 1.724 + } 1.725 + 1.726 + Node blacken(){ 1.727 + return new BlackBranch(key, left, right); 1.728 + } 1.729 + 1.730 +} 1.731 + 1.732 + 1.733 +static class RedBranchVal extends RedBranch{ 1.734 + final Object val; 1.735 + 1.736 + public RedBranchVal(Object key, Object val, Node left, Node right){ 1.737 + super(key, left, right); 1.738 + this.val = val; 1.739 + } 1.740 + 1.741 + public Object val(){ 1.742 + return val; 1.743 + } 1.744 + 1.745 + Node blacken(){ 1.746 + return new BlackBranchVal(key, val, left, right); 1.747 + } 1.748 +} 1.749 + 1.750 + 1.751 +static public class Seq extends ASeq{ 1.752 + final ISeq stack; 1.753 + final boolean asc; 1.754 + final int cnt; 1.755 + 1.756 + public Seq(ISeq stack, boolean asc){ 1.757 + this.stack = stack; 1.758 + this.asc = asc; 1.759 + this.cnt = -1; 1.760 + } 1.761 + 1.762 + public Seq(ISeq stack, boolean asc, int cnt){ 1.763 + this.stack = stack; 1.764 + this.asc = asc; 1.765 + this.cnt = cnt; 1.766 + } 1.767 + 1.768 + Seq(IPersistentMap meta, ISeq stack, boolean asc, int cnt){ 1.769 + super(meta); 1.770 + this.stack = stack; 1.771 + this.asc = asc; 1.772 + this.cnt = cnt; 1.773 + } 1.774 + 1.775 + static Seq create(Node t, boolean asc, int cnt){ 1.776 + return new Seq(push(t, null, asc), asc, cnt); 1.777 + } 1.778 + 1.779 + static ISeq push(Node t, ISeq stack, boolean asc){ 1.780 + while(t != null) 1.781 + { 1.782 + stack = RT.cons(t, stack); 1.783 + t = asc ? t.left() : t.right(); 1.784 + } 1.785 + return stack; 1.786 + } 1.787 + 1.788 + public Object first(){ 1.789 + return stack.first(); 1.790 + } 1.791 + 1.792 + public ISeq next(){ 1.793 + Node t = (Node) stack.first(); 1.794 + ISeq nextstack = push(asc ? t.right() : t.left(), stack.next(), asc); 1.795 + if(nextstack != null) 1.796 + { 1.797 + return new Seq(nextstack, asc, cnt - 1); 1.798 + } 1.799 + return null; 1.800 + } 1.801 + 1.802 + public int count(){ 1.803 + if(cnt < 0) 1.804 + return super.count(); 1.805 + return cnt; 1.806 + } 1.807 + 1.808 + public Obj withMeta(IPersistentMap meta){ 1.809 + return new Seq(meta, stack, asc, cnt); 1.810 + } 1.811 +} 1.812 + 1.813 +static public class NodeIterator implements Iterator{ 1.814 + Stack stack = new Stack(); 1.815 + boolean asc; 1.816 + 1.817 + NodeIterator(Node t, boolean asc){ 1.818 + this.asc = asc; 1.819 + push(t); 1.820 + } 1.821 + 1.822 + void push(Node t){ 1.823 + while(t != null) 1.824 + { 1.825 + stack.push(t); 1.826 + t = asc ? t.left() : t.right(); 1.827 + } 1.828 + } 1.829 + 1.830 + public boolean hasNext(){ 1.831 + return !stack.isEmpty(); 1.832 + } 1.833 + 1.834 + public Object next(){ 1.835 + Node t = (Node) stack.pop(); 1.836 + push(asc ? t.right() : t.left()); 1.837 + return t; 1.838 + } 1.839 + 1.840 + public void remove(){ 1.841 + throw new UnsupportedOperationException(); 1.842 + } 1.843 +} 1.844 + 1.845 +static class KeyIterator implements Iterator{ 1.846 + NodeIterator it; 1.847 + 1.848 + KeyIterator(NodeIterator it){ 1.849 + this.it = it; 1.850 + } 1.851 + 1.852 + public boolean hasNext(){ 1.853 + return it.hasNext(); 1.854 + } 1.855 + 1.856 + public Object next(){ 1.857 + return ((Node) it.next()).key; 1.858 + } 1.859 + 1.860 + public void remove(){ 1.861 + throw new UnsupportedOperationException(); 1.862 + } 1.863 +} 1.864 + 1.865 +static class ValIterator implements Iterator{ 1.866 + NodeIterator it; 1.867 + 1.868 + ValIterator(NodeIterator it){ 1.869 + this.it = it; 1.870 + } 1.871 + 1.872 + public boolean hasNext(){ 1.873 + return it.hasNext(); 1.874 + } 1.875 + 1.876 + public Object next(){ 1.877 + return ((Node) it.next()).val(); 1.878 + } 1.879 + 1.880 + public void remove(){ 1.881 + throw new UnsupportedOperationException(); 1.882 + } 1.883 +} 1.884 +/* 1.885 +static public void main(String args[]){ 1.886 + if(args.length != 1) 1.887 + System.err.println("Usage: RBTree n"); 1.888 + int n = Integer.parseInt(args[0]); 1.889 + Integer[] ints = new Integer[n]; 1.890 + for(int i = 0; i < ints.length; i++) 1.891 + { 1.892 + ints[i] = i; 1.893 + } 1.894 + Collections.shuffle(Arrays.asList(ints)); 1.895 + //force the ListMap class loading now 1.896 +// try 1.897 +// { 1.898 +// 1.899 +// //PersistentListMap.EMPTY.assocEx(1, null).assocEx(2,null).assocEx(3,null); 1.900 +// } 1.901 +// catch(Exception e) 1.902 +// { 1.903 +// e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 1.904 +// } 1.905 + System.out.println("Building set"); 1.906 + //IPersistentMap set = new PersistentArrayMap(); 1.907 + //IPersistentMap set = new PersistentHashtableMap(1001); 1.908 + IPersistentMap set = PersistentHashMap.EMPTY; 1.909 + //IPersistentMap set = new ListMap(); 1.910 + //IPersistentMap set = new ArrayMap(); 1.911 + //IPersistentMap set = new PersistentTreeMap(); 1.912 +// for(int i = 0; i < ints.length; i++) 1.913 +// { 1.914 +// Integer anInt = ints[i]; 1.915 +// set = set.add(anInt); 1.916 +// } 1.917 + long startTime = System.nanoTime(); 1.918 + for(Integer anInt : ints) 1.919 + { 1.920 + set = set.assoc(anInt, anInt); 1.921 + } 1.922 + //System.out.println("_count = " + set.count()); 1.923 + 1.924 +// System.out.println("_count = " + set._count + ", min: " + set.minKey() + ", max: " + set.maxKey() 1.925 +// + ", depth: " + set.depth()); 1.926 + for(Object aSet : set) 1.927 + { 1.928 + IMapEntry o = (IMapEntry) aSet; 1.929 + if(!set.contains(o.key())) 1.930 + System.err.println("Can't find: " + o.key()); 1.931 + //else if(n < 2000) 1.932 + // System.out.print(o.key().toString() + ","); 1.933 + } 1.934 + 1.935 + Random rand = new Random(42); 1.936 + for(int i = 0; i < ints.length / 2; i++) 1.937 + { 1.938 + Integer anInt = ints[rand.nextInt(n)]; 1.939 + set = set.without(anInt); 1.940 + } 1.941 + 1.942 + long estimatedTime = System.nanoTime() - startTime; 1.943 + System.out.println(); 1.944 + 1.945 + System.out.println("_count = " + set.count() + ", time: " + estimatedTime / 1000000); 1.946 + 1.947 + System.out.println("Building ht"); 1.948 + Hashtable ht = new Hashtable(1001); 1.949 + startTime = System.nanoTime(); 1.950 +// for(int i = 0; i < ints.length; i++) 1.951 +// { 1.952 +// Integer anInt = ints[i]; 1.953 +// ht.put(anInt,null); 1.954 +// } 1.955 + for(Integer anInt : ints) 1.956 + { 1.957 + ht.put(anInt, anInt); 1.958 + } 1.959 + //System.out.println("size = " + ht.size()); 1.960 + //Iterator it = ht.entrySet().iterator(); 1.961 + for(Object o1 : ht.entrySet()) 1.962 + { 1.963 + Map.Entry o = (Map.Entry) o1; 1.964 + if(!ht.containsKey(o.getKey())) 1.965 + System.err.println("Can't find: " + o); 1.966 + //else if(n < 2000) 1.967 + // System.out.print(o.toString() + ","); 1.968 + } 1.969 + 1.970 + rand = new Random(42); 1.971 + for(int i = 0; i < ints.length / 2; i++) 1.972 + { 1.973 + Integer anInt = ints[rand.nextInt(n)]; 1.974 + ht.remove(anInt); 1.975 + } 1.976 + estimatedTime = System.nanoTime() - startTime; 1.977 + System.out.println(); 1.978 + System.out.println("size = " + ht.size() + ", time: " + estimatedTime / 1000000); 1.979 + 1.980 + System.out.println("set lookup"); 1.981 + startTime = System.nanoTime(); 1.982 + int c = 0; 1.983 + for(Integer anInt : ints) 1.984 + { 1.985 + if(!set.contains(anInt)) 1.986 + ++c; 1.987 + } 1.988 + estimatedTime = System.nanoTime() - startTime; 1.989 + System.out.println("notfound = " + c + ", time: " + estimatedTime / 1000000); 1.990 + 1.991 + System.out.println("ht lookup"); 1.992 + startTime = System.nanoTime(); 1.993 + c = 0; 1.994 + for(Integer anInt : ints) 1.995 + { 1.996 + if(!ht.containsKey(anInt)) 1.997 + ++c; 1.998 + } 1.999 + estimatedTime = System.nanoTime() - startTime; 1.1000 + System.out.println("notfound = " + c + ", time: " + estimatedTime / 1000000); 1.1001 + 1.1002 +// System.out.println("_count = " + set._count + ", min: " + set.minKey() + ", max: " + set.maxKey() 1.1003 +// + ", depth: " + set.depth()); 1.1004 +} 1.1005 +*/ 1.1006 +}