1 package org.codehaus.plexus.util;
2
3
4
5
6
7
8
9 import java.io.IOException;
10 import java.io.ObjectInputStream;
11 import java.io.ObjectOutputStream;
12 import java.io.Serializable;
13 import java.util.AbstractCollection;
14 import java.util.AbstractSet;
15 import java.util.Collection;
16 import java.util.Iterator;
17 import java.util.Map;
18 import java.util.Set;
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 public class FastMap<K, V>
57 implements Map<K, V>, Cloneable, Serializable
58 {
59
60
61
62
63 private transient EntryImpl[] _entries;
64
65
66
67
68 private transient int _capacity;
69
70
71
72
73 private transient int _mask;
74
75
76
77
78 private transient EntryImpl _poolFirst;
79
80
81
82
83 private transient EntryImpl _mapFirst;
84
85
86
87
88 private transient EntryImpl _mapLast;
89
90
91
92
93 private transient int _size;
94
95
96
97
98 public FastMap()
99 {
100 initialize( 256 );
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public FastMap( Map map )
116 {
117 int capacity = ( map instanceof FastMap ) ? ( (FastMap) map ).capacity() : map.size();
118 initialize( capacity );
119 putAll( map );
120 }
121
122
123
124
125
126
127
128
129 public FastMap( int capacity )
130 {
131 initialize( capacity );
132 }
133
134
135
136
137
138
139 @Override
140 public int size()
141 {
142 return _size;
143 }
144
145
146
147
148
149
150
151 public int capacity()
152 {
153 return _capacity;
154 }
155
156
157
158
159
160
161 @Override
162 public boolean isEmpty()
163 {
164 return _size == 0;
165 }
166
167
168
169
170
171
172
173
174 @Override
175 public boolean containsKey( Object key )
176 {
177 EntryImpl entry = _entries[keyHash( key ) & _mask];
178 while ( entry != null )
179 {
180 if ( key.equals( entry._key ) )
181 {
182 return true;
183 }
184 entry = entry._next;
185 }
186 return false;
187 }
188
189
190
191
192
193
194
195
196 @Override
197 public boolean containsValue( Object value )
198 {
199 EntryImpl entry = _mapFirst;
200 while ( entry != null )
201 {
202 if ( value.equals( entry._value ) )
203 {
204 return true;
205 }
206 entry = entry._after;
207 }
208 return false;
209 }
210
211
212
213
214
215
216
217
218
219 @Override
220 public V get( Object key )
221 {
222 EntryImpl<K, V> entry = _entries[keyHash( key ) & _mask];
223 while ( entry != null )
224 {
225 if ( key.equals( entry._key ) )
226 {
227 return entry._value;
228 }
229 entry = entry._next;
230 }
231 return null;
232 }
233
234
235
236
237
238
239
240 public Map.Entry getEntry( Object key )
241 {
242 EntryImpl entry = _entries[keyHash( key ) & _mask];
243 while ( entry != null )
244 {
245 if ( key.equals( entry._key ) )
246 {
247 return entry;
248 }
249 entry = entry._next;
250 }
251 return null;
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265 @Override
266 public Object put( Object key, Object value )
267 {
268 EntryImpl entry = _entries[keyHash( key ) & _mask];
269 while ( entry != null )
270 {
271 if ( key.equals( entry._key ) )
272 {
273 Object prevValue = entry._value;
274 entry._value = value;
275 return prevValue;
276 }
277 entry = entry._next;
278 }
279
280 addEntry( key, value );
281 return null;
282 }
283
284
285
286
287
288
289
290
291 @Override
292 public void putAll( Map<? extends K, ? extends V> map )
293 {
294 for ( Entry<? extends K, ? extends V> entry : map.entrySet() )
295 {
296 addEntry( entry.getKey(), entry.getValue() );
297 }
298 }
299
300
301
302
303
304
305
306
307
308
309 @Override
310 public V remove( Object key )
311 {
312 EntryImpl<K, V> entry = _entries[keyHash( key ) & _mask];
313 while ( entry != null )
314 {
315 if ( key.equals( entry._key ) )
316 {
317 V prevValue = entry._value;
318 removeEntry( entry );
319 return prevValue;
320 }
321 entry = entry._next;
322 }
323 return null;
324 }
325
326
327
328
329 @Override
330 public void clear()
331 {
332
333 for ( EntryImpl entry = _mapFirst; entry != null; entry = entry._after )
334 {
335 entry._key = null;
336 entry._value = null;
337 entry._before = null;
338 entry._next = null;
339 if ( entry._previous == null )
340 {
341 _entries[entry._index] = null;
342 }
343 else
344 {
345 entry._previous = null;
346 }
347 }
348
349
350 if ( _mapLast != null )
351 {
352 _mapLast._after = _poolFirst;
353 _poolFirst = _mapFirst;
354 _mapFirst = null;
355 _mapLast = null;
356 _size = 0;
357 sizeChanged();
358 }
359 }
360
361
362
363
364
365
366
367
368 public void setCapacity( int newCapacity )
369 {
370 if ( newCapacity > _capacity )
371 {
372 for ( int i = _capacity; i < newCapacity; i++ )
373 {
374 EntryImpl entry = new EntryImpl();
375 entry._after = _poolFirst;
376 _poolFirst = entry;
377 }
378 }
379 else if ( newCapacity < _capacity )
380 {
381 for ( int i = newCapacity; ( i < _capacity ) && ( _poolFirst != null ); i++ )
382 {
383
384 EntryImpl entry = _poolFirst;
385 _poolFirst = entry._after;
386 entry._after = null;
387 }
388 }
389
390 int tableLength = 16;
391 while ( tableLength < newCapacity )
392 {
393 tableLength <<= 1;
394 }
395
396 if ( _entries.length != tableLength )
397 {
398 _entries = new EntryImpl[tableLength];
399 _mask = tableLength - 1;
400
401
402 EntryImpl entry = _mapFirst;
403 while ( entry != null )
404 {
405 int index = keyHash( entry._key ) & _mask;
406 entry._index = index;
407
408
409 entry._previous = null;
410 EntryImpl next = _entries[index];
411 entry._next = next;
412 if ( next != null )
413 {
414 next._previous = entry;
415 }
416 _entries[index] = entry;
417
418 entry = entry._after;
419 }
420 }
421 _capacity = newCapacity;
422 }
423
424
425
426
427
428
429 @Override
430 public Object clone()
431 {
432 try
433 {
434 FastMap clone = (FastMap) super.clone();
435 clone.initialize( _capacity );
436 clone.putAll( this );
437 return clone;
438 }
439 catch ( CloneNotSupportedException e )
440 {
441
442 throw new InternalError();
443 }
444 }
445
446
447
448
449
450
451
452
453 @Override
454 public boolean equals( Object obj )
455 {
456 if ( obj == this )
457 {
458 return true;
459 }
460 else if ( obj instanceof Map )
461 {
462 Map that = (Map) obj;
463 if ( this.size() == that.size() )
464 {
465 EntryImpl entry = _mapFirst;
466 while ( entry != null )
467 {
468 if ( !that.entrySet().contains( entry ) )
469 {
470 return false;
471 }
472 entry = entry._after;
473 }
474 return true;
475 }
476 else
477 {
478 return false;
479 }
480 }
481 else
482 {
483 return false;
484 }
485 }
486
487
488
489
490
491
492 @Override
493 public int hashCode()
494 {
495 int code = 0;
496 EntryImpl entry = _mapFirst;
497 while ( entry != null )
498 {
499 code += entry.hashCode();
500 entry = entry._after;
501 }
502 return code;
503 }
504
505
506
507
508
509
510 @Override
511 public String toString()
512 {
513 return entrySet().toString();
514 }
515
516
517
518
519
520
521
522
523
524
525 @Override
526 public Collection values()
527 {
528 return _values;
529 }
530
531 private transient Values _values;
532
533 private class Values
534 extends AbstractCollection
535 {
536 @Override
537 public Iterator iterator()
538 {
539 return new Iterator()
540 {
541 EntryImpl after = _mapFirst;
542
543 EntryImpl before;
544
545 @Override
546 public void remove()
547 {
548 removeEntry( before );
549 }
550
551 @Override
552 public boolean hasNext()
553 {
554 return after != null;
555 }
556
557 @Override
558 public Object next()
559 {
560 before = after;
561 after = after._after;
562 return before._value;
563 }
564 };
565 }
566
567 @Override
568 public int size()
569 {
570 return _size;
571 }
572
573 @Override
574 public boolean contains( Object o )
575 {
576 return containsValue( o );
577 }
578
579 @Override
580 public void clear()
581 {
582 FastMap.this.clear();
583 }
584 }
585
586
587
588
589
590
591
592
593
594
595
596 @Override
597 public Set entrySet()
598 {
599 return _entrySet;
600 }
601
602 private transient EntrySet _entrySet;
603
604 private class EntrySet
605 extends AbstractSet
606 {
607 @Override
608 public Iterator iterator()
609 {
610 return new Iterator()
611 {
612 EntryImpl after = _mapFirst;
613
614 EntryImpl before;
615
616 @Override
617 public void remove()
618 {
619 removeEntry( before );
620 }
621
622 @Override
623 public boolean hasNext()
624 {
625 return after != null;
626 }
627
628 @Override
629 public Object next()
630 {
631 before = after;
632 after = after._after;
633 return before;
634 }
635 };
636 }
637
638 @Override
639 public int size()
640 {
641 return _size;
642 }
643
644 @Override
645 public boolean contains( Object obj )
646 {
647 if ( obj instanceof Map.Entry )
648 {
649 Map.Entry entry = (Map.Entry) obj;
650 Map.Entry mapEntry = getEntry( entry.getKey() );
651 return entry.equals( mapEntry );
652 }
653 else
654 {
655 return false;
656 }
657 }
658
659 @Override
660 public boolean remove( Object obj )
661 {
662 if ( obj instanceof Map.Entry )
663 {
664 Map.Entry entry = (Map.Entry) obj;
665 EntryImpl mapEntry = (EntryImpl) getEntry( entry.getKey() );
666 if ( ( mapEntry != null ) && ( entry.getValue() ).equals( mapEntry._value ) )
667 {
668 removeEntry( mapEntry );
669 return true;
670 }
671 }
672 return false;
673 }
674 }
675
676
677
678
679
680
681
682
683
684
685 @Override
686 public Set keySet()
687 {
688 return _keySet;
689 }
690
691 private transient KeySet _keySet;
692
693 private class KeySet
694 extends AbstractSet
695 {
696 @Override
697 public Iterator iterator()
698 {
699 return new Iterator()
700 {
701 EntryImpl after = _mapFirst;
702
703 EntryImpl before;
704
705 @Override
706 public void remove()
707 {
708 removeEntry( before );
709 }
710
711 @Override
712 public boolean hasNext()
713 {
714 return after != null;
715 }
716
717 @Override
718 public Object next()
719 {
720 before = after;
721 after = after._after;
722 return before._key;
723 }
724 };
725 }
726
727 @Override
728 public int size()
729 {
730 return _size;
731 }
732
733 @Override
734 public boolean contains( Object obj )
735 {
736 return FastMap.this.containsKey( obj );
737 }
738
739 @Override
740 public boolean remove( Object obj )
741 {
742 return FastMap.this.remove( obj ) != null;
743 }
744
745 @Override
746 public void clear()
747 {
748 FastMap.this.clear();
749 }
750 }
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769 protected void sizeChanged()
770 {
771 if ( size() > capacity() )
772 {
773 setCapacity( capacity() * 2 );
774 }
775 }
776
777
778
779
780
781
782
783
784 private static int keyHash( Object key )
785 {
786
787 int hashCode = key.hashCode();
788 hashCode += ~( hashCode << 9 );
789 hashCode ^= ( hashCode >>> 14 );
790 hashCode += ( hashCode << 4 );
791 hashCode ^= ( hashCode >>> 10 );
792 return hashCode;
793 }
794
795
796
797
798
799
800
801 private void addEntry( Object key, Object value )
802 {
803 EntryImpl entry = _poolFirst;
804 if ( entry != null )
805 {
806 _poolFirst = entry._after;
807 entry._after = null;
808 }
809 else
810 {
811 entry = new EntryImpl();
812 }
813
814
815 entry._key = key;
816 entry._value = value;
817 int index = keyHash( key ) & _mask;
818 entry._index = index;
819
820
821 EntryImpl next = _entries[index];
822 entry._next = next;
823 if ( next != null )
824 {
825 next._previous = entry;
826 }
827 _entries[index] = entry;
828
829
830 if ( _mapLast != null )
831 {
832 entry._before = _mapLast;
833 _mapLast._after = entry;
834 }
835 else
836 {
837 _mapFirst = entry;
838 }
839 _mapLast = entry;
840
841
842 _size++;
843 sizeChanged();
844 }
845
846
847
848
849
850
851 private void removeEntry( EntryImpl entry )
852 {
853
854
855 EntryImpl previous = entry._previous;
856 EntryImpl next = entry._next;
857 if ( previous != null )
858 {
859 previous._next = next;
860 entry._previous = null;
861 }
862 else
863 {
864 _entries[entry._index] = next;
865 }
866 if ( next != null )
867 {
868 next._previous = previous;
869 entry._next = null;
870 }
871
872
873 EntryImpl before = entry._before;
874 EntryImpl after = entry._after;
875 if ( before != null )
876 {
877 before._after = after;
878 entry._before = null;
879 }
880 else
881 {
882 _mapFirst = after;
883 }
884 if ( after != null )
885 {
886 after._before = before;
887 }
888 else
889 {
890 _mapLast = before;
891 }
892
893
894 entry._key = null;
895 entry._value = null;
896
897
898 entry._after = _poolFirst;
899 _poolFirst = entry;
900
901
902 _size--;
903 sizeChanged();
904 }
905
906
907
908
909
910
911
912 private void initialize( int capacity )
913 {
914
915 int tableLength = 16;
916 while ( tableLength < capacity )
917 {
918 tableLength <<= 1;
919 }
920
921 _entries = new EntryImpl[tableLength];
922 _mask = tableLength - 1;
923 _capacity = capacity;
924 _size = 0;
925
926 _values = new Values();
927 _entrySet = new EntrySet();
928 _keySet = new KeySet();
929
930 _poolFirst = null;
931 _mapFirst = null;
932 _mapLast = null;
933
934 for ( int i = 0; i < capacity; i++ )
935 {
936 EntryImpl entry = new EntryImpl();
937 entry._after = _poolFirst;
938 _poolFirst = entry;
939 }
940 }
941
942
943
944
945
946
947
948
949 private void readObject( ObjectInputStream stream )
950 throws IOException, ClassNotFoundException
951 {
952 int capacity = stream.readInt();
953 initialize( capacity );
954 int size = stream.readInt();
955 for ( int i = 0; i < size; i++ )
956 {
957 Object key = stream.readObject();
958 Object value = stream.readObject();
959 addEntry( key, value );
960 }
961 }
962
963
964
965
966
967
968
969 private void writeObject( ObjectOutputStream stream )
970 throws IOException
971 {
972 stream.writeInt( _capacity );
973 stream.writeInt( _size );
974 int count = 0;
975 EntryImpl entry = _mapFirst;
976 while ( entry != null )
977 {
978 stream.writeObject( entry._key );
979 stream.writeObject( entry._value );
980 count++;
981 entry = entry._after;
982 }
983 if ( count != _size )
984 {
985 throw new IOException( "FastMap Corrupted" );
986 }
987 }
988
989
990
991
992 private static final class EntryImpl<K, V>
993 implements Map.Entry<K, V>
994 {
995
996
997
998
999 private K _key;
1000
1001
1002
1003
1004 private V _value;
1005
1006
1007
1008
1009 private int _index;
1010
1011
1012
1013
1014 private EntryImpl _previous;
1015
1016
1017
1018
1019 private EntryImpl _next;
1020
1021
1022
1023
1024 private EntryImpl _before;
1025
1026
1027
1028
1029 private EntryImpl _after;
1030
1031
1032
1033
1034
1035
1036 @Override
1037 public K getKey()
1038 {
1039 return _key;
1040 }
1041
1042
1043
1044
1045
1046
1047 @Override
1048 public V getValue()
1049 {
1050 return _value;
1051 }
1052
1053
1054
1055
1056
1057
1058
1059 @Override
1060 public V setValue( V value )
1061 {
1062 V old = _value;
1063 _value = value;
1064 return old;
1065 }
1066
1067
1068
1069
1070
1071
1072
1073 @Override
1074 public boolean equals( Object that )
1075 {
1076 if ( that instanceof Map.Entry )
1077 {
1078 Map.Entry entry = (Map.Entry) that;
1079 return ( _key.equals( entry.getKey() ) )
1080 && ( ( _value != null ) ? _value.equals( entry.getValue() ) : ( entry.getValue() == null ) );
1081 }
1082 else
1083 {
1084 return false;
1085 }
1086 }
1087
1088
1089
1090
1091
1092
1093 @Override
1094 public int hashCode()
1095 {
1096 return _key.hashCode() ^ ( ( _value != null ) ? _value.hashCode() : 0 );
1097 }
1098
1099
1100
1101
1102
1103
1104 @Override
1105 public String toString()
1106 {
1107 return _key + "=" + _value;
1108 }
1109 }
1110 }