Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8160751

Optimize ConcurrentHashMap.keySet().removeAll

XMLWordPrintable

      FULL PRODUCT VERSION :

      C:\tools\Java\jdk1.8.0_45\bin>java -version
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Window 7 64 bit.

      A DESCRIPTION OF THE PROBLEM :
      Hi Team

      We have an issue related to removeAll() implementation of Map in Java 8. As per the current implementation we are iterating the whole data structure to remove a single or no element (If the collection passed doesn't have any element).

      Please review the attached sample code and do a JVisual VM profiling.





       

      REGRESSION. Last worked in version 8u73

      ADDITIONAL REGRESSION INFORMATION:
      C:\tools\Java\jdk1.8.0_45\bin>java -version
      java version "1.8.0_45"
      Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Sample code and JVisualVM profiler snapshot attached.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Should work similar to JDK 7 logic. In order to remove a single entry we must not iterate the whole data structure.

      public boolean removeAll(Collection<?> c) {
              boolean modified = false;

              if (size() > c.size()) {
                  for (Iterator<?> i = c.iterator(); i.hasNext(); )
                      modified |= remove(i.next());
              } else {
                  for (Iterator<?> i = iterator(); i.hasNext(); ) {
                      if (c.contains(i.next())) {
                          i.remove();
                          modified = true;
                      }
                  }
              }
              return modified;
          }
      ACTUAL -
       In order to remove a single entry we must not iterate the whole data structure.
      public final boolean removeAll(Collection<?> c) {
                  if (c == null) throw new NullPointerException();
                  boolean modified = false;
                  for (Iterator<E> it = iterator(); it.hasNext();) {
                      if (c.contains(it.next())) {
                          it.remove();
                          modified = true;
                      }
                  }
                  return modified;
              }

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class TestConcurrentHashMap {

      public static void main(String[] args) {
      Map<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();

      for (int i=0; i<10000000; i++) {
      map.put(i, i);
      }

      List<Integer> oList = new ArrayList<Integer>();
      oList.add(9998);
      oList.add(9999);

      map.keySet().removeAll(oList);
      System.out.println(map);
      }

      }

      ---------- END SOURCE ----------

            martin Martin Buchholz
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: