├── .idea ├── compiler.xml ├── description.html ├── encodings.xml ├── libraries │ └── commons_codec_1_10.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml ├── vcs.xml └── workspace.xml ├── README.md ├── chord.iml ├── img-explane ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png └── 8.png ├── lib ├── commons-codec-1.10.jar ├── hamcrest-all-1.3.jar ├── junit-4.12.jar └── netty-all-4.1.42.Final.jar └── src ├── main └── net │ └── yzx66 │ ├── Main.java │ ├── commen │ ├── Chord.java │ ├── ChordStruct.java │ ├── DataOperate.java │ ├── IPNode.java │ └── abs │ │ ├── AbstractChordStruct.java │ │ ├── AbstractDataOperate.java │ │ ├── ChordStructPostProcessor.java │ │ └── DataOperatePostProcessor.java │ ├── operate │ └── SelfOperateFunctionAchieve.java │ ├── struct │ ├── SkipList.java │ ├── StructBasic.java │ ├── StructBasicTemplate.java │ ├── Tree.java │ └── chord │ │ ├── SelfStructFunctionAchieve.java │ │ └── enhanced │ │ ├── EnhancedSkipList.java │ │ ├── EnhancedTree.java │ │ └── StructEnhanced.java │ ├── type │ ├── cluster │ │ ├── ClusterChordStruct.java │ │ ├── ClusterSelfOperate.java │ │ └── socket │ │ │ └── ChordServer.java │ └── single │ │ ├── SingleChordStruct.java │ │ └── SingleSelfOperate.java │ └── utils │ ├── MD5Util.java │ └── StringUtil.java └── test └── net └── yzx66 ├── struct ├── SkipListTest.java ├── TreeTest.java └── chord │ ├── EnhancedSkipListTest.java │ └── EnhancedTreeTest.java └── utils ├── MD5UtilTest.java └── StringUtilTest.java /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/description.html: -------------------------------------------------------------------------------- 1 | Simple Java application that includes a class with main() method -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/libraries/commons_codec_1_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 13 | 23 | 24 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 480 | 481 | 482 | 483 | 495 | 496 | 497 | 498 | 499 | 502 | 503 | 511 | 512 | 513 | 514 | 515 | 518 | 519 | 527 | 528 | 529 | 530 | 531 | 534 | 535 | 543 | 544 | 545 | 546 | 547 | 550 | 551 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 1588270963881 576 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 676 | 677 | 678 | 679 | 680 | file://$PROJECT_DIR$/src/main/net/yzx66/Main.java 681 | 77 682 | 683 | 685 | 686 | file://$PROJECT_DIR$/src/main/net/yzx66/commen/IPNode.java 687 | 65 688 | 689 | 691 | 692 | file://$PROJECT_DIR$/src/main/net/yzx66/struct/SkipList.java 693 | 166 694 | 695 | 697 | 698 | file://$PROJECT_DIR$/src/main/net/yzx66/struct/SkipList.java 699 | 171 700 | 701 | 703 | 704 | file://$PROJECT_DIR$/src/main/net/yzx66/struct/SkipList.java 705 | 94 706 | 707 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | ip.replaceAll("\\.","") 716 | JAVA 717 | EXPRESSION 718 | 719 | 720 | ip.replaceAll(".","") 721 | JAVA 722 | EXPRESSION 723 | 724 | 725 | ip.replace(".","") 726 | JAVA 727 | EXPRESSION 728 | 729 | 730 | ip.replace("1","9") 731 | JAVA 732 | EXPRESSION 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | JAVA 767 | java.lang.Override 768 | 769 | java.lang.Override 770 | java.lang.annotation.Annotation 771 | java.lang.annotation.Target 772 | java.lang.annotation.Retention 773 | 774 | 775 | 776 | 777 | 778 | 779 | All 780 | private 781 | 782 | 783 | 784 | 785 | 786 | 787 | JAVA 788 | net.yzx66.commen.Chord 789 | 790 | net.yzx66.commen.Chord 791 | net.yzx66.commen.ChordStruct 792 | net.yzx66.commen.DataOperate 793 | 794 | 795 | 796 | 797 | 798 | 799 | All 800 | private 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | JAVA 826 | net.yzx66.type.single.SingleDataOperate 827 | 828 | net.yzx66.commen.abs.AbstractDataOperate 829 | net.yzx66.operate.DataOperateTemplate 830 | net.yzx66.commen.DataOperate 831 | net.yzx66.type.single.SingleDataOperate 832 | net.yzx66.operate.DataOperatePostProcessor 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | All 861 | private 862 | 863 | 864 | 865 | 866 | 867 | 868 | JAVA 869 | net.yzx66.type.single.SingleTreeChordStruct 870 | 871 | net.yzx66.struct.chord.ChordStructTemplate 872 | net.yzx66.commen.ChordStruct 873 | net.yzx66.struct.chord.SelfStructFunctionAchieve 874 | net.yzx66.struct.chord.ChordStructPostProcessor 875 | net.yzx66.type.single.SingleTreeChordStruct 876 | net.yzx66.commen.abs.AbstractChordStruct 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | All 909 | private 910 | 911 | 912 | 913 | 914 | 915 | 916 | JAVA 917 | net.yzx66.struct.chord.enhanced.EnhancedTree 918 | 919 | net.yzx66.struct.chord.enhanced.StructEnhanced 920 | net.yzx66.struct.StructBasicTemplate 921 | net.yzx66.struct.chord.enhanced.EnhancedTree 922 | net.yzx66.struct.Tree 923 | net.yzx66.struct.StructBasic 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | All 960 | private 961 | 962 | 963 | 964 | 965 | 966 | 967 | JAVA 968 | net.yzx66.struct 969 | 970 | net.yzx66.struct.chord.enhanced.StructEnhanced 971 | net.yzx66.struct.chord.enhanced.EnhancedTree 972 | net.yzx66.struct.chord.ChordStructTemplate 973 | net.yzx66.struct.StructBasicTemplate 974 | net.yzx66.struct.SkipList 975 | net.yzx66.struct.Tree 976 | net.yzx66.struct.StructBasic 977 | net.yzx66.struct.chord.SelfStructFunctionAchieve 978 | net.yzx66.struct.chord.ChordStructPostProcessor 979 | net.yzx66.struct.chord.enhanced.EnhancedSkipList 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | All 1060 | private 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | JAVA 1069 | net.yzx66 1070 | 1071 | net.yzx66.type.cluster.socket 1072 | net.yzx66.utils.MD5UtilTest 1073 | net.yzx66.struct.chord.enhanced.EnhancedTree 1074 | net.yzx66.struct.StructBasicTemplate 1075 | net.yzx66.struct.SkipList 1076 | net.yzx66.commen.abs.AbstractDataOperate 1077 | net.yzx66.type.cluster.ClusterSelfOperate 1078 | net.yzx66.struct.chord.EnhancedSkipListTest 1079 | net.yzx66.commen.Chord 1080 | net.yzx66.utils.StringUtilTest 1081 | net.yzx66.struct.chord.enhanced.EnhancedSkipList 1082 | net.yzx66.type.cluster.ClusterChordStruct 1083 | net.yzx66.type.single.SingleSelfOperate 1084 | net.yzx66.struct.StructBasic 1085 | net.yzx66.commen.DataOperate 1086 | net.yzx66.commen.IPNode.Entry 1087 | net.yzx66.struct.SkipListTest 1088 | net.yzx66.commen.abs.AbstractChordStruct 1089 | net.yzx66.utils.MD5Util 1090 | net.yzx66.commen.IPNode.Lazy 1091 | net.yzx66.struct.Tree 1092 | net.yzx66.operate.SelfOperateFunctionAchieve 1093 | net.yzx66.commen.ChordStruct 1094 | net.yzx66.type.single.SingleChordStruct 1095 | net.yzx66.commen.abs.ChordStructPostProcessor 1096 | net.yzx66.struct.chord.SelfStructFunctionAchieve 1097 | net.yzx66.commen.abs.DataOperatePostProcessor 1098 | net.yzx66.struct.chord.enhanced.StructEnhanced 1099 | net.yzx66.struct.TreeTest 1100 | net.yzx66.utils.StringUtil 1101 | net.yzx66.struct.SkipList.Node 1102 | net.yzx66.struct.Tree.Node 1103 | net.yzx66.Main 1104 | net.yzx66.commen.IPNode 1105 | net.yzx66.struct.chord.EnhancedTreeTest 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1185 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | All 1232 | private 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 1288 | 1289 | 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | 1309 | 1310 | 1311 | 1312 | 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1345 | 1346 | 1347 | 1348 | 1349 | 1350 | 1351 | 1352 | 1353 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1360 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1372 | 1373 | 1374 | 1375 | 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1490 | 1491 | 1492 | 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | 1504 | 1505 | 1506 | 1507 | 1508 | 1509 | 1510 | 1511 | 1512 | 1513 | 1514 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1528 | 1529 | 1530 | 1531 | 1532 | 1533 | 1534 | 1535 | 1536 | 1537 | 1538 | 1539 | 1540 | 1541 | 1542 | 1543 | 1544 | 1545 | 1546 | 1547 | 1548 | 1549 | 1550 | 1551 | 1552 | 1553 | 1554 | 1555 | 1556 | 1557 | 1558 | 1559 | 1560 | 1561 | 1562 | 1563 | 1564 | 1565 | 1566 | 1571 | 1572 | 1573 | 1574 | 1575 | 1576 | 1577 | 1582 | 1583 | 1584 | 1585 | 1586 | 1587 | 1588 | 1593 | 1594 | 1595 | 1596 | 1597 | 1598 | 1599 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1615 | 1616 | 1617 | 1618 | 1619 | 1620 | commons-codec-1.10 1621 | 1622 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # distribute_hash 2 | 分布式一致性hash算法 3 | 4 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/1.png "屏幕截图.png") 5 | 6 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 7 | 8 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/2.png "屏幕截图.png") 9 | 10 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 11 | 12 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/3.png "屏幕截图.png") 13 | 14 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 15 | 16 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/4.png "屏幕截图.png") 17 | 18 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 19 | 20 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/5.png "屏幕截图.png") 21 | 22 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 23 | 24 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/6.png "屏幕截图.png") 25 | 26 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 27 | 28 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/7.png "屏幕截图.png") 29 | 30 | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 31 | 32 | ![输入图片说明](https://github.com/yzx66-net/distribute_hash/blob/master/img-explane/8.png "屏幕截图.png") 33 | 34 | 35 | -------------------------------------------------------------------------------- /chord.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /img-explane/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/1.png -------------------------------------------------------------------------------- /img-explane/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/2.png -------------------------------------------------------------------------------- /img-explane/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/3.png -------------------------------------------------------------------------------- /img-explane/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/4.png -------------------------------------------------------------------------------- /img-explane/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/5.png -------------------------------------------------------------------------------- /img-explane/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/6.png -------------------------------------------------------------------------------- /img-explane/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/7.png -------------------------------------------------------------------------------- /img-explane/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/img-explane/8.png -------------------------------------------------------------------------------- /lib/commons-codec-1.10.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/lib/commons-codec-1.10.jar -------------------------------------------------------------------------------- /lib/hamcrest-all-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/lib/hamcrest-all-1.3.jar -------------------------------------------------------------------------------- /lib/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/lib/junit-4.12.jar -------------------------------------------------------------------------------- /lib/netty-all-4.1.42.Final.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzx-66/distribute_hash/233f163ab6ef6d2f10a75c9ea59eb9076b2befec/lib/netty-all-4.1.42.Final.jar -------------------------------------------------------------------------------- /src/main/net/yzx66/Main.java: -------------------------------------------------------------------------------- 1 | package net.yzx66; 2 | 3 | import net.yzx66.commen.Chord; 4 | import net.yzx66.commen.IPNode; 5 | import net.yzx66.commen.abs.AbstractChordStruct; 6 | import net.yzx66.commen.abs.AbstractDataOperate; 7 | import net.yzx66.struct.chord.enhanced.EnhancedSkipList; 8 | import net.yzx66.struct.chord.enhanced.EnhancedTree; 9 | import net.yzx66.type.single.SingleChordStruct; 10 | import net.yzx66.type.single.SingleSelfOperate; 11 | 12 | import java.util.List; 13 | 14 | public class Main { 15 | 16 | public static void main(String[] args) { 17 | System.out.println("******************************** 测试 Tree 作为一致性哈希环 ********************************"); 18 | testFuction(initChord(true)); 19 | System.out.println("\n******************************** 测试 SkipList 作为一致性哈希环 ********************************"); 20 | testFuction(initChord(false)); 21 | } 22 | 23 | private static Chord initChord(boolean isTreeStruct){ 24 | return new Chord(getDataOperateWrapper(isTreeStruct)); 25 | } 26 | 27 | private static AbstractDataOperate getDataOperateWrapper(boolean isTreeStruct){ 28 | return isTreeStruct ? new SingleSelfOperate(getTreeChordStruct()) : new SingleSelfOperate(getSkipListChordStruct()); 29 | } 30 | 31 | private static AbstractChordStruct getSkipListChordStruct(){ 32 | return new SingleChordStruct(new EnhancedSkipList()); 33 | } 34 | 35 | private static AbstractChordStruct getTreeChordStruct(){ 36 | return new SingleChordStruct(new EnhancedTree()); 37 | } 38 | 39 | private static void testFuction(Chord chord){ 40 | initIps(chord); 41 | 42 | testAddData(chord); 43 | testGetData(chord); 44 | testJoin(chord); 45 | testLeave(chord); 46 | } 47 | 48 | private static void initIps(Chord chord){ 49 | System.out.println("=============== 测试初始化 IPNODE ==============="); 50 | chord.join("127.0.0.1"); 51 | chord.join("192.168.56.129"); 52 | chord.join("192.168.56.130"); 53 | 54 | show(chord); 55 | } 56 | 57 | private static void testAddData(Chord chord) { 58 | System.out.println("=============== 测试添加数据[(1,1),(2,2),(3,3),(4,4),(5,5)]后的数据分片 ==============="); 59 | chord.insert("1",1); 60 | chord.insert("2",2); 61 | chord.insert("3",3); 62 | chord.insert("4",4); 63 | chord.insert("5",5); 64 | 65 | show(chord); 66 | } 67 | 68 | private static void testGetData(Chord chord){ 69 | System.out.println("=============== 测试查找数据 ==============="); 70 | System.out.println("查找:2,结果:" + chord.get("2")); 71 | System.out.println("查找:4,结果:" + chord.get("4")); 72 | System.out.println(); 73 | } 74 | 75 | 76 | private static void testJoin(Chord chord) { 77 | System.out.println("=============== 测试添加 IPNODE 后的数据迁移 ==============="); 78 | chord.join("192.168.56.140"); 79 | show(chord); 80 | } 81 | 82 | private static void testLeave(Chord chord) { 83 | System.out.println("=============== 测试移除 IPNODE 后的数据迁移 ==============="); 84 | chord.leave("192.168.56.140"); 85 | show(chord); 86 | } 87 | 88 | private static void show(Chord chord){ 89 | List nodes = chord.getAllIPNodes(); 90 | for(IPNode ipNode : nodes){ 91 | System.out.println(ipNode.getIp() +"(hash:" + ipNode.getstartHash() +"):" + ipNode.getDatas()); 92 | } 93 | System.out.println(); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/Chord.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen; 2 | 3 | import net.yzx66.commen.abs.AbstractDataOperate; 4 | 5 | import java.util.List; 6 | 7 | //门面类 8 | public class Chord implements ChordStruct,DataOperate { 9 | 10 | private ChordStruct chordStruct; 11 | private DataOperate dataOperate; 12 | 13 | public Chord(AbstractDataOperate dataOperate){ 14 | this.dataOperate=dataOperate; 15 | this.chordStruct=dataOperate.getChordStruct(); 16 | } 17 | 18 | @Override 19 | public boolean join(String ip) { 20 | return chordStruct.join(ip); 21 | } 22 | 23 | @Override 24 | public void leave(String ip) { 25 | chordStruct.leave(ip); 26 | } 27 | 28 | @Override 29 | public List getAllIPNodes() { 30 | return chordStruct.getAllIPNodes(); 31 | } 32 | 33 | @Override 34 | public void insert(String k, Object v) { 35 | dataOperate.insert(k,v); 36 | } 37 | 38 | @Override 39 | public void update(String k, Object v) { 40 | dataOperate.update(k,v); 41 | } 42 | 43 | @Override 44 | public void delete(String k) { 45 | dataOperate.delete(k); 46 | } 47 | 48 | @Override 49 | public Object get(String k) { 50 | return dataOperate.get(k); 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/ChordStruct.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * chrod网络的结构: 7 | * 数组、链表、跳跃表、树 8 | */ 9 | public interface ChordStruct { 10 | 11 | boolean join(String ip); 12 | 13 | void leave(String ip); 14 | 15 | List getAllIPNodes(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/DataOperate.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen; 2 | 3 | /** 4 | * 对数据的操作 5 | */ 6 | public interface DataOperate { 7 | 8 | void insert(String k,Object v); 9 | 10 | void update(String k,Object v); 11 | 12 | void delete(String k); 13 | 14 | Object get(String k); 15 | } -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/IPNode.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen; 2 | 3 | import net.yzx66.struct.SkipList; 4 | import net.yzx66.utils.MD5Util; 5 | 6 | import java.util.List; 7 | 8 | 9 | /** 10 | * chord网络每个ip节点的存储结构 11 | */ 12 | public class IPNode implements Comparable{ 13 | 14 | public static final int SUM_FRAGMENT = 2048; 15 | 16 | private String ip; 17 | private int startHash; 18 | private SkipList datas; 19 | 20 | public IPNode(){ 21 | datas=new SkipList<>(); 22 | } 23 | 24 | public IPNode(String ip){ 25 | this.ip=ip; 26 | startHash = MD5Util.string2MD5HashCode(ip) % SUM_FRAGMENT; 27 | datas=new SkipList<>(); 28 | } 29 | 30 | //TODO 测试使用 31 | public IPNode(int startHash){ 32 | this.startHash = startHash; 33 | } 34 | 35 | 36 | public String getIp(){ 37 | return ip; 38 | } 39 | 40 | public int getstartHash(){ 41 | return startHash; 42 | } 43 | 44 | public List getDatas() { 45 | return datas.getAllDatas(); 46 | } 47 | 48 | public Entry getData(String k){ 49 | int hash = calculatHash(k); 50 | return datas.getCompleteNode(Entry.getIncompleteEntryWithStartHashToQuery(hash)); 51 | } 52 | 53 | public void addData(String k, Object v){ 54 | datas.add(new Entry(k,v)); 55 | } 56 | 57 | public void deleteData(String k){ 58 | int kHash = MD5Util.string2MD5HashCode(k) % SUM_FRAGMENT; 59 | datas.delete(Entry.getIncompleteEntryWithStartHashToQuery(kHash)); 60 | } 61 | 62 | //返回的 (start , end] 63 | public List getDatasByHash(int start,int end){ 64 | //说明过了中间临界点 65 | if(start > end){ 66 | List leftCircleDatas = datas.getDatasByScope(Entry.getIncompleteEntryWithStartHashToQuery(start), 67 | Entry.getIncompleteEntryWithEndHashToQuery(SUM_FRAGMENT - 1)); 68 | //因为返回的(start ,end ] 所以要从-1 开始才可以返回 0 69 | List rightCircleDatas = datas.getDatasByScope(Entry.getIncompleteEntryWithStartHashToQuery(-1) , 70 | Entry.getIncompleteEntryWithEndHashToQuery(end)); 71 | 72 | leftCircleDatas.addAll(rightCircleDatas); 73 | return leftCircleDatas; 74 | } 75 | return datas.getDatasByScope(Entry.getIncompleteEntryWithStartHashToQuery(start), 76 | Entry.getIncompleteEntryWithEndHashToQuery(end)); 77 | } 78 | 79 | //单例:用于获取包含索引数据的不完整节点,用该不完整的节点去查询完整的节点 80 | public static IPNode getIncompleteNodeWithHashToQuery(int ipHashCode){ 81 | Lazy.sigleIpNode.startHash = ipHashCode % SUM_FRAGMENT; 82 | return Lazy.sigleIpNode; 83 | } 84 | public static IPNode getIncompleteNodeWithIPToQuery(String ip){ 85 | Lazy.sigleIpNode.startHash = MD5Util.string2MD5HashCode(ip) % IPNode.SUM_FRAGMENT; ; 86 | return Lazy.sigleIpNode; 87 | } 88 | //懒汉式 89 | private static class Lazy{ 90 | private final static IPNode sigleIpNode = new IPNode(); 91 | } 92 | 93 | public static int calculatHash(String k){ 94 | return MD5Util.string2MD5HashCode(k) % IPNode.SUM_FRAGMENT; 95 | } 96 | 97 | @Override 98 | public int compareTo(IPNode o) { 99 | return Integer.compare(startHash,o.startHash); 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return "IPNode{" + 105 | "ip='" + ip + '\'' + 106 | ", startHash=" + startHash + 107 | ", datas=" + datas + 108 | '}'; 109 | } 110 | 111 | public static class Entry implements Comparable{ 112 | String k; 113 | Object v; 114 | int hash; 115 | 116 | Entry(){} 117 | 118 | Entry(String k, Object v) { 119 | this.k = k; 120 | this.v = v; 121 | this.hash = MD5Util.string2MD5HashCode(k) % SUM_FRAGMENT; 122 | } 123 | 124 | public String getK() { 125 | return k; 126 | } 127 | 128 | public Object getV() { 129 | return v; 130 | } 131 | 132 | //单例:用于获取包含索引数据的不完整节点,用该不完整的节点去查询完整的节点 133 | static Entry getIncompleteEntryWithStartHashToQuery(int startHash){ 134 | StartHashLazy.sigleEntry.hash = startHash; 135 | return StartHashLazy.sigleEntry; 136 | } 137 | //单例:用于获取包含索引数据的不完整节点,用该不完整的节点去查询完整的节点 138 | static Entry getIncompleteEntryWithEndHashToQuery(int endHash){ 139 | EndHashLazy.sigleEntry.hash = endHash; 140 | return EndHashLazy.sigleEntry; 141 | } 142 | //懒汉式 143 | private static class StartHashLazy{ 144 | private final static Entry sigleEntry = new Entry(); 145 | } 146 | private static class EndHashLazy{ 147 | private final static Entry sigleEntry = new Entry(); 148 | } 149 | 150 | @Override 151 | public int compareTo(Entry o) { 152 | return Integer.compare(hash , o.hash); 153 | } 154 | 155 | @Override 156 | public String toString() { 157 | return "Entry{" + 158 | "k='" + k + '\'' + 159 | ", v=" + v + 160 | ", hash=" + hash + 161 | '}'; 162 | } 163 | } 164 | 165 | 166 | } 167 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/abs/AbstractChordStruct.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen.abs; 2 | 3 | import net.yzx66.commen.ChordStruct; 4 | import net.yzx66.commen.IPNode; 5 | 6 | public abstract class AbstractChordStruct implements ChordStruct , ChordStructPostProcessor{ 7 | 8 | public abstract IPNode getIPNodeByKey(String k); 9 | 10 | @Override 11 | public boolean join(String ip) { 12 | 13 | boolean isAddSuccess = joinSelf(ip); 14 | postProcessorJoin(ip , isAddSuccess); 15 | return isAddSuccess; 16 | } 17 | 18 | @Override 19 | public void leave(String ip) { 20 | leaveSelf(ip); 21 | postProcessorLeave(ip); 22 | } 23 | 24 | protected abstract boolean joinSelf(String ip); 25 | protected abstract void leaveSelf(String ip); 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/abs/AbstractDataOperate.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen.abs; 2 | 3 | import net.yzx66.commen.ChordStruct; 4 | import net.yzx66.commen.DataOperate; 5 | 6 | public abstract class AbstractDataOperate implements DataOperate , DataOperatePostProcessor { 7 | //桥接 8 | protected AbstractChordStruct chordStruct; 9 | 10 | public AbstractDataOperate(AbstractChordStruct chordStruct){ 11 | this.chordStruct=chordStruct; 12 | } 13 | 14 | //为了职责单一,不提供ChordStruct的操作,对外提供访问ChordStruct的方法,由chord 统一包装 15 | final public ChordStruct getChordStruct(){ 16 | return chordStruct; 17 | } 18 | 19 | @Override 20 | public void insert(String k, Object v) { 21 | 22 | insertSelf(k,v); 23 | postProcessInsert(k,v); 24 | } 25 | @Override 26 | public void update(String k, Object v) { 27 | updateSelf(k,v); 28 | postProcessUpdate(k,v); 29 | } 30 | @Override 31 | public void delete(String k) { 32 | deleteSelf(k); 33 | postProcessDelete(k); 34 | } 35 | @Override 36 | public Object get(String k){ 37 | Object v = getSelf(k); 38 | postProcessGet(k , v); 39 | return v; 40 | } 41 | 42 | protected abstract void insertSelf(String k, Object v); 43 | protected abstract void updateSelf(String k, Object v); 44 | protected abstract void deleteSelf(String k); 45 | protected abstract Object getSelf(String k); 46 | } 47 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/abs/ChordStructPostProcessor.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen.abs; 2 | 3 | //ChordStruct的拓展点 4 | public interface ChordStructPostProcessor { 5 | 6 | 7 | void postProcessorJoin(String ip , boolean isAddSuccess); 8 | 9 | void postProcessorLeave(String ip); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/net/yzx66/commen/abs/DataOperatePostProcessor.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.commen.abs; 2 | 3 | //DataOperate的后置拓展点 4 | public interface DataOperatePostProcessor { 5 | 6 | void postProcessInsert(String k, Object v); 7 | void postProcessUpdate(String k, Object v); 8 | void postProcessDelete(String k); 9 | void postProcessGet(String k , Object v); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/main/net/yzx66/operate/SelfOperateFunctionAchieve.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.operate; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.commen.abs.AbstractChordStruct; 5 | import net.yzx66.commen.abs.AbstractDataOperate; 6 | import net.yzx66.commen.abs.DataOperatePostProcessor; 7 | 8 | public abstract class SelfOperateFunctionAchieve extends AbstractDataOperate { 9 | 10 | public SelfOperateFunctionAchieve(AbstractChordStruct chordStruct) { 11 | super(chordStruct); 12 | } 13 | 14 | 15 | @Override 16 | protected void insertSelf(String k, Object v){ 17 | IPNode node = chordStruct.getIPNodeByKey(k); 18 | node.addData(k, v); 19 | } 20 | 21 | 22 | @Override 23 | protected void updateSelf(String k, Object v){ 24 | IPNode node = chordStruct.getIPNodeByKey(k); 25 | node.deleteData(k); 26 | node.addData(k , v); 27 | } 28 | 29 | 30 | @Override 31 | protected Object getSelf(String k) { 32 | IPNode node = chordStruct.getIPNodeByKey(k); 33 | return node.getData(k).getV(); 34 | } 35 | 36 | 37 | @Override 38 | protected void deleteSelf(String k){ 39 | IPNode node = chordStruct.getIPNodeByKey(k); 40 | node.deleteData(k); 41 | } 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/SkipList.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | //跳跃表 9 | public class SkipList extends StructBasicTemplate { 10 | 11 | protected Node head; 12 | protected Node tail; 13 | protected int hight; 14 | protected int size; 15 | 16 | public SkipList(){ 17 | head = new Node<>(); 18 | tail = new Node<>(); 19 | 20 | head.right = tail; 21 | tail.left = head; 22 | 23 | hight = 1; 24 | size = 0; 25 | } 26 | 27 | @Override 28 | public boolean doAdd(T data) { 29 | Node selfOrNearestLeftNode = findSelfOrNearestLeftNode(data); 30 | if(isExist(selfOrNearestLeftNode , data)){ 31 | return false; 32 | } 33 | 34 | 35 | Node previousNode = null; 36 | Node leftNode = selfOrNearestLeftNode; 37 | Random r = new Random(); 38 | 39 | for(int i = 1; r.nextBoolean() || i == 1 ; i++){ 40 | //最高层都是空层 保证后面的节点在找上一层时肯定存在上一层 41 | if(i >= hight){ 42 | addHight(); 43 | } 44 | Node newNode = new Node<>(data); 45 | spliceNode(leftNode , newNode); 46 | 47 | while(leftNode.up == null){ 48 | leftNode = leftNode.left; 49 | } 50 | leftNode = leftNode.up; 51 | 52 | //拼接该节点的上下层 53 | if(i > 1){ 54 | previousNode.up = newNode; 55 | newNode.down = previousNode; 56 | } 57 | previousNode = newNode; 58 | } 59 | size ++; 60 | return true; 61 | } 62 | 63 | protected boolean isExist(Node selfOrNearestLeftNode ,T data){ 64 | return ! isHead(selfOrNearestLeftNode) && 65 | isFirstDataEqualToSecondData(data , selfOrNearestLeftNode.data); 66 | } 67 | 68 | private void spliceNode(Node leftNode , Node newRightNode){ 69 | newRightNode.right = leftNode.right; 70 | newRightNode.right.left = newRightNode; 71 | 72 | leftNode.right = newRightNode; 73 | newRightNode.left = leftNode; 74 | } 75 | 76 | private void addHight() { 77 | Node newHead = new Node<>(); 78 | Node newTail = new Node<>(); 79 | 80 | newHead.right = newTail; 81 | newTail.left = newHead; 82 | 83 | newHead.down = head; 84 | newTail.down = tail; 85 | 86 | head.up = newHead; 87 | tail.up = newTail; 88 | 89 | this.head = newHead; 90 | this.tail = newTail; 91 | hight++; 92 | } 93 | 94 | protected Node findSelfOrNearestLeftNode(T data){ 95 | Node node = head; 96 | 97 | while(true){ 98 | if(isHead(node)){ 99 | node = node.right; 100 | } 101 | //升序排列 102 | while(!isTail(node) && !isFirstDataSmallerThanSecondData(data , node.data)){ 103 | node = node.right; 104 | } 105 | 106 | if(node.left.down != null) { 107 | node = node.left.down; 108 | }else { 109 | //找到尾的情况:大于等于最后一个节点、前一个节点是头节点 110 | return node.left; 111 | } 112 | } 113 | } 114 | 115 | protected boolean isHead(Node node){ 116 | return node.data == null && node.left == null && node.right != null; 117 | } 118 | 119 | protected boolean isTail(Node node){ 120 | return node.data == null && node.right == null && node.left != null; 121 | } 122 | 123 | @Override 124 | public void doDelete(T incompletelNodeWithIndex) { 125 | Node selfOrNearestLeftNode = findSelfOrNearestLeftNode(incompletelNodeWithIndex); 126 | if(! isExist(selfOrNearestLeftNode , incompletelNodeWithIndex)){ 127 | return; 128 | } 129 | 130 | do { 131 | Node leftNode = selfOrNearestLeftNode.left; 132 | Node rightNode = selfOrNearestLeftNode.right; 133 | leftNode.right = rightNode; 134 | rightNode.left = leftNode; 135 | 136 | selfOrNearestLeftNode = selfOrNearestLeftNode.up; 137 | }while(selfOrNearestLeftNode != null); 138 | 139 | size --; 140 | } 141 | 142 | @Override 143 | public T doGetCompleteNode(T incompletelNodeWithIndex) { 144 | Node selfOrNearestLeftNode = findSelfOrNearestLeftNode(incompletelNodeWithIndex); 145 | if(!isExist(selfOrNearestLeftNode , incompletelNodeWithIndex)){ 146 | return null; 147 | } 148 | return selfOrNearestLeftNode.data; 149 | } 150 | 151 | @Override 152 | public void show() { 153 | Node node = head; 154 | while(node.down != null){ 155 | node = node.down; 156 | } 157 | node = node.right; 158 | 159 | while(!isTail(node)){ 160 | System.out.println(node.data); 161 | node = node.right; 162 | } 163 | } 164 | 165 | //返回 (start , end] 166 | public List getDatasByScope(T start , T end){ 167 | if(size == 0){ 168 | return Collections.emptyList(); 169 | } 170 | 171 | List res = new ArrayList<>(); 172 | Node selfOrNearestLeftNode = findSelfOrNearestLeftNode(start); 173 | //三种情况的起始节点都是后一个: 174 | // 存在元素返回head、返回值等于start的节点、返回小于start的节点(即下一个节点大于start的值或者tail) 175 | Node resNode = selfOrNearestLeftNode.right; 176 | 177 | while(!isTail(resNode) && !isFirstDataBiggerThanSecondData(resNode.data , end)){ 178 | res.add(resNode.data); 179 | resNode = resNode.right; 180 | } 181 | 182 | return res; 183 | } 184 | 185 | @Override 186 | public List getAllDatas(){ 187 | List res = new ArrayList<>(); 188 | Node lowestStartNode = getLowest(head).right; 189 | while(!isTail(lowestStartNode)){ 190 | res.add(lowestStartNode.data); 191 | lowestStartNode = lowestStartNode.right; 192 | } 193 | return res; 194 | } 195 | 196 | protected Node getLowest(Node node){ 197 | while(node.down != null){ 198 | node = node.down; 199 | } 200 | return node; 201 | } 202 | 203 | protected static class Node{ 204 | 205 | public T_ data; 206 | 207 | public Node up; 208 | public Node down; 209 | public Node right; 210 | public Node left; 211 | 212 | Node(){} 213 | 214 | Node(T_ data){ 215 | this.data = data; 216 | } 217 | } 218 | 219 | } 220 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/StructBasic.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct; 2 | 3 | import java.util.List; 4 | 5 | public interface StructBasic { 6 | 7 | boolean add(T data); 8 | 9 | /** 10 | * @param incompletelNodeWithIndex 删除节点,通过包含该节点索引的不完整节点 11 | */ 12 | void delete(T incompletelNodeWithIndex); 13 | 14 | /** 15 | * @param incompletelNodeWithIndex 获得完整的节点,通过包含该节点索引的不完整节点 16 | */ 17 | T getCompleteNode(T incompletelNodeWithIndex); 18 | 19 | void show(); 20 | 21 | List getAllDatas(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/StructBasicTemplate.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct; 2 | 3 | import java.util.List; 4 | 5 | public abstract class StructBasicTemplate implements StructBasic { 6 | 7 | @Override 8 | public boolean add(T data){ 9 | //确保每一个添加的元素都可以比较 10 | checkNodeCanCompare(data); 11 | return doAdd(data); 12 | } 13 | 14 | private void checkNodeCanCompare(T data) { 15 | if(! (data instanceof Comparable)){ 16 | throw new IllegalArgumentException("没有实现Comparable接口!"); 17 | } 18 | } 19 | 20 | protected abstract boolean doAdd(T data); 21 | 22 | @Override 23 | public void delete(T incompletelNodeWithIndex){ 24 | //确保参数可以比较 25 | checkNodeCanCompare(incompletelNodeWithIndex); 26 | doDelete(incompletelNodeWithIndex); 27 | } 28 | 29 | protected abstract void doDelete(T incompletelNodeWithIndex); 30 | 31 | @Override 32 | public T getCompleteNode(T incompletelNodeWithIndex){ 33 | //确保参数可以比较 34 | checkNodeCanCompare(incompletelNodeWithIndex); 35 | return doGetCompleteNode(incompletelNodeWithIndex); 36 | } 37 | 38 | protected abstract T doGetCompleteNode(T incompletelNodeWithIndex); 39 | 40 | /** 41 | * 给子类提供的三个比较函数 42 | */ 43 | @SuppressWarnings("unchecked")//可以压制,因为在提供的模板方法起始都用checkNodeCanCompare先检查确保为Comparable的实现类 44 | protected boolean isFirstDataBiggerThanSecondData(T firstData,T secondData){ 45 | Comparable firstParamNodeDataCompare = (Comparable) firstData; 46 | Comparable secondParamNodeDataCompare = (Comparable) secondData; 47 | return firstParamNodeDataCompare.compareTo(secondParamNodeDataCompare) > 0; 48 | } 49 | 50 | @SuppressWarnings("unchecked")//可以压制,因为在提供的模板方法起始都用checkNodeCanCompare先检查确保为Comparable的实现类 51 | protected boolean isFirstDataSmallerThanSecondData(T firstData,T secondData){ 52 | Comparable firstParamNodeDataCompare = (Comparable) firstData; 53 | Comparable secondParamNodeDataCompare = (Comparable) secondData; 54 | return firstParamNodeDataCompare.compareTo(secondParamNodeDataCompare) < 0; 55 | } 56 | 57 | protected boolean isFirstDataEqualToSecondData(T firstData,T secondData){ 58 | return ! isFirstDataBiggerThanSecondData(firstData , secondData) && 59 | ! isFirstDataSmallerThanSecondData(firstData , secondData); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/Tree.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Tree extends StructBasicTemplate { 7 | protected Node root; 8 | 9 | @Override 10 | public boolean doAdd(T data){ 11 | Node newNode = new Node<>(data); 12 | if(isNewRoot(newNode)){ 13 | return true; 14 | } 15 | return addNode(newNode); 16 | } 17 | 18 | private boolean isNewRoot(Node newNode){ 19 | if(root == null){ 20 | root = newNode; 21 | return true; 22 | } 23 | return false; 24 | } 25 | 26 | private boolean addNode(Node newNode){ 27 | //起始查找节点为root 28 | Node compareNode = root; 29 | 30 | while(true){ 31 | if(isFirstDataBiggerThanSecondData(newNode.data,compareNode.data)){ 32 | if(compareNode.right != null){ 33 | compareNode = compareNode.right; 34 | }else { 35 | compareNode.right = newNode; 36 | return true; 37 | } 38 | }else if(isFirstDataSmallerThanSecondData(newNode.data,compareNode.data)){ 39 | if(compareNode.left != null){ 40 | compareNode = compareNode.left; 41 | }else { 42 | compareNode.left = newNode; 43 | return true; 44 | } 45 | }else { 46 | return false; 47 | } 48 | } 49 | } 50 | 51 | @Override 52 | public T doGetCompleteNode(T incompletelNodeWithIndex){ 53 | //起始查找节点为root 54 | Node compareNode = root; 55 | 56 | while(compareNode != null){ 57 | if(isFirstDataBiggerThanSecondData(incompletelNodeWithIndex,compareNode.data)){ 58 | compareNode = compareNode.right; 59 | }else if(isFirstDataSmallerThanSecondData(incompletelNodeWithIndex,compareNode.data)){ 60 | compareNode = compareNode.left; 61 | }else { 62 | return compareNode.data; 63 | } 64 | } 65 | 66 | return null; 67 | } 68 | 69 | @Override 70 | public void doDelete(T incompletelNodeWithIndex){ 71 | Node compareNode = root; 72 | Node compareNodeParent = null; 73 | boolean isLeftChild = true; 74 | 75 | while(compareNode != null){ 76 | if(isFirstDataBiggerThanSecondData(incompletelNodeWithIndex,compareNode.data)){ 77 | compareNodeParent = compareNode; 78 | isLeftChild = false; 79 | compareNode = compareNode.right; 80 | }else if (isFirstDataSmallerThanSecondData(incompletelNodeWithIndex,compareNode.data)){ 81 | compareNodeParent = compareNode; 82 | isLeftChild = true; 83 | compareNode = compareNode.left; 84 | }else { 85 | if(isBeEmptyTree(compareNode)){ 86 | return; 87 | } 88 | 89 | if(isDeleteLeafNode(compareNode,compareNodeParent,isLeftChild)){ 90 | return; 91 | } 92 | 93 | doDeleteNotLeafNode(compareNode); 94 | return; 95 | } 96 | } 97 | } 98 | 99 | private boolean isBeEmptyTree(Node compareNode){ 100 | if(root == compareNode && root.left == null && root.right == null){ 101 | root = null; 102 | return true; 103 | } 104 | return false; 105 | } 106 | 107 | private boolean isDeleteLeafNode(Node compareNode,Node compareNodeParent,boolean isLeftChild){ 108 | if(compareNode.right == null && compareNode.left == null){ 109 | if(isLeftChild){ 110 | compareNodeParent.left = null; 111 | }else { 112 | compareNodeParent.right = null; 113 | } 114 | return true; 115 | } 116 | return false; 117 | } 118 | 119 | private void doDeleteNotLeafNode(Node compareNode){ 120 | T data; 121 | if(compareNode.right != null){ 122 | data = findNodeMinData(compareNode.right); 123 | }else { 124 | data = findNodeMaxData(compareNode.left); 125 | } 126 | //该data对应节点一定是上面三种的一种 127 | delete(data); 128 | compareNode.data = data; 129 | } 130 | 131 | protected T findNodeMaxData(Node node){ 132 | while(node != null){ 133 | if(node.right == null){ 134 | return node.data; 135 | } 136 | node = node.right; 137 | } 138 | return null; 139 | } 140 | 141 | protected T findNodeMinData(Node node){ 142 | while(node != null){ 143 | if(node.left == null){ 144 | return node.data; 145 | } 146 | node = node.left; 147 | } 148 | return null; 149 | } 150 | 151 | @Override 152 | public void show(){ 153 | leftFirstShow(root); 154 | } 155 | 156 | private void leftFirstShow(Node node){ 157 | if(node != null){ 158 | leftFirstShow(node.left); 159 | System.out.println(node.data); 160 | leftFirstShow(node.right); 161 | } 162 | } 163 | 164 | @Override 165 | public List getAllDatas() { 166 | List list = new ArrayList<>(); 167 | leftFirstAdd(list , root); 168 | return list; 169 | } 170 | 171 | private void leftFirstAdd(List list , Node node){ 172 | if(node != null){ 173 | leftFirstAdd(list , node.left); 174 | list.add(node.data); 175 | leftFirstAdd(list ,node.right); 176 | } 177 | } 178 | 179 | //因为非静态内部类无法声明static对象,所以不好实现单例 180 | //同时Node是private的,所以在内部new Node时,可以保证T_ = T 181 | protected static class Node{ 182 | 183 | //声明为public是为了Tree的子类可以访问该内部类的属性 184 | public T_ data; 185 | public Node right; 186 | public Node left; 187 | 188 | Node(T_ data){ 189 | this.data = data; 190 | } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/chord/SelfStructFunctionAchieve.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct.chord; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.commen.abs.AbstractChordStruct; 5 | import net.yzx66.struct.chord.enhanced.StructEnhanced; 6 | 7 | import java.util.List; 8 | 9 | public abstract class SelfStructFunctionAchieve extends AbstractChordStruct { 10 | 11 | private StructEnhanced structEnhanced; 12 | 13 | public SelfStructFunctionAchieve(StructEnhanced structEnhanced){ 14 | this.structEnhanced = structEnhanced; 15 | } 16 | 17 | @Override 18 | protected boolean joinSelf(String ip) { 19 | IPNode nearestSmallerIPNode = getNearestSmallerIPNode(ip); 20 | IPNode nearestBiggerIPNode = getNearestBiggerIPNode(ip); 21 | 22 | IPNode newIpNode = new IPNode(ip); 23 | if(!structEnhanced.add(newIpNode)){ 24 | return false; 25 | } 26 | 27 | moveDataToNewIPNode(nearestSmallerIPNode , nearestBiggerIPNode , newIpNode); 28 | return true; 29 | } 30 | 31 | private IPNode getNearestSmallerIPNode(String newIp){ 32 | return structEnhanced.getNearestSmallerIPNode(IPNode.calculatHash(newIp)); 33 | } 34 | 35 | private IPNode getNearestBiggerIPNode(String newIp){ 36 | return structEnhanced.getNearestBiggerIPNode(IPNode.calculatHash(newIp)); 37 | } 38 | 39 | private void moveDataToNewIPNode(IPNode smallerIPNode ,IPNode biggerIPNode, IPNode newIpNode){ 40 | if(smallerIPNode == null){ 41 | return; 42 | } 43 | 44 | 45 | int newIpNodeHash = newIpNode.getstartHash(); 46 | int smallerNodeHash = smallerIPNode.getstartHash(); 47 | 48 | //(smallerNodeHash , newIpNodeHash ] 49 | List datasByHash = biggerIPNode.getDatasByHash(smallerNodeHash, newIpNodeHash); 50 | for(IPNode.Entry entry : datasByHash){ 51 | newIpNode.addData(entry.getK() , entry.getV()); 52 | biggerIPNode.deleteData(entry.getK()); 53 | } 54 | } 55 | 56 | @Override 57 | protected void leaveSelf(String ip) { 58 | List moveDatas = deleteIPNodeAndGetDatas(ip); 59 | moveDataToNearestSmallerIPNode(ip , moveDatas); 60 | } 61 | 62 | private List deleteIPNodeAndGetDatas(String ip){ 63 | IPNode ipNode = structEnhanced.getCompleteNode(IPNode.getIncompleteNodeWithIPToQuery(ip)); 64 | structEnhanced.delete(ipNode); 65 | return ipNode.getDatas(); 66 | } 67 | 68 | private void moveDataToNearestSmallerIPNode(String deletedIp , List moveDatas){ 69 | IPNode nearestBiggerIPNode = structEnhanced.getNearestBiggerIPNode(IPNode.calculatHash(deletedIp)); 70 | if(nearestBiggerIPNode == null){ 71 | throw new IllegalStateException("所有已经节点下线 数据丢失!丢失数据:"+ moveDatas); 72 | } 73 | 74 | for(IPNode.Entry entry : moveDatas){ 75 | nearestBiggerIPNode.addData(entry.getK() , entry.getV()); 76 | } 77 | } 78 | 79 | @Override 80 | public IPNode getIPNodeByKey(String k) { 81 | return structEnhanced.getNearestBiggerIPNode(IPNode.calculatHash(k)); 82 | } 83 | 84 | @Override 85 | public List getAllIPNodes() { 86 | return structEnhanced.getAllDatas(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/chord/enhanced/EnhancedSkipList.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct.chord.enhanced; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.struct.SkipList; 5 | 6 | public class EnhancedSkipList extends SkipList implements StructEnhanced { 7 | 8 | @Override 9 | public IPNode getNearestBiggerIPNode(int hashCode) { 10 | return getNearestIPNode(hashCode , true); 11 | } 12 | 13 | @Override 14 | public IPNode getNearestSmallerIPNode(int hashCode) { 15 | return getNearestIPNode(hashCode , false); 16 | } 17 | 18 | private IPNode getNearestIPNode(int hashCode , boolean isBigger){ 19 | if(size == 0){ 20 | return null; 21 | } 22 | hashCode %= IPNode.SUM_FRAGMENT; 23 | IPNode withHashToQuery = IPNode.getIncompleteNodeWithHashToQuery(hashCode); 24 | Node selfOrNearestLeftNode = findSelfOrNearestLeftNode(withHashToQuery); 25 | 26 | if(isExist(selfOrNearestLeftNode , withHashToQuery)){ 27 | return selfOrNearestLeftNode.data; 28 | } 29 | 30 | if(isBigger){ 31 | return doGetNearestBiggerData(selfOrNearestLeftNode); 32 | }else { 33 | return doGetNearestSmallerData(selfOrNearestLeftNode); 34 | } 35 | } 36 | 37 | private IPNode doGetNearestBiggerData(Node nearestLeftNode) { 38 | Node resNode = nearestLeftNode.right; 39 | if(isTail(resNode)){ 40 | Node minNode = getLowest(head).right; 41 | return minNode.data; 42 | } 43 | 44 | return resNode.data; 45 | } 46 | 47 | private IPNode doGetNearestSmallerData(Node nearestLeftNode) { 48 | if(isHead(nearestLeftNode)){ 49 | Node maxNode = getLowest(tail).left; 50 | return maxNode.data; 51 | } 52 | 53 | return nearestLeftNode.data; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/chord/enhanced/EnhancedTree.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct.chord.enhanced; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.struct.Tree; 5 | 6 | public class EnhancedTree extends Tree implements StructEnhanced { 7 | 8 | private IPNode maxData; 9 | private IPNode minData; 10 | 11 | @Override 12 | public IPNode getNearestBiggerIPNode(int hashCode) { 13 | return getNearestIPNode(hashCode , true); 14 | } 15 | 16 | @Override 17 | public IPNode getNearestSmallerIPNode(int hashCode) { 18 | return getNearestIPNode(hashCode , false); 19 | } 20 | 21 | private IPNode getNearestIPNode(int hashCode , boolean isBigger){ 22 | if(root == null){ 23 | return null; 24 | } 25 | hashCode %= IPNode.SUM_FRAGMENT; 26 | IPNode data = IPNode.getIncompleteNodeWithHashToQuery(hashCode); 27 | 28 | return doGetNearestIPNode(data ,isBigger); 29 | } 30 | 31 | private IPNode doGetNearestIPNode(IPNode data , boolean isBigger){ 32 | Node compareNode = root; 33 | while(compareNode != null){ 34 | if(isFirstDataBiggerThanSecondData(data , compareNode.data)){ 35 | Node biggerNode = compareNode.right; 36 | 37 | IPNode res; 38 | if(isBigger){ 39 | res = getNearestBiggerDataFromRightBranch(biggerNode , data); 40 | }else { 41 | res = getNearestSmallerDataFromRightBranch(biggerNode , compareNode ,data); 42 | } 43 | 44 | if(res != null){ 45 | return res; 46 | } 47 | compareNode = biggerNode; 48 | }else if(isFirstDataSmallerThanSecondData(data , compareNode.data)){ 49 | Node smallerNode = compareNode.left; 50 | 51 | IPNode res; 52 | if(isBigger){ 53 | res = getNearestBiggerDataFromLeftBranch(compareNode , smallerNode , data); 54 | }else { 55 | res = getNearestSmallerDataFromLeftBranch(smallerNode ,data); 56 | } 57 | 58 | if(res != null){ 59 | return res; 60 | } 61 | compareNode = smallerNode; 62 | }else { 63 | return compareNode.data; 64 | } 65 | } 66 | 67 | return buildDataCircle(data , isBigger); 68 | } 69 | 70 | private IPNode getNearestBiggerDataFromRightBranch(Node biggerNode , IPNode data){ 71 | //只有最右边会等于null 72 | if(biggerNode != null && isFirstDataSmallerThanSecondData(data , biggerNode.data)){ 73 | //在较大节点的左子树找一个值更加接近的 因为该左子树的所有节点的值也在(biggerNode.data , comparenNode.data) 74 | IPNode nearestBiggerIPNode = getChildTreeNearestData(biggerNode.left, data ,true); 75 | return nearestBiggerIPNode != null ? nearestBiggerIPNode : biggerNode.data; 76 | } 77 | return null; 78 | } 79 | private IPNode getNearestBiggerDataFromLeftBranch(Node biggerNode , Node smallerNode , IPNode data){ 80 | //只有最左边会等于null 81 | if(smallerNode != null && isFirstDataBiggerThanSecondData(data , smallerNode.data)){ 82 | //在较小节点的右子树找一个值更加接近的 因为该右子树的所有节点的值也在(compareNode.data , smllarNode.data) 83 | IPNode nearestBiggerIPNode = getChildTreeNearestData(smallerNode.right, data ,true); 84 | return nearestBiggerIPNode != null ? nearestBiggerIPNode : biggerNode.data; 85 | } 86 | return null; 87 | } 88 | private IPNode getNearestSmallerDataFromRightBranch(Node biggerNode ,Node smallerNode , IPNode data){ 89 | //只有最右边会等于null 90 | if(biggerNode != null && isFirstDataSmallerThanSecondData(data , biggerNode.data)){ 91 | //在较大节点的左子树找一个值更加接近的 因为该左子树的所有节点的值也在(biggerNode.data , comparenNode.data) 92 | IPNode nearestSmallerIPNode = getChildTreeNearestData(biggerNode.left, data , false); 93 | return nearestSmallerIPNode != null ? nearestSmallerIPNode : smallerNode.data; 94 | } 95 | return null; 96 | } 97 | private IPNode getNearestSmallerDataFromLeftBranch(Node smallerNode , IPNode data){ 98 | //只有最左边会等于null 99 | if(smallerNode != null && isFirstDataBiggerThanSecondData(data , smallerNode.data)){ 100 | //在较小节点的右子树找一个值更加接近的 因为该右子树的所有节点的值也在(compareNode.data , smllarNode.data) 101 | IPNode nearestSmallerIPNode = getChildTreeNearestData(smallerNode.right, data , false); 102 | return nearestSmallerIPNode != null ? nearestSmallerIPNode : smallerNode.data; 103 | } 104 | return null; 105 | } 106 | 107 | private IPNode getChildTreeNearestData(Node childTreeRoot , IPNode data , boolean isNeedBigger){ 108 | if(childTreeRoot == null){ 109 | return null; 110 | } 111 | 112 | IPNode res = null; 113 | while(childTreeRoot != null){ 114 | if(isFirstDataBiggerThanSecondData(childTreeRoot.data , data)){ 115 | if(isNeedBigger){ 116 | res = childTreeRoot.data; 117 | } 118 | childTreeRoot = childTreeRoot.left; 119 | }else if(isFirstDataSmallerThanSecondData(childTreeRoot.data , data)){ 120 | if(!isNeedBigger){ 121 | res = childTreeRoot.data; 122 | } 123 | childTreeRoot = childTreeRoot.right; 124 | }else { 125 | return childTreeRoot.data; 126 | } 127 | } 128 | 129 | return res; 130 | } 131 | 132 | //只有大于最大或者小于最小才会到这个方法 133 | private IPNode buildDataCircle(IPNode data , boolean isBigger){ 134 | refreshMaxDataAndMinData(); 135 | if(isBigger){ //即顺时针 136 | return minData; 137 | }else { //即逆时针 138 | return maxData; 139 | } 140 | } 141 | 142 | private void refreshMaxDataAndMinData(){ 143 | maxData = findNodeMaxData(root); 144 | minData = findNodeMinData(root); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/net/yzx66/struct/chord/enhanced/StructEnhanced.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct.chord.enhanced; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.struct.StructBasic; 5 | 6 | public interface StructEnhanced extends StructBasic { 7 | 8 | /** 9 | * 增加某个IP节点时,要选择该ip的hashcode的顺时针方向第一个节点,将下一个节点的部分数据迁移新增节点 10 | * 移除某个IP节点时,要选择该ip的hashcode的顺时针方向第一个节点,将该节点的值全部迁移到下一个节点 11 | * 插入值要选择节点时,要选择key的hashcode的顺时针方向第一个节点(即:最近的大于该hash的节点) 12 | */ 13 | IPNode getNearestBiggerIPNode(int hashCode); 14 | 15 | /** 16 | * 在增加IP节点时,要找到逆时针方向第一个节点的hash值,新增节点将从顺时针方向第一个节点 17 | * 迁移 (逆时针方向第一个节点hash,新增节点hash] 区间的值 18 | */ 19 | IPNode getNearestSmallerIPNode(int hashCode); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/net/yzx66/type/cluster/ClusterChordStruct.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.type.cluster; 2 | 3 | import net.yzx66.struct.chord.SelfStructFunctionAchieve; 4 | import net.yzx66.struct.chord.enhanced.StructEnhanced; 5 | import net.yzx66.type.cluster.socket.ChordServer; 6 | 7 | //只负责节点增删的通讯工作 8 | public class ClusterChordStruct extends SelfStructFunctionAchieve { 9 | 10 | public ClusterChordStruct(StructEnhanced structEnhanced) { super(structEnhanced); } 11 | //chordServer通讯模块的实现 12 | public ClusterChordStruct(StructEnhanced structEnhanced , ChordServer chordServer) { super(structEnhanced); } 13 | 14 | @Override 15 | public void postProcessorJoin(String ip , boolean isAddSuccess) { 16 | notityClusterNodeJoin(ip); 17 | } 18 | @Override 19 | public void postProcessorLeave(String ip) { 20 | notifyClusterNodeLeave(ip); 21 | } 22 | 23 | private void notityClusterNodeJoin(String ip){ 24 | //TODO 该方法维护集群中其他节点的socket列表 25 | // 1、获取已加入集群的socket列表 26 | // 2、给每个socket发送消息 27 | // 3、等待ack 刷新本地列表 28 | } 29 | 30 | private void notifyClusterNodeLeave(String ip){ 31 | //TODO 该方法维护集群中其他节点的socket列表 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/net/yzx66/type/cluster/ClusterSelfOperate.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.type.cluster; 2 | 3 | import net.yzx66.commen.abs.AbstractChordStruct; 4 | import net.yzx66.operate.SelfOperateFunctionAchieve; 5 | import net.yzx66.type.cluster.socket.ChordServer; 6 | 7 | //只负责数据改变的通讯工作 8 | public class ClusterSelfOperate extends SelfOperateFunctionAchieve { 9 | 10 | public ClusterSelfOperate(AbstractChordStruct chordStruct) { 11 | super(chordStruct); 12 | } 13 | //chordServer通讯模块的实现 14 | public ClusterSelfOperate(AbstractChordStruct chordStruct, ChordServer chordServer){ super(chordStruct); } 15 | 16 | @Override 17 | public void postProcessInsert(String k, Object v) { 18 | notifyClusterDataInsert(k, v); 19 | } 20 | @Override 21 | public void postProcessUpdate(String k, Object v) { 22 | notifyClusterDataUpdate(k, v); 23 | } 24 | @Override 25 | public void postProcessDelete(String k) { 26 | notifyClusterDataDelete(k); 27 | } 28 | 29 | 30 | private void notifyClusterDataInsert(String k, Object v){ 31 | //TODO 该方法给集群其他节点发送数据增加的消息 32 | } 33 | 34 | private void notifyClusterDataUpdate(String k, Object v){ 35 | //TODO 该方法给集群其他节点发送数据改变的消息 36 | } 37 | 38 | private void notifyClusterDataDelete(String k){ 39 | //TODO 该方法给集群其他节点发送数据删除的消息 40 | } 41 | 42 | @Override 43 | public void postProcessGet(String k, Object v) { 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/net/yzx66/type/cluster/socket/ChordServer.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.type.cluster.socket; 2 | 3 | import java.util.List; 4 | 5 | // 通讯模块的实现:netty、nio、bio ... 6 | public interface ChordServer { 7 | 8 | void join(String ip); 9 | 10 | void leave(String ip); 11 | 12 | void insert(String insertDataIp ); 13 | 14 | void sendDatas(String destIP , List datas); 15 | 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/net/yzx66/type/single/SingleChordStruct.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.type.single; 2 | 3 | import net.yzx66.struct.chord.SelfStructFunctionAchieve; 4 | import net.yzx66.struct.chord.enhanced.StructEnhanced; 5 | 6 | public class SingleChordStruct extends SelfStructFunctionAchieve { 7 | public SingleChordStruct(StructEnhanced structEnhanced) { 8 | super(structEnhanced); 9 | } 10 | 11 | @Override 12 | public void postProcessorJoin(String ip , boolean isAddSuccess){/*not do anything*/ } 13 | @Override 14 | public void postProcessorLeave(String ip){/*not do anything*/ } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/net/yzx66/type/single/SingleSelfOperate.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.type.single; 2 | 3 | import net.yzx66.commen.abs.AbstractChordStruct; 4 | import net.yzx66.operate.SelfOperateFunctionAchieve; 5 | 6 | public class SingleSelfOperate extends SelfOperateFunctionAchieve { 7 | public SingleSelfOperate(AbstractChordStruct chordStruct) { 8 | super(chordStruct); 9 | } 10 | 11 | @Override 12 | public void postProcessInsert(String k, Object v) {/*not do anything*/ } 13 | @Override 14 | public void postProcessUpdate(String k, Object v) {/*not do anything*/} 15 | @Override 16 | public void postProcessDelete(String k) {/*not do anything*/} 17 | @Override 18 | public void postProcessGet(String k, Object v) {/*not do anything*/ } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/net/yzx66/utils/MD5Util.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.utils; 2 | 3 | import org.apache.commons.codec.digest.DigestUtils; 4 | 5 | public class MD5Util { 6 | 7 | public static int string2MD5HashCode(String s){ 8 | return Math.abs(DigestUtils.md5Hex(s).hashCode()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/net/yzx66/utils/StringUtil.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.utils; 2 | 3 | public class StringUtil { 4 | 5 | public static int ipString2Int(String ip){ 6 | String s = ip.replaceAll("\\.", ""); 7 | return Integer.parseInt(s); 8 | } 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/test/net/yzx66/struct/SkipListTest.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.List; 8 | 9 | public class SkipListTest { 10 | 11 | private SkipList skipList; 12 | 13 | @Before 14 | public void init(){ 15 | skipList = new SkipList<>(); 16 | skipList.add(new IPNode(15)); 17 | skipList.add(new IPNode(10)); 18 | skipList.add(new IPNode(20)); 19 | skipList.add(new IPNode(8)); 20 | skipList.add(new IPNode(13)); 21 | skipList.add(new IPNode(12)); 22 | skipList.add(new IPNode(17)); 23 | skipList.add(new IPNode(19)); 24 | } 25 | 26 | @Test 27 | public void testAdd(){ 28 | skipList.show(); 29 | } 30 | 31 | @Test 32 | public void testDelete(){ 33 | skipList.delete(IPNode.getIncompleteNodeWithHashToQuery(8)); 34 | skipList.delete(IPNode.getIncompleteNodeWithHashToQuery(10)); 35 | skipList.delete(IPNode.getIncompleteNodeWithHashToQuery(19)); 36 | skipList.show(); 37 | } 38 | 39 | @Test 40 | public void testGetCompleteNode(){ 41 | System.out.println(skipList.getCompleteNode(IPNode.getIncompleteNodeWithHashToQuery(8))); 42 | System.out.println(skipList.getCompleteNode(IPNode.getIncompleteNodeWithHashToQuery(10))); 43 | System.out.println(skipList.getCompleteNode(IPNode.getIncompleteNodeWithHashToQuery(20))); 44 | System.out.println(skipList.getCompleteNode(IPNode.getIncompleteNodeWithHashToQuery(99))); 45 | } 46 | 47 | @Test 48 | public void testGetDatasByScope(){ 49 | IPNode start = new IPNode(9); 50 | IPNode end = new IPNode(20); 51 | System.out.println(skipList.getDatasByScope(start,end)); 52 | } 53 | 54 | @Test 55 | public void testGetAllDatas(){ 56 | System.out.println(skipList.getAllDatas()); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/net/yzx66/struct/TreeTest.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.List; 8 | 9 | public class TreeTest { 10 | 11 | private Tree ipNodeTree; 12 | 13 | @Before 14 | public void initTree(){ 15 | ipNodeTree = new Tree<>(); 16 | 17 | ipNodeTree.add(new IPNode(2)); 18 | ipNodeTree.add(new IPNode(1)); 19 | ipNodeTree.add(new IPNode(3)); 20 | ipNodeTree.add(new IPNode(0)); 21 | } 22 | 23 | @Test 24 | public void testAdd(){ 25 | ipNodeTree.show(); 26 | } 27 | 28 | @Test 29 | public void testGetCompleteNode(){ 30 | IPNode ipToQuery = IPNode.getIncompleteNodeWithHashToQuery(0); 31 | IPNode completeNode = ipNodeTree.getCompleteNode(ipToQuery); 32 | System.out.println(completeNode); 33 | } 34 | 35 | @Test 36 | public void testDelete(){ 37 | ipNodeTree.delete(IPNode.getIncompleteNodeWithHashToQuery(2)); 38 | ipNodeTree.delete(IPNode.getIncompleteNodeWithHashToQuery(3)); 39 | ipNodeTree.show(); 40 | } 41 | 42 | @Test 43 | public void testGetAllDatas(){ 44 | List datas = ipNodeTree.getAllDatas(); 45 | for(IPNode node : datas){ 46 | System.out.println(node); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/net/yzx66/struct/chord/EnhancedSkipListTest.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct.chord; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.struct.chord.enhanced.EnhancedSkipList; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | public class EnhancedSkipListTest { 9 | 10 | private EnhancedSkipList skipList; 11 | 12 | @Before 13 | public void init(){ 14 | skipList = new EnhancedSkipList(); 15 | skipList.add(new IPNode(15)); 16 | skipList.add(new IPNode(10)); 17 | skipList.add(new IPNode(20)); 18 | skipList.add(new IPNode(8)); 19 | skipList.add(new IPNode(13)); 20 | skipList.add(new IPNode(12)); 21 | skipList.add(new IPNode(17)); 22 | skipList.add(new IPNode(19)); 23 | } 24 | 25 | @Test 26 | public void testGetBigger(){ 27 | assert skipList.getNearestBiggerIPNode(0).getstartHash() == 8; 28 | assert skipList.getNearestBiggerIPNode(99).getstartHash() == 8; 29 | assert skipList.getNearestBiggerIPNode(16).getstartHash() == 17; 30 | assert skipList.getNearestBiggerIPNode(18).getstartHash() == 19; 31 | assert skipList.getNearestBiggerIPNode(11).getstartHash() == 12; 32 | assert skipList.getNearestBiggerIPNode(9).getstartHash() == 10; 33 | } 34 | 35 | @Test 36 | public void testSmaller(){ 37 | assert skipList.getNearestSmallerIPNode(0).getstartHash() == 20; 38 | assert skipList.getNearestSmallerIPNode(99).getstartHash() == 20; 39 | assert skipList.getNearestSmallerIPNode(16).getstartHash() == 15; 40 | assert skipList.getNearestSmallerIPNode(18).getstartHash() == 17; 41 | assert skipList.getNearestSmallerIPNode(11).getstartHash() == 10; 42 | assert skipList.getNearestSmallerIPNode(9).getstartHash() == 8; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/net/yzx66/struct/chord/EnhancedTreeTest.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.struct.chord; 2 | 3 | import net.yzx66.commen.IPNode; 4 | import net.yzx66.struct.chord.enhanced.EnhancedTree; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | public class EnhancedTreeTest { 9 | 10 | private EnhancedTree tree; 11 | 12 | @Before 13 | public void init(){ 14 | tree = new EnhancedTree(); 15 | tree.add(new IPNode(15)); 16 | tree.add(new IPNode(10)); 17 | tree.add(new IPNode(20)); 18 | tree.add(new IPNode(8)); 19 | tree.add(new IPNode(13)); 20 | tree.add(new IPNode(12)); 21 | tree.add(new IPNode(17)); 22 | tree.add(new IPNode(19)); 23 | //8 10 12 13 15 17 19 20 24 | tree.show(); 25 | } 26 | 27 | @Test 28 | public void testGetBigger(){ 29 | assert tree.getNearestBiggerIPNode(0).getstartHash() == 8; 30 | assert tree.getNearestBiggerIPNode(99).getstartHash() == 8; 31 | assert tree.getNearestBiggerIPNode(16).getstartHash() == 17; 32 | assert tree.getNearestBiggerIPNode(18).getstartHash() == 19; 33 | assert tree.getNearestBiggerIPNode(11).getstartHash() == 12; 34 | assert tree.getNearestBiggerIPNode(9).getstartHash() == 10; 35 | } 36 | 37 | @Test 38 | public void testSmaller(){ 39 | assert tree.getNearestSmallerIPNode(0).getstartHash() == 20; 40 | assert tree.getNearestSmallerIPNode(99).getstartHash() == 20; 41 | assert tree.getNearestSmallerIPNode(16).getstartHash() == 15; 42 | assert tree.getNearestSmallerIPNode(18).getstartHash() == 17; 43 | assert tree.getNearestSmallerIPNode(11).getstartHash() == 10; 44 | assert tree.getNearestSmallerIPNode(9).getstartHash() == 8; 45 | } 46 | 47 | 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/net/yzx66/utils/MD5UtilTest.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.utils; 2 | 3 | import net.yzx66.utils.MD5Util; 4 | import org.junit.Test; 5 | import sun.security.provider.MD5; 6 | 7 | public class MD5UtilTest { 8 | 9 | @Test 10 | public void testString2MD5HashCode(){ 11 | System.out.println(MD5Util.string2MD5HashCode("127.0.0.1")); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/net/yzx66/utils/StringUtilTest.java: -------------------------------------------------------------------------------- 1 | package net.yzx66.utils; 2 | 3 | import net.yzx66.utils.StringUtil; 4 | import org.junit.Test; 5 | 6 | public class StringUtilTest { 7 | 8 | @Test 9 | public void testIpString2Int(){ 10 | System.out.println(StringUtil.ipString2Int("127.0.0.1")); 11 | } 12 | } 13 | --------------------------------------------------------------------------------