1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.avltree;
21
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Comparator;
26 import java.util.List;
27
28
29
30
31
32
33
34 public class ArrayTree<K>
35 {
36
37 private Comparator<K> comparator;
38
39
40 private K[] array;
41
42
43 private int size;
44
45
46 private static final int INCREMENT = 16;
47
48
49
50
51
52
53
54 public ArrayTree( Comparator<K> comparator )
55 {
56 this.comparator = comparator;
57 array = ( K[] ) new Object[INCREMENT];
58 size = 0;
59 }
60
61
62
63
64
65
66
67
68 public ArrayTree( Comparator<K> comparator, K[] array )
69 {
70 this.comparator = comparator;
71
72 if ( array != null )
73 {
74 size = array.length;
75 int arraySize = size;
76
77 if ( size % INCREMENT != 0 )
78 {
79 arraySize += INCREMENT - size % INCREMENT;
80 }
81
82 this.array = ( K[] ) new Object[arraySize];
83 System.arraycopy( array, 0, this.array, 0, size );
84 }
85 }
86
87
88
89
90
91 public Comparator<K> getComparator()
92 {
93 return comparator;
94 }
95
96
97
98
99
100
101
102
103
104 public K insert( K key )
105 {
106 if ( key == null )
107 {
108
109 return null;
110 }
111
112
113
114 K existing = find( key );
115
116 if ( existing != null )
117 {
118 return existing;
119 }
120
121 if ( size == array.length )
122 {
123
124 K[] newArray = ( K[] ) new Object[size + INCREMENT];
125
126 System.arraycopy( array, 0, newArray, 0, size );
127 array = newArray;
128 }
129
130
131
132
133
134 array[size++] = key;
135 Arrays.sort( array, 0, size, comparator );
136
137 return null;
138 }
139
140
141
142
143
144 private void reduceArray()
145 {
146
147
148
149 if ( ( array.length - size ) > ( INCREMENT << 1 ) )
150 {
151 K[] newArray = ( K[] ) new Object[array.length - INCREMENT];
152 System.arraycopy( array, 0, newArray, 0, array.length );
153 }
154 }
155
156
157
158
159
160
161
162
163 public K remove( K key )
164 {
165
166 int pos = getPosition( key );
167
168 if ( pos != -1 )
169 {
170
171 if ( pos != size - 1 )
172 {
173
174
175 System.arraycopy( array, pos + 1, array, pos, size - pos - 1 );
176
177 reduceArray();
178 }
179
180 size--;
181
182 return key;
183 }
184 else
185 {
186 return null;
187 }
188 }
189
190
191
192
193
194
195
196 public boolean isEmpty()
197 {
198 return size == 0;
199 }
200
201
202
203
204
205
206
207 public int size()
208 {
209 return size;
210 }
211
212
213
214
215
216 public List<K> getKeys()
217 {
218 List<K> list = new ArrayList<>( size );
219
220 for ( int i = 0; i < size; i++ )
221 {
222 list.add( array[i] );
223 }
224
225 return list;
226 }
227
228
229
230
231
232 public void printTree()
233 {
234 if ( isEmpty() )
235 {
236 System.out.println( "Tree is empty" );
237 return;
238 }
239
240 boolean isFirst = true;
241
242 for ( K key : array )
243 {
244 if ( isFirst )
245 {
246 isFirst = false;
247 }
248 else
249 {
250 System.out.print( ", " );
251 }
252
253 System.out.println( key );
254 }
255 }
256
257
258
259
260
261
262
263 public K get( int position )
264 {
265 if ( ( position < 0 ) || ( position >= size ) )
266 {
267 throw new ArrayIndexOutOfBoundsException();
268 }
269
270 return array[position];
271 }
272
273
274
275
276
277
278
279 public K getFirst()
280 {
281 if ( size != 0 )
282 {
283 return array[0];
284 }
285 else
286 {
287 return null;
288 }
289 }
290
291
292
293
294
295
296
297 public K getLast()
298 {
299 if ( size != 0 )
300 {
301 return array[size - 1];
302 }
303 else
304 {
305 return null;
306 }
307 }
308
309
310
311
312
313
314
315
316
317
318 public K findGreater( K key )
319 {
320 if ( key == null )
321 {
322 return null;
323 }
324
325 switch ( size )
326 {
327 case 0:
328 return null;
329
330 case 1:
331 if ( comparator.compare( array[0], key ) > 0 )
332 {
333 return array[0];
334 }
335 else
336 {
337 return null;
338 }
339
340 case 2:
341 if ( comparator.compare( array[0], key ) > 0 )
342 {
343 return array[0];
344 }
345 else if ( comparator.compare( array[1], key ) > 0 )
346 {
347 return array[1];
348 }
349 else
350 {
351 return null;
352 }
353
354 default:
355
356 int current = size >> 1;
357 int start = 0;
358 int end = size - 1;
359
360 while ( end - start + 1 > 2 )
361 {
362 int res = comparator.compare( array[current], key );
363
364 if ( res == 0 )
365 {
366
367 return array[current + 1];
368 }
369 else if ( res < 0 )
370 {
371 start = current;
372 current = ( current + end + 1 ) >> 1;
373 }
374 else
375 {
376 end = current;
377 current = ( current + start + 1 ) >> 1;
378 }
379 }
380
381 switch ( end - start + 1 )
382 {
383 case 1:
384 int res = comparator.compare( array[start], key );
385
386 if ( res <= 0 )
387 {
388 if ( start == size )
389 {
390 return null;
391 }
392 else
393 {
394 return array[start + 1];
395 }
396 }
397
398 return array[start];
399
400 case 2:
401 res = comparator.compare( array[start], key );
402
403 if ( res <= 0 )
404 {
405 res = comparator.compare( array[start + 1], key );
406
407 if ( res <= 0 )
408 {
409 if ( start == size - 2 )
410 {
411 return null;
412 }
413
414 return array[start + 2];
415 }
416
417 return array[start + 1];
418 }
419
420 return array[start];
421
422 default:
423 return null;
424 }
425 }
426 }
427
428
429
430
431
432
433
434
435
436 public K findGreaterOrEqual( K key )
437 {
438 if ( key == null )
439 {
440 return null;
441 }
442
443 switch ( size )
444 {
445 case 0:
446 return null;
447
448 case 1:
449 if ( comparator.compare( array[0], key ) >= 0 )
450 {
451 return array[0];
452 }
453 else
454 {
455 return null;
456 }
457
458 case 2:
459 if ( comparator.compare( array[0], key ) >= 0 )
460 {
461 return array[0];
462 }
463 else if ( comparator.compare( array[1], key ) >= 0 )
464 {
465 return array[1];
466 }
467 else
468 {
469 return null;
470 }
471
472 default:
473
474 int current = size >> 1;
475 int start = 0;
476 int end = size - 1;
477
478 while ( end - start + 1 > 2 )
479 {
480 int res = comparator.compare( array[current], key );
481
482 if ( res == 0 )
483 {
484 return array[current];
485 }
486 else if ( res < 0 )
487 {
488 start = current;
489 current = ( current + end + 1 ) >> 1;
490 }
491 else
492 {
493 end = current;
494 current = ( current + start + 1 ) >> 1;
495 }
496 }
497
498 switch ( end - start + 1 )
499 {
500 case 1:
501 int res = comparator.compare( array[start], key );
502
503 if ( res >= 0 )
504 {
505 return array[start];
506 }
507 else
508 {
509 if ( start == size - 1 )
510 {
511 return null;
512 }
513 else
514 {
515 return array[start + 1];
516 }
517 }
518
519 case 2:
520 res = comparator.compare( array[start], key );
521
522 if ( res < 0 )
523 {
524 res = comparator.compare( array[start + 1], key );
525
526 if ( res < 0 )
527 {
528 if ( start == size - 2 )
529 {
530 return null;
531 }
532
533 return array[start + 2];
534 }
535
536 return array[start + 1];
537 }
538
539 return array[start];
540
541 default:
542 return null;
543 }
544 }
545 }
546
547
548
549
550
551
552
553
554
555 public K findLess( K key )
556 {
557 if ( key == null )
558 {
559 return null;
560 }
561
562 switch ( size )
563 {
564 case 0:
565 return null;
566
567 case 1:
568 if ( comparator.compare( array[0], key ) >= 0 )
569 {
570 return null;
571 }
572 else
573 {
574 return array[0];
575 }
576
577 case 2:
578 if ( comparator.compare( array[0], key ) >= 0 )
579 {
580 return null;
581 }
582 else if ( comparator.compare( array[1], key ) >= 0 )
583 {
584 return array[0];
585 }
586 else
587 {
588 return array[1];
589 }
590
591 default:
592
593 int current = size >> 1;
594 int start = 0;
595 int end = size - 1;
596
597 while ( end - start + 1 > 2 )
598 {
599 int res = comparator.compare( array[current], key );
600
601 if ( res == 0 )
602 {
603
604 return array[current - 1];
605 }
606 else if ( res < 0 )
607 {
608 start = current;
609 current = ( current + end + 1 ) >> 1;
610 }
611 else
612 {
613 end = current;
614 current = ( current + start + 1 ) >> 1;
615 }
616 }
617
618 switch ( end - start + 1 )
619 {
620 case 1:
621
622
623
624
625
626
627
628
629 int res = comparator.compare( array[start], key );
630
631 if ( res >= 0 )
632 {
633
634 if ( start == 1 )
635 {
636 return null;
637 }
638 else
639 {
640 return array[start - 1];
641 }
642 }
643 else
644 {
645 return array[start];
646 }
647
648 case 2:
649
650
651
652
653
654
655
656
657
658 res = comparator.compare( array[start], key );
659
660 if ( res >= 0 )
661 {
662 if ( start == 0 )
663 {
664 return null;
665 }
666 else
667 {
668 return array[start - 1];
669 }
670 }
671 else if ( comparator.compare( array[start + 1], key ) >= 0 )
672 {
673 return array[start];
674 }
675 else
676 {
677 return array[start + 1];
678 }
679
680 default:
681 return null;
682 }
683 }
684 }
685
686
687
688
689
690
691
692
693
694 public K findLessOrEqual( K key )
695 {
696 if ( key == null )
697 {
698 return null;
699 }
700
701 switch ( size )
702 {
703 case 0:
704 return null;
705
706 case 1:
707 if ( comparator.compare( array[0], key ) <= 0 )
708 {
709 return array[0];
710 }
711 else
712 {
713 return null;
714 }
715
716 case 2:
717 int res = comparator.compare( array[0], key );
718
719 if ( res > 0 )
720 {
721 return null;
722 }
723 else if ( res == 0 )
724 {
725 return array[0];
726 }
727
728 res = comparator.compare( array[1], key );
729
730 if ( res == 0 )
731 {
732 return array[1];
733 }
734 else if ( comparator.compare( array[1], key ) > 0 )
735 {
736 return array[0];
737 }
738 else
739 {
740 return array[1];
741 }
742
743 default:
744
745 int current = size >> 1;
746 int start = 0;
747 int end = size - 1;
748
749 while ( end - start + 1 > 2 )
750 {
751 res = comparator.compare( array[current], key );
752
753 if ( res == 0 )
754 {
755 return array[current];
756 }
757 else if ( res < 0 )
758 {
759 start = current;
760 current = ( current + end + 1 ) >> 1;
761 }
762 else
763 {
764 end = current;
765 current = ( current + start + 1 ) >> 1;
766 }
767 }
768
769 switch ( end - start + 1 )
770 {
771 case 1:
772
773
774
775
776
777
778
779
780 res = comparator.compare( array[start], key );
781
782 if ( res > 0 )
783 {
784
785 if ( start == 1 )
786 {
787 return null;
788 }
789 else
790 {
791 return array[start - 1];
792 }
793 }
794 else
795 {
796 return array[start];
797 }
798
799 case 2:
800
801
802
803
804
805
806
807
808
809 res = comparator.compare( array[start], key );
810
811 if ( res > 0 )
812 {
813 if ( start == 0 )
814 {
815 return null;
816 }
817 else
818 {
819 return array[start - 1];
820 }
821 }
822
823 res = comparator.compare( array[start + 1], key );
824
825 if ( res > 0 )
826 {
827 return array[start];
828 }
829 else
830 {
831 return array[start + 1];
832 }
833
834 default:
835 return null;
836 }
837 }
838 }
839
840
841
842
843
844
845
846
847 public K find( K key )
848 {
849 if ( key == null )
850 {
851 return null;
852 }
853
854 switch ( size )
855 {
856 case 0:
857 return null;
858
859 case 1:
860 if ( comparator.compare( array[0], key ) == 0 )
861 {
862 return array[0];
863 }
864 else
865 {
866 return null;
867 }
868
869 case 2:
870 if ( comparator.compare( array[0], key ) == 0 )
871 {
872 return array[0];
873 }
874 else if ( comparator.compare( array[1], key ) == 0 )
875 {
876 return array[1];
877 }
878 else
879 {
880 return null;
881 }
882
883 default:
884
885 int current = size >> 1;
886 int start = 0;
887 int end = size - 1;
888
889 while ( end - start + 1 > 2 )
890 {
891 int res = comparator.compare( array[current], key );
892
893 if ( res == 0 )
894 {
895 return array[current];
896 }
897 else if ( res < 0 )
898 {
899 start = current;
900 current = ( current + end + 1 ) >> 1;
901 }
902 else
903 {
904 end = current;
905 current = ( current + start + 1 ) >> 1;
906 }
907 }
908
909 switch ( end - start + 1 )
910 {
911 case 1:
912 if ( comparator.compare( array[start], key ) == 0 )
913 {
914 return array[start];
915 }
916 else
917 {
918 return null;
919 }
920
921 case 2:
922 if ( comparator.compare( array[start], key ) == 0 )
923 {
924 return array[start];
925 }
926 else if ( comparator.compare( array[end], key ) == 0 )
927 {
928 return array[end];
929 }
930 else
931 {
932 return null;
933 }
934
935 default:
936 return null;
937 }
938 }
939 }
940
941
942
943
944
945
946
947
948 public int getPosition( K key )
949 {
950 if ( key == null )
951 {
952 return -1;
953 }
954
955 switch ( size )
956 {
957 case 0:
958 return -1;
959
960 case 1:
961 if ( comparator.compare( array[0], key ) == 0 )
962 {
963 return 0;
964 }
965 else
966 {
967 return -1;
968 }
969
970 case 2:
971 if ( comparator.compare( array[0], key ) == 0 )
972 {
973 return 0;
974 }
975 else if ( comparator.compare( array[1], key ) == 0 )
976 {
977 return 1;
978 }
979 else
980 {
981 return -1;
982 }
983
984 default:
985
986 int current = size >> 1;
987 int start = 0;
988 int end = size - 1;
989
990 while ( end - start + 1 > 2 )
991 {
992 int res = comparator.compare( array[current], key );
993
994 if ( res == 0 )
995 {
996 return current;
997 }
998 else if ( res < 0 )
999 {
1000 start = current;
1001 current = ( current + end + 1 ) >> 1;
1002 }
1003 else
1004 {
1005 end = current;
1006 current = ( current + start + 1 ) >> 1;
1007 }
1008 }
1009
1010 switch ( end - start + 1 )
1011 {
1012 case 1:
1013 if ( comparator.compare( array[start], key ) == 0 )
1014 {
1015 return start;
1016 }
1017 else
1018 {
1019 return -1;
1020 }
1021
1022 case 2:
1023 if ( comparator.compare( array[start], key ) == 0 )
1024 {
1025 return start;
1026 }
1027 else if ( comparator.compare( array[end], key ) == 0 )
1028 {
1029 return end;
1030 }
1031 else
1032 {
1033 return -1;
1034 }
1035
1036 default:
1037 return -1;
1038 }
1039 }
1040 }
1041
1042
1043
1044
1045
1046
1047
1048
1049 public int getAfterPosition( K key )
1050 {
1051 if ( key == null )
1052 {
1053 return -1;
1054 }
1055
1056 switch ( size )
1057 {
1058 case 0:
1059 return -1;
1060
1061 case 1:
1062 if ( comparator.compare( array[0], key ) > 0 )
1063 {
1064 return 0;
1065 }
1066 else
1067 {
1068 return -1;
1069 }
1070
1071 case 2:
1072 if ( comparator.compare( array[0], key ) > 0 )
1073 {
1074 return 0;
1075 }
1076
1077 if ( comparator.compare( array[1], key ) > 0 )
1078 {
1079 return 1;
1080 }
1081 else
1082 {
1083 return -1;
1084 }
1085
1086 default:
1087
1088 int current = size >> 1;
1089 int start = 0;
1090 int end = size - 1;
1091
1092 while ( end - start + 1 > 2 )
1093 {
1094 int res = comparator.compare( array[current], key );
1095
1096 if ( res == 0 )
1097 {
1098 if ( current != size - 1 )
1099 {
1100 return current + 1;
1101 }
1102 else
1103 {
1104 return -1;
1105 }
1106 }
1107 else if ( res < 0 )
1108 {
1109 start = current;
1110 current = ( current + end + 1 ) >> 1;
1111 }
1112 else
1113 {
1114 end = current;
1115 current = ( current + start + 1 ) >> 1;
1116 }
1117 }
1118
1119 switch ( end - start + 1 )
1120 {
1121 case 1:
1122 if ( comparator.compare( array[start], key ) > 0 )
1123 {
1124 return start;
1125 }
1126 else
1127 {
1128 return -1;
1129 }
1130
1131 case 2:
1132 if ( comparator.compare( array[start], key ) > 0 )
1133 {
1134 return start;
1135 }
1136
1137 if ( comparator.compare( array[end], key ) > 0 )
1138 {
1139 return end;
1140 }
1141 else
1142 {
1143 return -1;
1144 }
1145
1146 default:
1147 return -1;
1148 }
1149 }
1150 }
1151
1152
1153
1154
1155
1156
1157
1158
1159 public int getBeforePosition( K key )
1160 {
1161 if ( key == null )
1162 {
1163 return -1;
1164 }
1165
1166 switch ( size )
1167 {
1168 case 0:
1169 return -1;
1170
1171 case 1:
1172 if ( comparator.compare( array[0], key ) < 0 )
1173 {
1174 return 0;
1175 }
1176 else
1177 {
1178 return -1;
1179 }
1180
1181 case 2:
1182 if ( comparator.compare( array[1], key ) < 0 )
1183 {
1184 return 1;
1185 }
1186
1187 if ( comparator.compare( array[0], key ) < 0 )
1188 {
1189 return 0;
1190 }
1191 else
1192 {
1193 return -1;
1194 }
1195
1196 default:
1197
1198 int current = size >> 1;
1199 int start = 0;
1200 int end = size - 1;
1201
1202 while ( end - start + 1 > 2 )
1203 {
1204 int res = comparator.compare( array[current], key );
1205
1206 if ( res == 0 )
1207 {
1208 if ( current == 0 )
1209 {
1210 return -1;
1211 }
1212 else
1213 {
1214 return current - 1;
1215 }
1216 }
1217 else if ( res < 0 )
1218 {
1219 start = current;
1220 current = ( current + end + 1 ) >> 1;
1221 }
1222 else
1223 {
1224 end = current;
1225 current = ( current + start + 1 ) >> 1;
1226 }
1227 }
1228
1229 switch ( end - start + 1 )
1230 {
1231 case 1:
1232 if ( comparator.compare( array[start], key ) < 0 )
1233 {
1234 return start;
1235 }
1236 else
1237 {
1238 return -1;
1239 }
1240
1241 case 2:
1242 if ( comparator.compare( array[end], key ) < 0 )
1243 {
1244 return end;
1245 }
1246
1247 if ( comparator.compare( array[start], key ) < 0 )
1248 {
1249 return start;
1250 }
1251 else
1252 {
1253 return -1;
1254 }
1255
1256 default:
1257 return -1;
1258 }
1259 }
1260 }
1261
1262
1263
1264
1265
1266
1267
1268
1269 public boolean contains( K key )
1270 {
1271 return find( key ) != null;
1272 }
1273
1274
1275
1276
1277
1278 public String toString()
1279 {
1280 if ( isEmpty() )
1281 {
1282 return "[]";
1283 }
1284
1285 StringBuilder sb = new StringBuilder();
1286
1287 boolean isFirst = true;
1288
1289 for ( int i = 0; i < size; i++ )
1290 {
1291 K key = array[i];
1292
1293 if ( isFirst )
1294 {
1295 isFirst = false;
1296 }
1297 else
1298 {
1299 sb.append( ", " );
1300 }
1301
1302 sb.append( key );
1303 }
1304
1305 return sb.toString();
1306 }
1307 }