├── .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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
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 |
5 |
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 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
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 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
170 |
171 |
172 |
173 | postProcessorJoin
174 | thisNode
175 | startFragment
176 | getstartHash
177 | 确保后面的泛型的强制转型成功
178 | queryRoot
179 | checkChildTreeHasNearstData
180 | checkChildTreeRoot
181 | doGetNearestSmalelrData
182 | calculatIPHash
183 | getAllIPNOdes()
184 | StructEnhancedFunction
185 | tree
186 | selfStructAdpater
187 | ****************
188 | addIps
189 | ipString2Int
190 | list
191 |
192 |
193 | compareNode
194 | startHash
195 | 确保可以比较 即实现了Compareable接口
196 | checkChildTreeRoot
197 | getChildTreeNearestData
198 | childTreeRoot
199 | skipList
200 | calculatHash
201 | getAllIPNodes()
202 | doGetNearestSmallerData
203 | StructEnhanced
204 | selfStruct
205 | structEnhanced
206 | ===============
207 | initIps
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
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 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 | 1588270963881
576 |
577 |
578 | 1588270963881
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
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 |
625 |
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 |
675 |
676 |
677 |
678 |
679 |
680 | file://$PROJECT_DIR$/src/main/net/yzx66/Main.java
681 | 77
682 |
683 |
684 |
685 |
686 | file://$PROJECT_DIR$/src/main/net/yzx66/commen/IPNode.java
687 | 65
688 |
689 |
690 |
691 |
692 | file://$PROJECT_DIR$/src/main/net/yzx66/struct/SkipList.java
693 | 166
694 |
695 |
696 |
697 |
698 | file://$PROJECT_DIR$/src/main/net/yzx66/struct/SkipList.java
699 | 171
700 |
701 |
702 |
703 |
704 | file://$PROJECT_DIR$/src/main/net/yzx66/struct/SkipList.java
705 | 94
706 |
707 |
708 |
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 |
1567 |
1568 |
1569 |
1570 |
1571 |
1572 |
1573 |
1574 |
1575 |
1576 |
1577 |
1578 |
1579 |
1580 |
1581 |
1582 |
1583 |
1584 |
1585 |
1586 |
1587 |
1588 |
1589 |
1590 |
1591 |
1592 |
1593 |
1594 |
1595 |
1596 |
1597 |
1598 |
1599 |
1600 |
1601 |
1602 |
1603 |
1604 |
1605 |
1606 |
1607 |
1608 |
1609 |
1610 |
1611 |
1612 |
1613 |
1614 |
1615 |
1616 |
1617 |
1618 |
1619 |
1620 | commons-codec-1.10
1621 |
1622 |
1623 |
1624 |
1625 |
1626 |
1627 |
1628 |
1629 |
1630 |
1631 |
1632 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # distribute_hash
2 | 分布式一致性hash算法
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 |
--------------------------------------------------------------------------------
/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