1 package com.jofti.util; 2 3 import java.util.AbstractCollection ; 4 import java.util.AbstractMap ; 5 import java.util.AbstractSet ; 6 import java.util.ArrayList ; 7 import java.util.Collection ; 8 import java.util.Comparator ; 9 import java.util.ConcurrentModificationException ; 10 import java.util.HashMap ; 11 import java.util.Iterator ; 12 import java.util.List ; 13 import java.util.Map ; 14 import java.util.NoSuchElementException ; 15 import java.util.Set ; 16 import java.util.SortedMap ; 17 import java.util.SortedSet ; 18 19 20 26 27 28 52 53 public class ValueTreeMap extends AbstractMap 54 implements Cloneable , java.io.Serializable 55 { 56 62 63 private final DefaultComparator DEFAULT_COMPARATOR = new DefaultComparator(); 64 private Comparator comparator = DEFAULT_COMPARATOR; 65 66 private transient Entry root = null; 67 68 71 private transient int size = 0; 72 73 76 private transient int modCount = 0; 77 78 private void incrementSize() { modCount++; size++; } 79 private void decrementSize() { modCount++; size--; } 80 81 transient volatile Set keySet = null; 83 transient volatile Collection values = null; 84 85 86 87 100 public ValueTreeMap() { 101 } 102 103 116 public ValueTreeMap(Comparator c) { 117 this.comparator = c; 118 } 119 120 134 public ValueTreeMap(Map m) { 135 putAll(m); 136 } 137 138 147 public ValueTreeMap(SortedMap m) { 148 comparator = m.comparator(); 149 try { 150 buildFromSorted(m.size(), m.entrySet().iterator(), null, null); 151 } catch (java.io.IOException cannotHappen) { 152 } catch (ClassNotFoundException cannotHappen) { 153 } 154 } 155 156 157 159 164 public int size() { 165 return size; 166 } 167 168 182 public boolean containsKey(Object key) { 183 return getEntry(key) != null; 184 } 185 186 199 public boolean containsValue(Object value) { 200 return (root==null ? false : 201 (value==null ? valueSearchNull(root) 202 : valueSearchNonNull(root, value))); 203 } 204 205 private boolean valueSearchNull(Entry n) { 206 if (n.value == null) 207 return true; 208 209 return (n.left != null && valueSearchNull(n.left)) || 211 (n.right != null && valueSearchNull(n.right)); 212 } 213 214 private boolean valueSearchNonNull(Entry n, Object value) { 215 if (value.equals(n.value)) 217 return true; 218 219 return (n.left != null && valueSearchNonNull(n.left, value)) || 221 (n.right != null && valueSearchNonNull(n.right, value)); 222 } 223 224 private Entry keySearchNonNull(Entry n, Object key) { 225 if (key.equals(n.key)) 227 return n; 228 229 Entry temp =null; 230 if (n.left != null ){ 231 temp= keySearchNonNull(n.left, key); 232 }if (temp == null && n.right != null){ 233 temp=keySearchNonNull(n.right, key); 234 }else if (temp ==null){ 235 return null; 236 } 237 return temp; 238 } 239 240 241 private Entry keyGetListNonNull(Entry n, Object key,List values) { 242 if (key.equals(n.key)){ 244 values.add(n.value); 245 } 246 Entry temp =null; 247 if (n.left != null ){ 248 temp= keyGetListNonNull(n.left, key,values); 249 }if (temp ==null && n.right != null){ 250 temp=keyGetListNonNull(n.right, key,values); 251 }else{ 252 return null; 253 } 254 return temp; 255 } 256 257 276 public Object get(Object key) { 277 return getEntryList(key); 278 } 279 280 287 public Comparator comparator() { 288 return comparator; 289 } 290 291 297 public Object firstKey() { 298 return key(firstEntry()); 299 } 300 301 307 public Object lastKey() { 308 return key(lastEntry()); 309 } 310 311 314 public void putAll(Map map) { 315 throw new UnsupportedOperationException ("ValueTreeMap is readonly"); 316 } 317 318 330 private Entry getEntry(Object key) { 331 332 333 Entry p = root; 334 335 if (comparator == DEFAULT_COMPARATOR){ 337 338 Entry temp = new Entry(key,null,null); 339 while (p != null) { 340 int cmp = compare(temp,p); 341 if (cmp == 0) 342 return p; 343 else if (cmp < 0) 344 p = p.left; 345 else 346 p = p.right; 347 } 348 return null; 349 }else{ 351 return (root==null ? null : 352 (key==null ? null 353 : keySearchNonNull(root, key))); 354 } 355 356 } 357 358 private List getEntryList(Object key) { 359 360 361 Entry p = root; 362 List tempList = new ArrayList (); 363 if (comparator == DEFAULT_COMPARATOR){ 365 366 Entry temp = new Entry(key,null,null); 367 while (p != null) { 368 int cmp = compare(temp,p); 369 if (cmp == 0){ 370 tempList.add(p.value); 371 return tempList;} 372 else if (cmp < 0) 373 p = p.left; 374 else 375 p = p.right; 376 } 377 return null; 378 }else{ 380 if (key ==null || root ==null){ 381 return tempList; 382 }else{ 383 keyGetListNonNull(root, key,tempList); 384 return tempList; 385 } 386 } 387 388 } 389 private Entry getTreeEntry(Map.Entry temp) { 390 391 392 Entry p = root; 393 394 while (p != null) { 395 int cmp = compare(temp,p); 396 if (cmp == 0) 397 return p; 398 else if (cmp < 0) 399 p = p.left; 400 else 401 p = p.right; 402 } 403 return null; 404 405 } 406 407 408 489 493 private static Object key(Entry e) { 494 if (e==null) 495 throw new NoSuchElementException (); 496 return e.key; 497 } 498 499 517 public Object put(Object key, Object value) { 518 519 Entry t = root; 520 521 if (t == null) { 522 incrementSize(); 523 root = new Entry(key, value, null); 524 return null; 525 } 526 Entry temp = new Entry(key,value,null); 527 while (true) { 528 int cmp = compare(temp, t); 529 if (cmp == 0) { 530 return t.setValue(value); 531 } else if (cmp < 0) { 532 if (t.left != null) { 533 t = t.left; 534 } else { 535 incrementSize(); 536 537 t.left = new Entry(key, value, t); 538 fixAfterInsertion(t.left); 539 return null; 540 } 541 } else { if (t.right != null) { 543 t = t.right; 544 } else { 545 incrementSize(); 546 547 t.right = new Entry(key, value, t); 548 fixAfterInsertion(t.right); 549 return null; 550 } 551 } 552 } 553 } 554 555 570 public Object remove(Object key) { 571 Entry p = getEntry(key); 572 List oldValues =new ArrayList (); 573 574 while (p != null){ 575 576 oldValues.add(p.value); 577 deleteEntry(p); 578 p = getEntry(key); 579 } 580 return oldValues; 581 } 582 583 public Object removeEntry(Object key,Object value) { 584 Entry p = getTreeEntry(new Entry(key,value,null)); 585 Object oldValue = p.value; 586 deleteEntry(p); 587 return oldValue; 588 } 589 592 public void clear() { 593 modCount++; 594 size = 0; 595 root = null; 596 597 } 598 599 605 public Object clone() { 606 ValueTreeMap clone = null; 607 try { 608 clone = (ValueTreeMap)super.clone(); 609 } catch (CloneNotSupportedException e) { 610 throw new InternalError (); 611 } 612 613 clone.root = null; 615 clone.size = 0; 616 clone.modCount = 0; 617 clone.entrySet = null; 618 619 try { 621 clone.buildFromSorted(size, entrySet().iterator(), null, null); 622 } catch (java.io.IOException cannotHappen) { 623 } catch (ClassNotFoundException cannotHappen) { 624 } 625 return clone; 626 } 627 628 629 631 636 private transient volatile Set entrySet = null; 637 638 650 public Set keySet() { 651 if (keySet == null) { 652 keySet = new AbstractSet () { 653 public Iterator iterator() { 654 return new KeyIterator(); 655 } 656 657 public int size() { 658 return ValueTreeMap.this.size(); 659 } 660 661 public boolean contains(Object o) { 662 return containsKey(o); 663 } 664 665 public boolean remove(Object o) { 666 if (o != null) { 667 return ValueTreeMap.this.remove(o) ==null; 668 } 669 return false; 670 } 671 672 public void clear() { 673 ValueTreeMap.this.clear(); 674 } 675 }; 676 } 677 return keySet; 678 } 679 680 693 public Collection values() { 694 if (values == null) { 695 values = new AbstractCollection () { 696 public Iterator iterator() { 697 return new ValueIterator(); 698 } 699 700 public int size() { 701 return ValueTreeMap.this.size(); 702 } 703 704 public boolean contains(Object o) { 705 for (Entry e = firstEntry(); e != null; e = successor(e)) 706 if (valEquals(e.getValue(), o)) 707 return true; 708 return false; 709 } 710 711 public boolean remove(Object o) { 712 for (Entry e = firstEntry(); e != null; e = successor(e)) { 713 if (valEquals(e.getValue(), o)) { 714 deleteEntry(e); 715 return true; 716 } 717 } 718 return false; 719 } 720 721 public void clear() { 722 ValueTreeMap.this.clear(); 723 } 724 }; 725 } 726 return values; 727 } 728 729 743 public Set entrySet() { 744 if (entrySet == null) { 745 entrySet = new AbstractSet () { 746 public Iterator iterator() { 747 return new EntryIterator(); 748 } 749 750 public boolean contains(Object o) { 751 if (!(o instanceof Map.Entry )) 752 return false; 753 Map.Entry entry = (Map.Entry )o; 754 755 Entry p = getTreeEntry(entry); 756 return p != null; 757 } 758 759 public boolean remove(Object o) { 760 if (!(o instanceof Map.Entry )) 761 return false; 762 Map.Entry entry = (Map.Entry )o; 763 Entry p = getTreeEntry(entry); 764 if (p != null) { 765 deleteEntry(p); 766 767 return true; 768 } 769 return false; 770 } 771 772 public int size() { 773 return ValueTreeMap.this.size(); 774 } 775 776 public void clear() { 777 ValueTreeMap.this.clear(); 778 } 779 }; 780 } 781 return entrySet; 782 } 783 784 828 1078 1081 private class EntryIterator implements Iterator { 1082 private int expectedModCount = ValueTreeMap.this.modCount; 1083 private Entry lastReturned = null; 1084 Entry next; 1085 1086 EntryIterator() { 1087 next = firstEntry(); 1088 } 1089 1090 EntryIterator(Entry first) { 1092 next = first; 1093 } 1094 1095 public boolean hasNext() { 1096 return next != null; 1097 } 1098 1099 final Entry nextEntry() { 1100 if (next == null) 1101 throw new NoSuchElementException (); 1102 if (modCount != expectedModCount) 1103 throw new ConcurrentModificationException (); 1104 lastReturned = next; 1105 next = successor(next); 1106 return lastReturned; 1107 } 1108 1109 public Object next() { 1110 return nextEntry(); 1111 } 1112 1113 public void remove() { 1114 if (lastReturned == null) 1115 throw new IllegalStateException (); 1116 if (modCount != expectedModCount) 1117 throw new ConcurrentModificationException (); 1118 if (lastReturned.left != null && lastReturned.right != null) 1119 next = lastReturned; 1120 deleteEntry(lastReturned); 1121 expectedModCount++; 1122 lastReturned = null; 1123 } 1124 } 1125 1126 private class KeyIterator extends EntryIterator { 1127 public Object next() { 1128 return nextEntry().key; 1129 } 1130 } 1131 1132 private class ValueIterator extends EntryIterator { 1133 public Object next() { 1134 return nextEntry().value; 1135 } 1136 } 1137 1138 private class SubMapEntryIterator extends EntryIterator { 1139 private final Object firstExcludedKey; 1140 1141 SubMapEntryIterator(Entry first, Entry firstExcluded) { 1142 super(first); 1143 firstExcludedKey = (firstExcluded == null ? 1144 firstExcluded : firstExcluded.key); 1145 } 1146 1147 public boolean hasNext() { 1148 return next != null && next.key != firstExcludedKey; 1149 } 1150 1151 public Object next() { 1152 if (next == null || next.key == firstExcludedKey) 1153 throw new NoSuchElementException (); 1154 return nextEntry(); 1155 } 1156 } 1157 1158 1161 private int compare(Map.Entry k1, Map.Entry k2) { 1162 int res = (comparator==null ? ((Comparable )k1.getKey()).compareTo(k2.getKey()) 1163 : comparator.compare(k1, k2)); 1164 if (res ==0 && comparator != DEFAULT_COMPARATOR){ 1165 res =((Comparable )k1.getKey()).compareTo(k2.getKey()); 1166 } 1167 return res; 1168 } 1169 1170 1171 1175 private static boolean valEquals(Object o1, Object o2) { 1176 return (o1==null ? o2==null : o1.equals(o2)); 1177 } 1178 1179 private static final boolean RED = false; 1180 private static final boolean BLACK = true; 1181 1182 1186 1187 static class Entry implements Map.Entry { 1188 Object key; 1189 Object value; 1190 Entry left = null; 1191 Entry right = null; 1192 Entry parent; 1193 boolean color = BLACK; 1194 1195 1199 Entry(Object key, Object value, Entry parent) { 1200 this.key = key; 1201 this.value = value; 1202 this.parent = parent; 1203 } 1204 1205 1210 public Object getKey() { 1211 return key; 1212 } 1213 1214 1219 public Object getValue() { 1220 return value; 1221 } 1222 1223 1230 public Object setValue(Object value) { 1231 Object oldValue = this.value; 1232 this.value = value; 1233 return oldValue; 1234 } 1235 1236 public boolean equals(Object o) { 1237 if (!(o instanceof Map.Entry )) 1238 return false; 1239 Map.Entry e = (Map.Entry )o; 1240 1241 return valEquals(key,e.getKey()) && valEquals(value,e.getValue()); 1242 } 1243 1244 public int hashCode() { 1245 int keyHash = (key==null ? 0 : key.hashCode()); 1246 int valueHash = (value==null ? 0 : value.hashCode()); 1247 return keyHash ^ valueHash; 1248 } 1249 1250 public String toString() { 1251 return key + "=" + value; 1252 } 1253 } 1254 1255 1259 private Entry firstEntry() { 1260 Entry p = root; 1261 if (p != null) 1262 while (p.left != null) 1263 p = p.left; 1264 return p; 1265 } 1266 1267 public Map getSubMap(int startEntry, int maxNumber){ 1268 int count =0; 1269 1270 if (startEntry <0){ 1271 throw new RuntimeException ("the start entry for a subset limit cannot be negative: "+startEntry); 1272 } 1273 if(maxNumber <0){ 1274 throw new RuntimeException ("the max number of entries cannot be negative:" + maxNumber); 1275 } 1276 1277 Map returnMap = new ValueTreeMap(comparator); 1278 1279 Entry t = firstEntry(); 1281 1282 while (count < startEntry){ 1283 t = successor(t); 1284 if (t ==null){ 1285 return returnMap; 1286 } 1287 count++; 1288 } 1289 returnMap.put(t.key, t.value); 1291 1292 count =1; 1293 1294 while(count < maxNumber){ 1295 t =successor(t); 1296 if (t != null){ 1297 returnMap.put(t.key, t.value); 1298 }else{ 1299 break; 1301 } 1302 count++; 1303 } 1304 1305 1306 return returnMap; 1307 } 1308 1312 private Entry lastEntry() { 1313 Entry p = root; 1314 if (p != null) 1315 while (p.right != null) 1316 p = p.right; 1317 return p; 1318 } 1319 1320 1323 private Entry successor(Entry t) { 1324 if (t == null) 1325 return null; 1326 else if (t.right != null) { 1327 Entry p = t.right; 1328 while (p.left != null) 1329 p = p.left; 1330 return p; 1331 } else { 1332 Entry p = t.parent; 1333 Entry ch = t; 1334 while (p != null && ch == p.right) { 1335 ch = p; 1336 p = p.parent; 1337 } 1338 return p; 1339 } 1340 } 1341 1342 1351 1352 private static boolean colorOf(Entry p) { 1353 return (p == null ? BLACK : p.color); 1354 } 1355 1356 private static Entry parentOf(Entry p) { 1357 return (p == null ? null: p.parent); 1358 } 1359 1360 private static void setColor(Entry p, boolean c) { 1361 if (p != null) p.color = c; 1362 } 1363 1364 private static Entry leftOf(Entry p) { 1365 return (p == null)? null: p.left; 1366 } 1367 1368 private static Entry rightOf(Entry p) { 1369 return (p == null)? null: p.right; 1370 } 1371 1372 1373 private void rotateLeft(Entry p) { 1374 Entry r = p.right; 1375 p.right = r.left; 1376 if (r.left != null) 1377 r.left.parent = p; 1378 r.parent = p.parent; 1379 if (p.parent == null) 1380 root = r; 1381 else if (p.parent.left == p) 1382 p.parent.left = r; 1383 else 1384 p.parent.right = r; 1385 r.left = p; 1386 p.parent = r; 1387 } 1388 1389 1390 private void rotateRight(Entry p) { 1391 Entry l = p.left; 1392 p.left = l.right; 1393 if (l.right != null) l.right.parent = p; 1394 l.parent = p.parent; 1395 if (p.parent == null) 1396 root = l; 1397 else if (p.parent.right == p) 1398 p.parent.right = l; 1399 else p.parent.left = l; 1400 l.right = p; 1401 p.parent = l; 1402 } 1403 1404 1405 1406 private void fixAfterInsertion(Entry x) { 1407 x.color = RED; 1408 1409 while (x != null && x != root && x.parent.color == RED) { 1410 if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { 1411 Entry y = rightOf(parentOf(parentOf(x))); 1412 if (colorOf(y) == RED) { 1413 setColor(parentOf(x), BLACK); 1414 setColor(y, BLACK); 1415 setColor(parentOf(parentOf(x)), RED); 1416 x = parentOf(parentOf(x)); 1417 } else { 1418 if (x == rightOf(parentOf(x))) { 1419 x = parentOf(x); 1420 rotateLeft(x); 1421 } 1422 setColor(parentOf(x), BLACK); 1423 setColor(parentOf(parentOf(x)), RED); 1424 if (parentOf(parentOf(x)) != null) 1425 rotateRight(parentOf(parentOf(x))); 1426 } 1427 } else { 1428 Entry y = leftOf(parentOf(parentOf(x))); 1429 if (colorOf(y) == RED) { 1430 setColor(parentOf(x), BLACK); 1431 setColor(y, BLACK); 1432 setColor(parentOf(parentOf(x)), RED); 1433 x = parentOf(parentOf(x)); 1434 } else { 1435 if (x == leftOf(parentOf(x))) { 1436 x = parentOf(x); 1437 rotateRight(x); 1438 } 1439 setColor(parentOf(x), BLACK); 1440 setColor(parentOf(parentOf(x)), RED); 1441 if (parentOf(parentOf(x)) != null) 1442 rotateLeft(parentOf(parentOf(x))); 1443 } 1444 } 1445 } 1446 root.color = BLACK; 1447 } 1448 1449 1452 1453 private void deleteEntry(Entry p) { 1454 decrementSize(); 1455 1456 if (p.left != null && p.right != null) { 1459 Entry s = successor (p); 1460 p.key = s.key; 1461 p.value = s.value; 1462 p = s; 1463 } 1465 Entry replacement = (p.left != null ? p.left : p.right); 1467 1468 if (replacement != null) { 1469 replacement.parent = p.parent; 1471 if (p.parent == null) 1472 root = replacement; 1473 else if (p == p.parent.left) 1474 p.parent.left = replacement; 1475 else 1476 p.parent.right = replacement; 1477 1478 p.left = p.right = p.parent = null; 1480 1481 if (p.color == BLACK) 1483 fixAfterDeletion(replacement); 1484 } else if (p.parent == null) { root = null; 1486 } else { if (p.color == BLACK) 1488 fixAfterDeletion(p); 1489 1490 if (p.parent != null) { 1491 if (p == p.parent.left) 1492 p.parent.left = null; 1493 else if (p == p.parent.right) 1494 p.parent.right = null; 1495 p.parent = null; 1496 } 1497 } 1498 } 1499 1500 1501 private void fixAfterDeletion(Entry x) { 1502 while (x != root && colorOf(x) == BLACK) { 1503 if (x == leftOf(parentOf(x))) { 1504 Entry sib = rightOf(parentOf(x)); 1505 1506 if (colorOf(sib) == RED) { 1507 setColor(sib, BLACK); 1508 setColor(parentOf(x), RED); 1509 rotateLeft(parentOf(x)); 1510 sib = rightOf(parentOf(x)); 1511 } 1512 1513 if (colorOf(leftOf(sib)) == BLACK && 1514 colorOf(rightOf(sib)) == BLACK) { 1515 setColor(sib, RED); 1516 x = parentOf(x); 1517 } else { 1518 if (colorOf(rightOf(sib)) == BLACK) { 1519 setColor(leftOf(sib), BLACK); 1520 setColor(sib, RED); 1521 rotateRight(sib); 1522 sib = rightOf(parentOf(x)); 1523 } 1524 setColor(sib, colorOf(parentOf(x))); 1525 setColor(parentOf(x), BLACK); 1526 setColor(rightOf(sib), BLACK); 1527 rotateLeft(parentOf(x)); 1528 x = root; 1529 } 1530 } else { Entry sib = leftOf(parentOf(x)); 1532 1533 if (colorOf(sib) == RED) { 1534 setColor(sib, BLACK); 1535 setColor(parentOf(x), RED); 1536 rotateRight(parentOf(x)); 1537 sib = leftOf(parentOf(x)); 1538 } 1539 1540 if (colorOf(rightOf(sib)) == BLACK && 1541 colorOf(leftOf(sib)) == BLACK) { 1542 setColor(sib, RED); 1543 x = parentOf(x); 1544 } else { 1545 if (colorOf(leftOf(sib)) == BLACK) { 1546 setColor(rightOf(sib), BLACK); 1547 setColor(sib, RED); 1548 rotateLeft(sib); 1549 sib = leftOf(parentOf(x)); 1550 } 1551 setColor(sib, colorOf(parentOf(x))); 1552 setColor(parentOf(x), BLACK); 1553 setColor(leftOf(sib), BLACK); 1554 rotateRight(parentOf(x)); 1555 x = root; 1556 } 1557 } 1558 } 1559 1560 setColor(x, BLACK); 1561 } 1562 1563 private static final long serialVersionUID = 919286545866124006L; 1564 1565 1577 private void writeObject(java.io.ObjectOutputStream s) 1578 throws java.io.IOException { 1579 s.defaultWriteObject(); 1581 1582 s.writeInt(size); 1584 1585 for (Iterator i = entrySet().iterator(); i.hasNext(); ) { 1587 Entry e = (Entry)i.next(); 1588 s.writeObject(e.key); 1589 s.writeObject(e.value); 1590 } 1591 } 1592 1593 1594 1595 1599 private void readObject(final java.io.ObjectInputStream s) 1600 throws java.io.IOException , ClassNotFoundException { 1601 s.defaultReadObject(); 1603 1604 int size = s.readInt(); 1606 1607 buildFromSorted(size, null, s, null); 1608 } 1609 1610 1611 void readTreeSet(int size, java.io.ObjectInputStream s, Object defaultVal) 1612 throws java.io.IOException , ClassNotFoundException { 1613 buildFromSorted(size, null, s, defaultVal); 1614 } 1615 1616 1617 void addAllForTreeSet(SortedSet set, Object defaultVal) { 1618 try { 1619 buildFromSorted(set.size(), set.iterator(), null, defaultVal); 1620 } catch (java.io.IOException cannotHappen) { 1621 } catch (ClassNotFoundException cannotHappen) { 1622 } 1623 } 1624 1625 1626 1656 private void buildFromSorted(int size, Iterator it, 1657 java.io.ObjectInputStream str, 1658 Object defaultVal) 1659 throws java.io.IOException , ClassNotFoundException { 1660 this.size = size; 1661 root = buildFromSorted(0, 0, size-1, computeRedLevel(size), 1662 it, str, defaultVal); 1663 } 1664 1665 1679 private static Entry buildFromSorted(int level, int lo, int hi, 1680 int redLevel, 1681 Iterator it, 1682 java.io.ObjectInputStream str, 1683 Object defaultVal) 1684 throws java.io.IOException , ClassNotFoundException { 1685 1696 1697 if (hi < lo) return null; 1698 1699 int mid = (lo + hi) / 2; 1700 1701 Entry left = null; 1702 if (lo < mid) 1703 left = buildFromSorted(level+1, lo, mid - 1, redLevel, 1704 it, str, defaultVal); 1705 1706 Object key; 1708 Object value; 1709 if (it != null) { if (defaultVal==null) { 1711 Map.Entry entry = (Map.Entry ) it.next(); 1712 key = entry.getKey(); 1713 value = entry.getValue(); 1714 } else { 1715 key = it.next(); 1716 value = defaultVal; 1717 } 1718 } else { key = str.readObject(); 1720 value = (defaultVal != null ? defaultVal : str.readObject()); 1721 } 1722 1723 Entry middle = new Entry(key, value, null); 1724 if (level == redLevel) 1726 middle.color = RED; 1727 1728 if (left != null) { 1729 middle.left = left; 1730 left.parent = middle; 1731 } 1732 1733 if (mid < hi) { 1734 Entry right = buildFromSorted(level+1, mid+1, hi, redLevel, 1735 it, str, defaultVal); 1736 middle.right = right; 1737 right.parent = middle; 1738 } 1739 1740 return middle; 1741 } 1742 1743 1752 private static int computeRedLevel(int sz) { 1753 int level = 0; 1754 for (int m = sz - 1; m >= 0; m = m / 2 - 1) 1755 level++; 1756 return level; 1757 } 1758 1759 class DefaultComparator implements Comparator { 1760 1761 public int compare(Object o1, Object o2) 1762 { 1763 Map.Entry entry1 = (Map.Entry )o1; 1764 Map.Entry entry2 = (Map.Entry )o2; 1765 1766 1767 return ((Comparable )entry1.getKey()).compareTo(entry2.getKey()); 1768 1769 } 1770 1771 }; 1772} 1773 | Popular Tags |