This project has retired. For details please refer to its Attic page.
CollectionUtils xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.giraph.utils;
20  
21  import com.google.common.collect.Iterables;
22  import java.util.Collection;
23  import java.util.Iterator;
24  import java.util.concurrent.ConcurrentMap;
25  import org.apache.log4j.Logger;
26  
27  /** Helper methods for Collections */
28  public class CollectionUtils {
29    /** Class logger */
30    private static final Logger LOG = Logger.getLogger(CollectionUtils.class);
31  
32    /** Do not instantiate. */
33    private CollectionUtils() { }
34  
35    /**
36     * If map already has a value associated with the key it adds values to that
37     * value, otherwise it will put values to the map.  Do not reuse values.
38     *
39     * @param key    Key under which we are adding values
40     * @param values Values we want to add
41     * @param map    Map which we are adding values to
42     * @param <K> Key
43     * @param <V> Value
44     * @param <C> Collection
45     * @return New value associated with the key
46     */
47    public static <K, V, C extends Collection<V>> C addConcurrent(K key,
48        C values, ConcurrentMap<K, C> map) {
49      C currentValues = map.get(key);
50      if (currentValues == null) {
51        currentValues = map.putIfAbsent(key, values);
52        if (currentValues == null) {
53          return values;
54        }
55      }
56      synchronized (currentValues) {
57        currentValues.addAll(values);
58      }
59      return currentValues;
60    }
61  
62    /**
63     * Helper method to check if iterables are equal.  Supports the case
64     * where the iterable next() returns a reused object.  We do assume that
65     * iterator() produces the objects in the same order across repeated calls,
66     * if the object doesn't change.   This is very expensive (n^2) and should
67     * be used for testing only.
68     *
69     * @param first First iterable
70     * @param second Second iterable
71     * @param <T> Type to compare
72     * @return True if equal, false otherwise
73     */
74    public static <T> boolean isEqual(Iterable<T> first, Iterable<T> second) {
75      // Relies on elements from the iterator arriving in the same order.
76      // For every element in first, check elements on the second iterable by
77      // marking the ones seen that have been found.  Then ensure that all
78      // the elements of the second have been seen as well.
79      int firstSize = Iterables.size(first);
80      int secondSize = Iterables.size(second);
81      boolean[] usedSecondArray = new boolean[secondSize];
82      Iterator<T> firstIterator = first.iterator();
83      while (firstIterator.hasNext()) {
84        T firstValue = firstIterator.next();
85        boolean foundFirstValue = false;
86        Iterator<T> secondIterator = second.iterator();
87        for (int i = 0; i < usedSecondArray.length; ++i) {
88          T secondValue = secondIterator.next();
89          if (!usedSecondArray[i]) {
90            if (firstValue.equals(secondValue)) {
91              usedSecondArray[i] = true;
92              foundFirstValue = true;
93              break;
94            }
95          }
96        }
97  
98        if (!foundFirstValue) {
99          LOG.error("isEqual: Couldn't find element from first (" + firstValue +
100             ") in second " + second + "(size=" + secondSize + ")");
101         return false;
102       }
103     }
104 
105     Iterator<T> secondIterator = second.iterator();
106     for (int i = 0; i < usedSecondArray.length; ++i) {
107       T secondValue = secondIterator.next();
108       if (!usedSecondArray[i]) {
109         LOG.error("isEqual: Element " + secondValue + " (index " + i +
110             ") in second " + second + "(size=" + secondSize +
111             ") not found in " + first + " (size=" + firstSize + ")");
112         return false;
113       }
114     }
115 
116     return true;
117   }
118 }