ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java (file contents):
Revision 1.110 by jsr166, Wed Apr 27 14:06:30 2011 UTC vs.
Revision 1.111 by jsr166, Thu Apr 28 00:15:06 2011 UTC

# Line 840 | Line 840 | public class ConcurrentHashMap<K, V> ext
840          // Try a few times to get accurate count. On failure due to
841          // continuous async changes in table, resort to locking.
842          final Segment<K,V>[] segments = this.segments;
843 <        int size;
844 <        boolean overflow; // true if size overflows 32 bits
845 <        long sum;         // sum of modCounts
846 <        long last = 0L;   // previous sum
847 <        int retries = -1; // first iteration isn't retry
848 <        try {
849 <            for (;;) {
850 <                if (retries++ == RETRIES_BEFORE_LOCK) {
851 <                    for (int j = 0; j < segments.length; ++j)
852 <                        ensureSegment(j).lock(); // force creation
853 <                }
854 <                sum = 0L;
855 <                size = 0;
856 <                overflow = false;
857 <                for (int j = 0; j < segments.length; ++j) {
858 <                    Segment<K,V> seg = segmentAt(segments, j);
859 <                    if (seg != null) {
860 <                        sum += seg.modCount;
861 <                        int c = seg.count;
862 <                        if (c < 0 || (size += c) < 0)
863 <                            overflow = true;
864 <                    }
843 >        final int segmentCount = segments.length;
844 >
845 >        long previousSum = 0L;
846 >        for (int retries = -1; retries < RETRIES_BEFORE_LOCK; retries++) {
847 >            long sum = 0L;    // sum of modCounts
848 >            long size = 0L;
849 >            for (int i = 0; i < segmentCount; i++) {
850 >                Segment<K,V> segment = segmentAt(segments, i);
851 >                if (segment != null) {
852 >                    sum += segment.modCount;
853 >                    size += segment.count;
854                  }
866                if (sum == last)
867                    break;
868                last = sum;
869            }
870        } finally {
871            if (retries > RETRIES_BEFORE_LOCK) {
872                for (int j = 0; j < segments.length; ++j)
873                    segmentAt(segments, j).unlock();
855              }
856 +            if (sum == previousSum)
857 +                return ((size >>> 31) == 0) ? (int) size : Integer.MAX_VALUE;
858 +            previousSum = sum;
859          }
860 <        return overflow ? Integer.MAX_VALUE : size;
860 >
861 >        long size = 0L;
862 >        for (int i = 0; i < segmentCount; i++) {
863 >            Segment<K,V> segment = ensureSegment(i);
864 >            segment.lock();
865 >            size += segment.count;
866 >        }
867 >        for (int i = 0; i < segmentCount; i++)
868 >            segments[i].unlock();
869 >        return ((size >>> 31) == 0) ? (int) size : Integer.MAX_VALUE;
870      }
871  
872      /**
# Line 949 | Line 942 | public class ConcurrentHashMap<K, V> ext
942          if (value == null)
943              throw new NullPointerException();
944          final Segment<K,V>[] segments = this.segments;
945 <        boolean found = false;
946 <        long last = 0L;   // previous sum
954 <        int retries = -1;
945 >        long previousSum = 0L;
946 >        int lockCount = 0;
947          try {
948 <            outer: for (;;) {
949 <                if (retries++ == RETRIES_BEFORE_LOCK) {
950 <                    for (int j = 0; j < segments.length; ++j)
951 <                        ensureSegment(j).lock(); // force creation
952 <                }
953 <                long sum = 0L;
954 <                for (int j = 0; j < segments.length; ++j) {
955 <                    HashEntry<K,V>[] tab;
956 <                    Segment<K,V> seg = segmentAt(segments, j);
957 <                    if (seg != null && (tab = seg.table) != null) {
948 >            for (int retries = -1; ; retries++) {
949 >                long sum = 0L;    // sum of modCounts
950 >                for (int j = 0; j < segments.length; j++) {
951 >                    Segment<K,V> segment;
952 >                    if (retries == RETRIES_BEFORE_LOCK) {
953 >                        segment = ensureSegment(j);
954 >                        segment.lock();
955 >                        lockCount++;
956 >                    } else {
957 >                        segment = segmentAt(segments, j);
958 >                        if (segment == null)
959 >                            continue;
960 >                    }
961 >                    HashEntry<K,V>[] tab = segment.table;
962 >                    if (tab != null) {
963                          for (int i = 0 ; i < tab.length; i++) {
964                              HashEntry<K,V> e;
965                              for (e = entryAt(tab, i); e != null; e = e.next) {
966                                  V v = e.value;
967 <                                if (v != null && value.equals(v)) {
968 <                                    found = true;
972 <                                    break outer;
973 <                                }
967 >                                if (v != null && value.equals(v))
968 >                                    return true;
969                              }
970                          }
971 <                        sum += seg.modCount;
971 >                        sum += segment.modCount;
972                      }
973                  }
974 <                if (retries > 0 && sum == last)
975 <                    break;
976 <                last = sum;
974 >                if ((retries >= 0 && sum == previousSum) || lockCount > 0)
975 >                    return false;
976 >                previousSum = sum;
977              }
978          } finally {
979 <            if (retries > RETRIES_BEFORE_LOCK) {
980 <                for (int j = 0; j < segments.length; ++j)
986 <                    segmentAt(segments, j).unlock();
987 <            }
979 >            for (int j = 0; j < lockCount; j++)
980 >                segments[j].unlock();
981          }
989        return found;
982      }
983  
984      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines