All Downloads are FREE. Search and download functionalities are using the official Maven repository.

opennlp.model.IndexHashTable Maven / Gradle / Ivy

The newest version!
/*
 * 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 opennlp.model;

/**
 * The {@link IndexHashTable} is a hash table which maps entries
 * of an array to their index in the array. All entries in the array must
 * be unique otherwise a well-defined mapping is not possible.
 * 

* The entry objects must implement {@link Object#equals(Object)} and * {@link Object#hashCode()} otherwise the behavior of this class is * undefined. *

* The implementation uses a hash table with open addressing and linear probing. *

* The table is thread safe and can concurrently accessed by multiple threads, * thread safety is achieved through immutability. Though its not strictly immutable * which means, that the table must still be safely published to other threads. */ public class IndexHashTable { private final Object keys[]; private final int values[]; private final int size; /** * Initializes the current instance. The specified array is copied into the * table and later changes to the array do not affect this table in any way. * * @param mapping * the values to be indexed, all values must be unique otherwise a * well-defined mapping of an entry to an index is not possible * @param loadfactor * the load factor, usually 0.7 * * @throws IllegalArgumentException * if the entries are not unique */ public IndexHashTable(T mapping[], double loadfactor) { if (loadfactor <= 0 || loadfactor > 1) { throw new IllegalArgumentException("loadfactor must be larger than 0 " + "and equal to or smaller than 1 but is " + loadfactor + "!"); } int arraySize = (int) (mapping.length / loadfactor) + 1; keys = new Object[arraySize]; values = new int[arraySize]; size = mapping.length; for (int i = 0; i < mapping.length; i++) { int startIndex = indexForHash(mapping[i].hashCode(), keys.length); int index = searchKey(startIndex, null, true); if (index == -1) throw new IllegalArgumentException( "Array must contain only unique keys!"); keys[index] = mapping[i]; values[index] = i; } } private static int indexForHash(int h, int length) { return (h & 0x7fffffff) % length; } private int searchKey(int startIndex, Object key, boolean insert) { for (int index = startIndex; true; index = (index + 1) % keys.length) { // The keys array contains at least one null element, which guarantees // termination of the loop if (keys[index] == null) { if (insert) return index; else return -1; } if (keys[index].equals(key)) { if (!insert) return index; else return -1; } } } /** * Retrieves the index for the specified key. * * @param key * @return the index or -1 if there is no entry to the keys */ public int get(T key) { int startIndex = indexForHash(key.hashCode(), keys.length); int index = searchKey(startIndex, key, false); if (index != -1) { return values[index]; } else { return -1; } } /** * Retrieves the size. * * @return the number of elements in this map. */ public int size() { return size; } @SuppressWarnings("unchecked") public T[] toArray(T array[]) { for (int i = 0; i < keys.length; i++) { if (keys[i] != null) array[values[i]] = (T) keys[i]; } return array; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy