Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source.
   * Copyright 2010, Red Hat, Inc., and individual contributors
   * as indicated by the @author tags. See the copyright.txt file in the
   * distribution for a full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
 package org.jboss.remoting3;
 
 import java.util.Set;
 
 final class UnlockedReadHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
 
     private static final int DEFAULT_INITIAL_CAPACITY = 512;
     private static final int MAXIMUM_CAPACITY = 1 << 30;
     private static final float DEFAULT_LOAD_FACTOR = 0.60f;
 
     // Final fields (thread-safe)
     private final Object writeLock = new Object();
     private final Set<Entry<K, V>> entrySet = new EntrySet();
     private final float loadFactor;
 
     // Volatile fields (writes protected by {@link #writeLock})
     private volatile int size;
     private volatile AtomicReferenceArray<Item<K,V>[]> table;
 
     // Raw fields (reads and writes protected by {@link #writeLock}
     private int threshold;
 
     UnlockedReadHashMap(int initialCapacityfinal float loadFactor) {
         if (initialCapacity < 0) {
             throw new IllegalArgumentException("Initial capacity must be > 0");
         }
         if (initialCapacity > ) {
             initialCapacity = ;
         }
         if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
             throw new IllegalArgumentException("Load factor must be > 0.0f");
         }
 
         int capacity = 1;
 
         while (capacity < initialCapacity) {
             capacity <<= 1;
         }
 
         this. = loadFactor;
         synchronized () {
              = (int)(capacity * loadFactor);
              = new AtomicReferenceArray<Item<K, V>[]>(capacity);
         }
     }
 
     UnlockedReadHashMap(final float loadFactor) {
         this(loadFactor);
     }
 
     UnlockedReadHashMap(final int initialCapacity) {
         this(initialCapacity);
     }
 
     UnlockedReadHashMap() {
     }
 
     @SuppressWarnings( { "unchecked" })
     private void resize() {
         assert Thread.holdsLock();
         final AtomicReferenceArray<Item<K, V>[]> oldTable = ;
         final int oldCapacity = oldTable.length();
         if (oldCapacity == ) {
             return;
         }
         final int newCapacity = oldCapacity << 1;
         final AtomicReferenceArray<Item<K, V>[]> newTable = new AtomicReferenceArray<Item<K, V>[]>(newCapacity);
         final int newThreshold = (int)(newCapacity * );
         for (int i = 0; i < oldCapacityi ++) {
            final Item<K, V>[] items = oldTable.get(i);
            if (items != null) {
                final int length = items.length;
                for (int j = 0; j < lengthj++) {
                    Item<K, V> item = items[j];
                    final int hc = item.hashCode() & (newCapacity - 1);
                    final Item<K, V>[] old = newTable.get(hc);
                    if (old == null) {
                        newTable.lazySet(hcnew Item[] { item });
                    } else {
                        final int oldLen = old.length;
                        final Item<K, V>[] copy = Arrays.copyOf(oldoldLen + 1);
                        copy[oldLen] = item;
                        newTable.lazySet(hccopy);
                    }
                }
            }
        }
         = newTable;
         = newThreshold;
    }
    private static <K, V> Item<K, V> doGet(final AtomicReferenceArray<Item<K, V>[]> tablefinal Object key) {
        Item<K, V>[] row = doGetRow(tablekey);
        return row == null ? null : doGet(rowkey);
    }
    private static <K, V> Item<K, V>[] doGetRow(final AtomicReferenceArray<Item<K, V>[]> tablefinal Object key) {
        final int hc = getIndex(tablekey);
        return doGetRow(tablehc);
    }
    private static <K, V> int getIndex(final AtomicReferenceArray<Item<K, V>[]> tablefinal Object key) {
        return key.hashCode() & (table.length() - 1);
    }
    private static <K, V> Item<K, V>[] doGetRow(final AtomicReferenceArray<Item<K, V>[]> tablefinal int hc) {
        return table.get(hc);
    }
    private static <K, V> Item<K, V> doGet(Item<K, V>[] rowObject key) {
        for (Item<K, V> item : row) {
            if (item.key.equals(key)) {
                return item;
            }
        }
        return null;
    }
    private V doPut(AtomicReferenceArray<Item<K, V>[]> table, K key, V valueboolean ifAbsent) {
        final int hc = getIndex(tablekey);
        final Item<K, V>[] old = doGetRow(tablehc);
        if (old == null) {
            @SuppressWarnings( { "unchecked" })
            final Item<K, V>[] newRow = new Item[] { new Item<K, V>(keyvalue) };
            table.set(hcnewRow);
            if (++ == ) {
                resize();
            }
            return null;
        } else {
            final Item<K, V> item = doGet(oldkey);
            if (item != null) {
                try {
                    return item.value;
                } finally {
                    if (! ifAbsentitem.value = value;
                }
            }
            final int oldLen = old.length;
            final Item<K, V>[] newRow = Arrays.copyOf(oldoldLen + 1);
            newRow[oldLen] = new Item<K, V>(keyvalue);
            table.set(hcnewRow);
            if (++ == ) {
                resize();
            }
            return null;
        }
    }
    private static <K, V> Item<K, V>[] remove(Item<K, V>[] rowint idx) {
        final int len = row.length;
        assert idx < len;
        if (len == 1) {
            return null;
        }
        @SuppressWarnings("unchecked")
        Item<K, V>[] newRow = new Item[len - 1];
        if (idx > 0) {
            System.arraycopy(row, 0, newRow, 0, idx);
        }
        if (idx < len - 1) {
            System.arraycopy(rowidx + 1, newRowidxlen - 1 - idx);
        }
        return newRow;
    }
    public Set<Entry<K, V>> entrySet() {
        return ;
    }
    public int size() {
        return ;
    }
    public boolean containsKey(final Object key) {
        if (key == null) {
            return false;
        }
        final Item<K, V> item = doGet(key);
        return item != null;
    }
    public V get(final Object key) {
        if (key == null) {
            return null;
        }
        final Item<K, V> item = doGet(key);
        return item == null ? null : item.value;
    }
    public V put(final K keyfinal V value) {
        if (key == null) {
            throw new IllegalArgumentException("key is null");
        }
        synchronized () {
            return doPut(keyvaluefalse);
        }
    }
    public V remove(final Object key) {
        if (key == null) {
            return null;
        }
        synchronized () {
            final int hc = getIndex(key);
            final Item<K, V>[] row = doGetRow(hc);
            if (row == null) {
                return null;
            }
            final int rowLen = row.length;
            for (int i = 0; i < rowLeni++) {
                final Item<K, V> item = row[i];
                if (item.key.equals(key)) {
                    .set(hcremove(rowi));
                     --;
                    return item.value;
                }
            }
            return null;
        }
    }
    public void clear() {
        synchronized () {
             = new AtomicReferenceArray<Item<K, V>[]>(.length());
             = 0;
        }
    }
    public V putIfAbsent(final K keyfinal V value) {
        if (key == null) {
            throw new IllegalArgumentException("key is null");
        }
        synchronized () {
            return doPut(keyvaluetrue);
        }
    }
    public boolean remove(final Object keyfinal Object value) {
        if (key == null) {
            return false;
        }
        synchronized () {
            final int hc = getIndex(key);
            final Item<K, V>[] row = doGetRow(hc);
            if (row == null) {
                return false;
            }
            final int rowLen = row.length;
            for (int i = 0; i < rowLeni++) {
                final Item<K, V> item = row[i];
                if (item.key.equals(key) && (value == null ? item.value == null : value.equals(item.value))) {
                    .set(hcremove(rowi));
                     --;
                    return true;
                }
            }
            return false;
        }
    }
    public boolean replace(final K keyfinal V oldValuefinal V newValue) {
        if (key == null) {
            return false;
        }
        synchronized () {
            final Item<K, V> item = doGet(key);
            if (item != null) {
                if (oldValue == null ? item.value == null : oldValue.equals(item.value)) {
                    item.value = newValue;
                    return true;
                }
            }
            return false;
        }
    }
    public V replace(final K keyfinal V value) {
        if (key == null) {
            return null;
        }
        synchronized () {
            final Item<K, V> item = doGet(key);
            if (item != nulltry {
                return item.value;
            } finally {
                item.value = value;
            }
            return null;
        }
    }
    private final class EntrySet extends AbstractSet<Entry<K, V>> implements Set<Entry<K, V>> {
        public Iterator<Entry<K, V>> iterator() {
            return new EntryIterator();
        }
        public int size() {
            return UnlockedReadHashMap.this.size();
        }
    }
    private final class EntryIterator implements Iterator<Entry<K, V>> {
        private final AtomicReferenceArray<Item<K,V>[]> table = UnlockedReadHashMap.this.;
        private int tableIdx;
        private int itemIdx;
        private Item<K, V> next;
        public boolean hasNext() {
            while ( == null) {
                if (.length() == ) {
                    return false;
                }
                final Item<K, V>[] items = .get();
                if (items != null) {
                    final int len = items.length;
                    if ( < len) {
                         = items[++];
                        return true;
                    }
                }
                 = 0;
                ++;
            }
            return true;
        }
        public Entry<K, V> next() {
            if (hasNext()) try {
                return ;
            } finally {
                 = null;
            }
            throw new NoSuchElementException();
        }
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final class Item<K, V> implements Entry<K, V> {
        private final K key;
        private volatile V value;
        private Item(final K keyfinal V value) {
            this. = key;
            this. = value;
        }
        public K getKey() {
            return ;
        }
        public V getValue() {
            return ;
        }
        public V setValue(final V value) {
            try {
                return this.;
            } finally {
                this. = value;
            }
        }
        public int hashCode() {
            return .hashCode();
        }
        public boolean equals(final Object obj) {
            return obj instanceof Item && equals((Item<?,?>) obj);
        }
        public boolean equals(final Item<?, ?> obj) {
            return obj != null && obj.key.equals();
        }
    }
New to GrepCode? Check out our FAQ X