/** * 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 org.apache.hadoop.hive.ql.exec.vector.expressions; import static org.junit.Assert.*; import java.util.Random; import org.junit.Test; public class TestCuckooSet { // maximum table size private static int MAX_SIZE = 65437; @Test public void testSetLong () { // Set of values to look for. Include the original blank value Long.MIN_VALUE to make sure // the process of choosing a new blank works. Long[] values = {1L, 2L, 3L, 1000L, 2000L, 3000L, 8L, 8L, 9L, 13L, 17L, 22L, 23L, 24L, 25L, -26L, 27L, 28L, 29L, 30L, 111111111111111L, -444444444444444L, Long.MIN_VALUE}; Long[] negatives = {0L, 4L, 4000L, -2L, 19L, 222222222222222L, -333333333333333L}; CuckooSetLong s = new CuckooSetLong(values.length); for(Long v : values) { s.insert(v); } // test that the values we added are there for(Long v : values) { assertTrue(s.lookup(v)); } // test that values that we know are missing are shown to be absent for (Long v : negatives) { assertFalse(s.lookup(v)); } // Set of values to look for. Long[] values2 = {1L, 2L, 3L, 1000L, 2000L, 3000L, 8L, 8L, 9L, 13L, 17L, 22L, 23L, 24L, 25L, -26L, 27L, 28L, 29L, 30L, 111111111111111L, -444444444444444L}; // Include the original blank value Long.MIN_VALUE in the negatives to make sure we get // the correct result that the blank value is not there. Long[] negatives2 = {0L, 4L, 4000L, -2L, 19L, 222222222222222L, -333333333333333L, Long.MIN_VALUE}; s = new CuckooSetLong(values2.length); for(Long v : values2) { s.insert(v); } // test that the values we added are there for(Long v : values2) { assertTrue(s.lookup(v)); } // test that values that we know are missing are shown to be absent for (Long v : negatives2) { assertFalse(s.lookup(v)); } } // load multiple random sets of Long values @Test public void testSetLongRandom() { long[] values; Random gen = new Random(98763537); for(int i = 0; i < 200;) { // Make a random array of longs int size = gen.nextInt() % MAX_SIZE; if (size <= 0) { // ensure size is >= 1, otherwise try again continue; } i++; values = new long[size]; loadRandom(values, gen); // load them into a SetLong CuckooSetLong s = new CuckooSetLong(size); loadSet(s, values); // look them up to make sure they are all there for (int j = 0; j != size; j++) { assertTrue(s.lookup(values[j])); } } } @Test public void testSetDouble() { // Set of values to look for. Double[] values = {7021.0D, 5780.0D, 0D, -1D, 1.999e50D}; Double[] negatives = {7000.0D, -2D, 1.9999e50D}; CuckooSetDouble s = new CuckooSetDouble(values.length); for(Double v : values) { s.insert(v); } // test that the values we added are there for(Double v : values) { assertTrue(s.lookup(v)); } // test that values that we know are missing are shown to be absent for (Double v : negatives) { assertFalse(s.lookup(v)); } } @Test public void testSetBytes() { String[] strings = {"foo", "bar", "baz", "a", "", "x1341", "Z"}; String[] negativeStrings = {"not", "in", "the", "set", "foobar"}; byte[][] values = getByteArrays(strings); byte[][] negatives = getByteArrays(negativeStrings); // load set CuckooSetBytes s = new CuckooSetBytes(strings.length); for(byte[] v : values) { s.insert(v); } // test that the values we added are there for(byte[] v : values) { assertTrue(s.lookup(v, 0, v.length)); } // test that values that we know are missing are shown to be absent for (byte[] v : negatives) { assertFalse(s.lookup(v, 0, v.length)); } // Test that we can search correctly using a buffer and pulling // a sequence of bytes out of the middle of it. In this case it // is the 3 letter sequence "foo". byte[] buf = getUTF8Bytes("thewordfooisinhere"); assertTrue(s.lookup(buf, 7, 3)); } @Test public void testSetBytesLargeRandom() { byte[][] values; Random gen = new Random(98763537); for(int i = 0; i < 200;) { // Make a random array of byte arrays int size = gen.nextInt() % MAX_SIZE; if (size <= 0) { // ensure size is >= 1, otherwise try again continue; } i++; values = new byte[size][]; loadRandomBytes(values, gen); // load them into a set CuckooSetBytes s = new CuckooSetBytes(size); loadSet(s, values); // look them up to make sure they are all there for (int j = 0; j != size; j++) { assertTrue(s.lookup(values[j], 0, values[j].length)); } } } public void loadRandomBytes(byte[][] values, Random gen) { for (int i = 0; i != values.length; i++) { values[i] = getUTF8Bytes(Integer.toString(gen.nextInt())); } } private byte[] getUTF8Bytes(String s) { byte[] v = null; try { v = s.getBytes("UTF-8"); } catch (Exception e) { ; // won't happen } return v; } // Get an array of UTF-8 byte arrays from an array of strings private byte[][] getByteArrays(String[] strings) { byte[][] values = new byte[strings.length][]; for(int i = 0; i != strings.length; i++) { try { values[i] = strings[i].getBytes("UTF-8"); } catch (Exception e) { ; // can't happen } } return values; } private void loadSet(CuckooSetLong s, long[] values) { for (Long v : values) { s.insert(v); } } private void loadSet(CuckooSetBytes s, byte[][] values) { for (byte[] v: values) { s.insert(v); } } private void loadRandom(long[] a, Random gen) { int size = a.length; for(int i = 0; i != size; i++) { a[i] = gen.nextLong(); } } }