Hi all,

I recently thought about how to resize hashmaps. When looking at the
JDK 6 source, I saw that java.util.HashMap always transfers old
entries from the old table. When memory is tight, it might be better
to first concatenate the entry lists into one big list, throw away the
old table, allocate the new one, and then fill it from the
concatenated list. So:

        @Override
        void resize( int _newCapacity )
        {
                try {
                        fastResize( _newCapacity ); // This would be the 
current resize code.
                }
                catch (OutOfMemoryError e) {
                        tightResize( _newCapacity );
                }
        }

        @SuppressWarnings( "unchecked" )
        private void tightResize( int newCapacity )
        {
                Entry head = joinLists();
                table = new Entry[ newCapacity ];
                threshold = (int) (newCapacity * loadFactor);
                transfer( head, table );
        }

        @SuppressWarnings("unchecked")
        private Entry joinLists()
        {
                final Entry[] src = table;
                final int n = src.length;
                Entry head = null;
                int i = 0;
                while (i < n && null == head) {
                        head = src[ i++ ];
                }
                Entry tail = head;
                assert i >= n || null != tail;
                while (i < n) {
                        Entry e = src[ i++ ];
                        if (null != e) {
                                tail.next = e;
                                do {
                                        tail = e;
                                        e = e.next;
                                } while (null != e);
                        }
                }
                return head;
        }

        @SuppressWarnings("unchecked")
        private void transfer( Entry head, Entry[] tgt )
        {
                int n = capacity();
                while (head != null) {
                        Entry e = head;
                        head = head.next;
                        int i = indexFor( e.hash, n );
                        e.next = tgt[ i ];
                        tgt[ i ] = e;
                }
        }


What do you think?
-peo

Reply via email to