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

remove method in HashSet are not working well

XMLWordPrintable

      FULL PRODUCT VERSION :
      We are tested the same in:
      Machine 1:
      Linux FRAN-WALLAPOP 4.2.0-35-generic #40-Ubuntu SMP Tue Mar 15 22:15:45 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
      java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

      Machine 2:
      Mac OSX 10.11.4
      java version "1.8.0_77"
      Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
      Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      We are tested the same in:
      Machine 1:
      Linux FRAN-WALLAPOP 4.2.0-35-generic #40-Ubuntu SMP Tue Mar 15 22:15:45 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
      java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

      Machine 2:
      Mac OSX 10.11.4
      java version "1.8.0_77"
      Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
      Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      In the code example we expect remove method in HashSet will remove a tree inside a forest but they can't do that.

      REGRESSION. Last worked in version 8u77

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Just run the class using JUnit

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Assert pass
      ACTUAL -
      Assert fail

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package org.amiguitos;

      import org.junit.Assert;
      import org.junit.Test;

      import java.util.*;

      /**
       * Created by Fran Navarro and Josep Ferrer for demostrate error in HashSet implementation on 15/04/16.
       */
      public class TestHashSet {

          @Test
          public void main() {
              org.amiguitos.MagicForest magicForest = setup(5, new org.amiguitos.Edge(0, 1), new org.amiguitos.Edge(2, 3), new org.amiguitos.Edge(1, 4), new org.amiguitos.Edge(3, 4));

              int countTrees = magicForest.countTrees();

              Assert.assertEquals(1, countTrees);
          }

          private org.amiguitos.MagicForest setup(int nodes, org.amiguitos.Edge... edges) {
              List<org.amiguitos.Edge> edgesList = new ArrayList<>();
              for (org.amiguitos.Edge edge : edges) {
                  edgesList.add(edge);
              }

              return new org.amiguitos.MagicForest(nodes, edgesList);
          }


          private class MagicForest {
              private int nodes;
              private List<Edge> edges;

              public MagicForest(int nodes, List<Edge> edges) {
                  this.nodes = nodes;
                  this.edges = edges;
              }

              public int countTrees() {
                  Set<Integer> nodes = new HashSet<>();
                  for (int i = 0; i < this.nodes; i++) {
                      nodes.add(i);
                  }

                  Set<Set<Integer>> forest = new HashSet<>();
                  FindForest findForest = new FindForest();
                  for (Edge edge : this.edges) {
                      Set<Integer> tree = findForest.find(forest, edge);

                      if (tree == null) {
                          tree = new HashSet<>();
                          tree.add(edge.getEdgePU());
                          tree.add(edge.getEdgeDO());

                          forest.add(tree);
                      } else {
                          tree.add(edge.getEdgePU());
                          tree.add(edge.getEdgeDO());
                      }

                      nodes.remove(edge.getEdgePU());
                      nodes.remove(edge.getEdgeDO());
                  }

                  return nodes.size() + forest.size();
              }
          }

          private class FindForest {
              public Set<Integer> find(Set<Set<Integer>> forest, Edge edge) {
                  Set<Integer> treePU = findTreeByNode(forest, edge.getEdgePU());
                  Set<Integer> treeDO = findTreeByNode(forest, edge.getEdgeDO());

                  if (treePU != null && treeDO != null) {
                      /* ------------------------------------------------------------------------------------------
                          We think that this remove are not working well
                       */
                      forest.remove(treeDO);
                      /* ------------------------------------------------------------------------------------------ */
                      treePU.addAll(treeDO);
                      return treePU;
                  } else if (treePU != null) {
                      return treePU;
                  } else if (treeDO != null) {
                      return treeDO;
                  }

                  return null;
              }

              private Set<Integer> findTreeByNode(Set<Set<Integer>> forest, int numNode) {
                  Iterator<Set<Integer>> iterForest = forest.iterator();
                  while (iterForest.hasNext()) {
                      Set<Integer> tree = iterForest.next();
                      Iterator<Integer> nodes = tree.iterator();
                      while (nodes.hasNext()) {
                          Integer node = nodes.next();
                          if (node.equals(numNode)) {
                              return tree;
                          }
                      }
                  }
                  return null;
              }
          }


          private class Edge {

              private int edgePU;
              private int edgeDO;

              public Edge(int edgePU, int edgeDO) {
                  this.edgePU = edgePU;
                  this.edgeDO = edgeDO;
              }

              public boolean contains(int edge) {
                  if (edge == edgePU || edge == edgeDO) {
                      return true;
                  }

                  return false;
              }

              public int getEdgePU() {
                  return edgePU;
              }

              public int getEdgeDO() {
                  return edgeDO;
              }
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Uknown

            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: