Added utility classes and methods

Project: http://git-wip-us.apache.org/repos/asf/incubator-hivemall/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-hivemall/commit/21a87814
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hivemall/tree/21a87814
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hivemall/diff/21a87814

Branch: refs/heads/master
Commit: 21a87814895c9c63479a049387dd53b34cc5c56e
Parents: 44528a8
Author: Makoto Yui <m...@apache.org>
Authored: Tue Sep 12 19:24:25 2017 +0900
Committer: Makoto Yui <m...@apache.org>
Committed: Tue Sep 12 19:24:25 2017 +0900

----------------------------------------------------------------------
 .../collections/maps/BoundedSortedMap.java      |  59 ++++++++++
 .../hivemall/utils/lang/NaturalComparator.java  |  48 ++++++++
 .../java/hivemall/utils/lang/StringUtils.java   |  17 +++
 .../main/java/hivemall/utils/struct/Pair.java   |  38 +++++++
 .../collections/BoundedPriorityQueueTest.java   | 114 +++++++++++++++++++
 .../collections/maps/BoundedSortedMapTest.java  |  84 ++++++++++++++
 6 files changed, 360 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hivemall/blob/21a87814/core/src/main/java/hivemall/utils/collections/maps/BoundedSortedMap.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/hivemall/utils/collections/maps/BoundedSortedMap.java 
b/core/src/main/java/hivemall/utils/collections/maps/BoundedSortedMap.java
new file mode 100644
index 0000000..b1bf806
--- /dev/null
+++ b/core/src/main/java/hivemall/utils/collections/maps/BoundedSortedMap.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package hivemall.utils.collections.maps;
+
+import hivemall.utils.lang.Preconditions;
+
+import java.util.Collections;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nullable;
+
+public final class BoundedSortedMap<K, V> extends TreeMap<K, V> {
+    private static final long serialVersionUID = 4580890152997313541L;
+
+    private final int bound;
+
+    public BoundedSortedMap(@Nonnegative int size) {
+        this(size, false);
+    }
+
+    public BoundedSortedMap(@Nonnegative int size, boolean reverseOrder) {
+        super(reverseOrder ? Collections.reverseOrder() : null);
+        Preconditions.checkArgument(size > 0, "size must be greater than zero: 
" + size);
+        this.bound = size;
+    }
+
+    @Nullable
+    public V put(@CheckForNull final K key, @Nullable final V value) {
+        final V old = super.put(key, value);
+        if (size() > bound) {
+            Entry<K, V> e = pollLastEntry();
+            if (e == null) {
+                return null;
+            }
+            return e.getValue();
+        }
+        return old;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hivemall/blob/21a87814/core/src/main/java/hivemall/utils/lang/NaturalComparator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/hivemall/utils/lang/NaturalComparator.java 
b/core/src/main/java/hivemall/utils/lang/NaturalComparator.java
new file mode 100644
index 0000000..d451f1b
--- /dev/null
+++ b/core/src/main/java/hivemall/utils/lang/NaturalComparator.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package hivemall.utils.lang;
+
+import java.util.Comparator;
+
+import javax.annotation.Nonnull;
+
+public final class NaturalComparator<T extends Comparable<? super T>> 
implements Comparator<T> {
+
+    @SuppressWarnings("rawtypes")
+    private final static NaturalComparator INSTANCE = new NaturalComparator();
+
+    private NaturalComparator() {}// avoid instantiation
+
+    @Override
+    public int compare(T o1, T o2) {
+        return o1.compareTo(o2);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Nonnull
+    public final static <T extends Comparable<? super T>> Comparator<T> 
getInstance() {
+        return (Comparator<T>) INSTANCE;
+    }
+
+    @Nonnull
+    public final static <T extends Comparable<? super T>> Comparator<T> 
newInstance() {
+        return new NaturalComparator<T>();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hivemall/blob/21a87814/core/src/main/java/hivemall/utils/lang/StringUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/hivemall/utils/lang/StringUtils.java 
b/core/src/main/java/hivemall/utils/lang/StringUtils.java
index 48e137f..5b66dd1 100644
--- a/core/src/main/java/hivemall/utils/lang/StringUtils.java
+++ b/core/src/main/java/hivemall/utils/lang/StringUtils.java
@@ -250,5 +250,22 @@ public final class StringUtils {
         return builder.toString();
     }
 
+    public static int compare(@Nullable final String o1, @Nullable final 
String o2) {
+        return compare(o1, o2, true);
+    }
+
+    public static int compare(@Nullable final String o1, @Nullable final 
String o2,
+            final boolean nullIsLess) {
+        if (o1 == o2) {
+            return 0;
+        }
+        if (o1 == null) {
+            return nullIsLess ? -1 : 1;
+        }
+        if (o2 == null) {
+            return nullIsLess ? 1 : -1;
+        }
+        return o1.compareTo(o2);
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-hivemall/blob/21a87814/core/src/main/java/hivemall/utils/struct/Pair.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/hivemall/utils/struct/Pair.java 
b/core/src/main/java/hivemall/utils/struct/Pair.java
new file mode 100644
index 0000000..17737ed
--- /dev/null
+++ b/core/src/main/java/hivemall/utils/struct/Pair.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package hivemall.utils.struct;
+
+import java.util.AbstractMap;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public class Pair<K, V> extends AbstractMap.SimpleEntry<K, V> {
+    private static final long serialVersionUID = 6411527075103472113L;
+
+    public Pair(@Nullable K key, @Nullable V value) {
+        super(key, value);
+    }
+
+    @Nonnull
+    public static <K, V> Pair<K, V> of(@Nullable K key, @Nullable V value) {
+        return new Pair<>(key, value);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hivemall/blob/21a87814/core/src/test/java/hivemall/utils/collections/BoundedPriorityQueueTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/hivemall/utils/collections/BoundedPriorityQueueTest.java 
b/core/src/test/java/hivemall/utils/collections/BoundedPriorityQueueTest.java
new file mode 100644
index 0000000..1220d76
--- /dev/null
+++ 
b/core/src/test/java/hivemall/utils/collections/BoundedPriorityQueueTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package hivemall.utils.collections;
+
+import hivemall.utils.lang.NaturalComparator;
+import hivemall.utils.lang.StringUtils;
+
+import java.util.Collections;
+import java.util.Comparator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BoundedPriorityQueueTest {
+
+    @Test
+    public void testTop3() {
+        BoundedPriorityQueue<Integer> queue = new 
BoundedPriorityQueue<Integer>(3,
+            new Comparator<Integer>() {
+                @Override
+                public int compare(Integer o1, Integer o2) {
+                    return Integer.compare(o1, o2);
+                }
+            });
+        Assert.assertTrue(queue.offer(1));
+        Assert.assertTrue(queue.offer(4));
+        Assert.assertTrue(queue.offer(3));
+        Assert.assertTrue(queue.offer(2));
+        Assert.assertFalse(queue.offer(1));
+        Assert.assertTrue(queue.offer(2));
+        Assert.assertTrue(queue.offer(3));
+
+        Assert.assertEquals(3, queue.size());
+
+        Assert.assertEquals(Integer.valueOf(3), queue.peek());
+        Assert.assertEquals(Integer.valueOf(3), queue.poll());
+        Assert.assertEquals(Integer.valueOf(3), queue.poll());
+        Assert.assertEquals(Integer.valueOf(4), queue.poll());
+        Assert.assertNull(queue.poll());
+        Assert.assertEquals(0, queue.size());
+    }
+
+    @Test
+    public void testTail3() {
+        BoundedPriorityQueue<Integer> queue = new 
BoundedPriorityQueue<Integer>(3,
+            Collections.<Integer>reverseOrder());
+        Assert.assertTrue(queue.offer(1));
+        Assert.assertTrue(queue.offer(4));
+        Assert.assertTrue(queue.offer(3));
+        Assert.assertTrue(queue.offer(2));
+        Assert.assertTrue(queue.offer(1));
+        Assert.assertTrue(queue.offer(2));
+        Assert.assertFalse(queue.offer(3));
+
+        Assert.assertEquals(3, queue.size());
+
+        Assert.assertEquals(Integer.valueOf(2), queue.peek());
+        Assert.assertEquals(Integer.valueOf(2), queue.poll());
+        Assert.assertEquals(Integer.valueOf(1), queue.poll());
+        Assert.assertEquals(Integer.valueOf(1), queue.poll());
+        Assert.assertNull(queue.poll());
+        Assert.assertEquals(0, queue.size());
+    }
+
+    @Test
+    public void testString1() {
+        BoundedPriorityQueue<String> queue = new BoundedPriorityQueue<>(3,
+            new Comparator<String>() {
+                @Override
+                public int compare(String o1, String o2) {
+                    return StringUtils.compare(o1, o2);
+                }
+            });
+        queue.offer("B");
+        queue.offer("A");
+        queue.offer("C");
+        queue.offer("D");
+        Assert.assertEquals("B", queue.poll());
+        Assert.assertEquals("C", queue.poll());
+        Assert.assertEquals("D", queue.poll());
+        Assert.assertNull(queue.poll());
+    }
+
+    @Test
+    public void testString2() {
+        BoundedPriorityQueue<String> queue = new BoundedPriorityQueue<>(3,
+            NaturalComparator.<String>getInstance());
+        queue.offer("B");
+        queue.offer("A");
+        queue.offer("C");
+        queue.offer("D");
+        Assert.assertEquals("B", queue.poll());
+        Assert.assertEquals("C", queue.poll());
+        Assert.assertEquals("D", queue.poll());
+        Assert.assertNull(queue.poll());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-hivemall/blob/21a87814/core/src/test/java/hivemall/utils/collections/maps/BoundedSortedMapTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/hivemall/utils/collections/maps/BoundedSortedMapTest.java 
b/core/src/test/java/hivemall/utils/collections/maps/BoundedSortedMapTest.java
new file mode 100644
index 0000000..ce376cf
--- /dev/null
+++ 
b/core/src/test/java/hivemall/utils/collections/maps/BoundedSortedMapTest.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package hivemall.utils.collections.maps;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.SortedMap;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BoundedSortedMapTest {
+
+    @Test
+    public void testNaturalOrderTop3() {
+        // natural order = ascending
+        SortedMap<Integer, Double> map = new BoundedSortedMap<Integer, 
Double>(3);
+        Assert.assertNull(map.put(1, 1.d));
+        Assert.assertEquals(Double.valueOf(1.d), map.put(1, 1.1d));
+        Assert.assertNull(map.put(4, 4.d));
+        Assert.assertNull(map.put(2, 2.d));
+        Assert.assertEquals(Double.valueOf(2.d), map.put(2, 2.2d));
+        Assert.assertEquals(Double.valueOf(4.d), map.put(3, 3.d));
+        Assert.assertEquals(Double.valueOf(3.d), map.put(3, 3.3d));
+
+        Assert.assertEquals(3, map.size());
+
+        Iterator<Entry<Integer, Double>> itor = map.entrySet().iterator();
+        Entry<Integer, Double> e = itor.next();
+        Assert.assertEquals(Integer.valueOf(1), e.getKey());
+        Assert.assertEquals(Double.valueOf(1.1d), e.getValue());
+        e = itor.next();
+        Assert.assertEquals(Integer.valueOf(2), e.getKey());
+        Assert.assertEquals(Double.valueOf(2.2d), e.getValue());
+        e = itor.next();
+        Assert.assertEquals(Integer.valueOf(3), e.getKey());
+        Assert.assertEquals(Double.valueOf(3.3d), e.getValue());
+        Assert.assertFalse(itor.hasNext());
+    }
+
+    @Test
+    public void testReverseOrderTop3() {
+        // reverse order = descending
+        SortedMap<Integer, Double> map = new BoundedSortedMap<Integer, 
Double>(3, true);
+        Assert.assertNull(map.put(1, 1.d));
+        Assert.assertEquals(Double.valueOf(1.d), map.put(1, 1.1d));
+        Assert.assertNull(map.put(4, 4.d));
+        Assert.assertNull(map.put(2, 2.d));
+        Assert.assertEquals(Double.valueOf(2.d), map.put(2, 2.2d));
+        Assert.assertEquals(Double.valueOf(1.1d), map.put(3, 3.d));
+        Assert.assertEquals(Double.valueOf(3.d), map.put(3, 3.3d));
+
+        Assert.assertEquals(3, map.size());
+
+        Iterator<Entry<Integer, Double>> itor = map.entrySet().iterator();
+        Entry<Integer, Double> e = itor.next();
+        Assert.assertEquals(Integer.valueOf(4), e.getKey());
+        Assert.assertEquals(Double.valueOf(4.d), e.getValue());
+        e = itor.next();
+        Assert.assertEquals(Integer.valueOf(3), e.getKey());
+        Assert.assertEquals(Double.valueOf(3.3d), e.getValue());
+        e = itor.next();
+        Assert.assertEquals(Integer.valueOf(2), e.getKey());
+        Assert.assertEquals(Double.valueOf(2.2d), e.getValue());
+        Assert.assertFalse(itor.hasNext());
+    }
+
+}

Reply via email to