/** * 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; import java.util.HashMap; import java.util.Random; import junit.framework.TestCase; import org.apache.hadoop.hive.ql.exec.persistence.HashMapWrapper; import org.apache.hadoop.hive.ql.metadata.HiveException; /** * TestHashMapWrapper. * */ public class TestHashMapWrapper extends TestCase { public void testHashMapWrapper() throws Exception { HashMap<String, String> mem_map = new HashMap<String, String>(); mem_map.put("k1", "v1"); mem_map.put("k2", "v2"); mem_map.put("k3", "v3"); mem_map.put("k4", "v4"); try { // NO cache HashMapWrapper<String, String> wrapper = new HashMapWrapper<String, String>(0); insertAll(wrapper, mem_map); checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files // cache size = 1 wrapper = new HashMapWrapper<String, String>(1); insertAll(wrapper, mem_map); checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files // cache size = 2 wrapper = new HashMapWrapper<String, String>(2); insertAll(wrapper, mem_map); checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files // cache size = 4 wrapper = new HashMapWrapper<String, String>(4); insertAll(wrapper, mem_map); checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files // default cache size (25000) wrapper = new HashMapWrapper<String, String>(); insertAll(wrapper, mem_map); checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files // check mixed put/remove/get functions wrapper = new HashMapWrapper<String, String>(2); insertAll(wrapper, mem_map); wrapper.remove("k3"); // k3 is in HTree mem_map.remove("k3"); assertTrue(mem_map.size() == 3); checkAll(wrapper, mem_map); wrapper.remove("k1"); mem_map.remove("k1"); checkAll(wrapper, mem_map); String v4 = wrapper.get("k4"); assertTrue(v4 != null); assert (v4.equals("v4")); wrapper.remove("k4"); mem_map.remove("k4"); checkAll(wrapper, mem_map); wrapper.put("k5", "v5"); mem_map.put("k5", "v5"); checkAll(wrapper, mem_map); wrapper.put("k6", "v6"); mem_map.put("k6", "v6"); checkAll(wrapper, mem_map); wrapper.put("k6", "v61"); mem_map.put("k6", "v61"); checkAll(wrapper, mem_map); wrapper.remove("k6"); mem_map.remove("k6"); checkAll(wrapper, mem_map); // get k1, k2 to main memory wrapper.get("k1"); wrapper.get("k2"); // delete k1 so that cache is half empty wrapper.remove("k1"); mem_map.remove("k1"); // put new pair (k6, v7) so that it will be in persistent hash wrapper.put("k6", "v7"); mem_map.put("k6", "v7"); checkAll(wrapper, mem_map); // test clear wrapper.clear(); mem_map.clear(); checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files // insert 3,000 pairs random testing wrapper = new HashMapWrapper<String, String>(1000); for (int i = 0; i < 3000; ++i) { String k = "k" + i; String v = "v" + i; wrapper.put(k, v); mem_map.put(k, v); } checkAll(wrapper, mem_map); System.out.println("Finished inserting 3000 pairs."); // do 10,000 random get/remove operations Random rand = new Random(12345678); for (int i = 0; i < 10000; ++i) { int j = rand.nextInt(3000); String k = "k" + j; String v; int command = rand.nextInt(3); switch (command) { case 0: // remove // System.out.println("removing " + k);// uncomment this for debugging wrapper.remove(k); mem_map.remove(k); break; case 1: // get // System.out.println("getting " + k);// uncomment this for debugging v = wrapper.get(k); String v2 = mem_map.get(k); assertTrue( "one of them doesn't exists or different values from two hash tables", v == null && v2 == null || v.equals(v2)); break; case 2: // put v = "v" + rand.nextInt(3000); // System.out.println("putting (" + k + ", " + v);// uncomment this // for debugging wrapper.put(k, v); mem_map.put(k, v); break; } // checkAll(wrapper, mem_map); // uncomment this for debugging } checkAll(wrapper, mem_map); wrapper.close(); // clean up temporary files } catch (Exception e) { e.printStackTrace(); System.out.println(e.toString()); assertTrue("Exception should not be thrown.", false); } System.out.println("TestHashMapWrapper successful"); } private void insertAll(HashMapWrapper<String, String> hashTable, HashMap<String, String> map) throws HiveException { for (String k : map.keySet()) { String v = map.get(k); hashTable.put(k, v); } } private void checkAll(HashMapWrapper<String, String> hashTable, HashMap<String, String> map) throws HiveException { // check each item in the HashMapWrapper was actually inserted for (String k : hashTable.keySet()) { String map_val = hashTable.get(k); String val = map.get(k); assertTrue( "some HashMapWrapper value is not in main memory HashMap: map_val = " + map_val + "; val = " + val, map_val != null && val != null); assertTrue( "value in HashMapWrapper is not the same as MM HashMap: map_val = " + map_val + "; val = " + val, val.equals(map_val)); } // check all inserted elements are in HashMapWrapper for (String k : map.keySet()) { String map_val = hashTable.get(k); String val = map.get(k); assertTrue("Some MM HashMap key is not in HashMapWrapper: map_val = " + map_val + "; val = " + val, map_val != null && val != null); assertTrue("Value in MM HashMap is not in HashMapWrapper: map_val = " + map_val + "; val = " + val, val.equals(map_val)); } } }