/** * 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.hashtable; /** * Fixed size hashtable with Linear/Quad Hashing collision resolution. Not fully * functional - may fail when putting a new element. * * @author tomasz * */ public class QuadHash implements THashSet { private final int shiftAttempts = 100; private int hash_mask; private Long[] entries; private int failed; private int[] hops; private int c = 1; public QuadHash(int size, int c) { entries = new Long[size]; hash_mask = size - 1; hops = new int[50]; // c = 0 -> linear probing, c=1 -> quad probing this.c = c; } public Long get(Long id) { int hash1 = getHash(id.longValue()); int pos = hash1; int k = 1; while ((entries[pos] != null) && (!entries[pos].equals(id))) { pos = (hash1 + k + c * k * k) & (hash_mask); k++; if (k > shiftAttempts) { return null; } } return entries[pos]; } public Long put(Long id) { int hash1 = getHash(id.longValue()); int pos = hash1; int k = 1; while ((entries[pos] != null) && (!entries[pos].equals(id))) { pos = (hash1 + k + c * k * k) & (hash_mask); k++; if (k > shiftAttempts) { failed++; return null; } } if (k < hops.length) hops[k]++; entries[pos] = id; return id; } public int getFailed() { return failed; } public String toString() { String ret = "QuadHash: c=" + c + " : "; for (int i = 0; i < hops.length; i++) { ret += "h[" + i + "]=" + hops[i] + "] "; } return ret + "\n"; } public Long remove(Long id) { int hash1 = getHash(id.longValue()); int pos = hash1; int k = 1; while ((entries[pos] != null) && (!entries[pos].equals(id))) { pos = (hash1 + k + k * k) & (hash_mask); k++; if (k > shiftAttempts) { return null; } } Long temp = entries[pos]; entries[pos] = null; return temp; } private int getHash(long id) { return Hashes.getHash(id, 0) & hash_mask; } }