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

com.ibm.commons.util.DoubleMap Maven / Gradle / Ivy

The newest version!
/*
 * © Copyright IBM Corp. 2010
 * 
 * Licensed 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 com.ibm.commons.util;


/**
 * Map that can efficiently be accessed by either the key or the value.
 * 

*

*/ public class DoubleMap { private int slotCount; private int size; // Hash map entries private MapEntry[] keyEntries; private MapEntry[] valueEntries; private static final class MapEntry { // List in the Hash table MapEntry keyPrevHash; MapEntry keyNextHash; MapEntry valuePrevHash; MapEntry valueNextHash; int keyHashCode; int valueHashCode; Object key; Object value; MapEntry(Object key, Object value) { this.key = key; this.value = value; this.keyHashCode = key.hashCode(); this.valueHashCode = value.hashCode(); } } public DoubleMap() { this(13); // See Aho for good values here... } public DoubleMap(int slotCount) { this.slotCount = slotCount; this.keyEntries = new MapEntry[slotCount]; this.valueEntries = new MapEntry[slotCount]; } public int size() { return size; } public void clear() { this.size = 0; this.keyEntries = new MapEntry[slotCount]; this.valueEntries = new MapEntry[slotCount]; } public void put(K key, V value) { MapEntry e = new MapEntry(key, value); put(e); } public void removeEntryByKey(K key) { MapEntry e = getEntryByKey(key); if (e != null) { removeEntry(e); } } public void removeEntryByValue(V value) { MapEntry e = getEntryByValue(value); if (e != null) { removeEntry(e); } } public V getNameByKey(K key) { MapEntry e = getEntryByKey(key); if (e != null) { return (V)e.value; } return null; } public K getIdByValue(V value) { MapEntry e = getEntryByValue(value); if (e != null) { return (K)e.key; } return null; } private final int getSlot(int hashCode) { return (hashCode & 0x7FFFFFFF) % slotCount; } private final MapEntry getEntryByKey(K key) { int hashCode = key.hashCode(); for (MapEntry e = keyEntries[getSlot(hashCode)]; e != null; e = e.keyNextHash) { if (e.keyHashCode == hashCode && e.key.equals(key)) { return e; } } return null; } private final MapEntry getEntryByValue(V value) { int hashCode = value.hashCode(); for (MapEntry e = valueEntries[getSlot(hashCode)]; e != null; e = e.valueNextHash) { if (e.valueHashCode == hashCode && e.value.equals(value)) { return e; } } return null; } private void put(MapEntry e) { // Insert the new entry in the ID HashTable int keySlot = getSlot(e.keyHashCode); e.keyNextHash = keyEntries[keySlot]; if (e.keyNextHash != null) { e.keyNextHash.keyPrevHash = e; } keyEntries[keySlot] = e; // Insert the new entry in the Name HashTable int valueSlot = getSlot(e.valueHashCode); e.valueNextHash = valueEntries[valueSlot]; if (e.valueNextHash != null) { e.valueNextHash.valuePrevHash = e; } valueEntries[valueSlot] = e; size++; } private final void removeEntry(MapEntry e) { // Remove the entry from the ID hashtable if (e.keyPrevHash != null) { e.keyPrevHash.keyNextHash = e.keyNextHash; } else { keyEntries[getSlot(e.keyHashCode)] = e.keyNextHash; } if (e.keyNextHash != null) { e.keyNextHash.keyPrevHash = e.keyPrevHash; } // Remove the entry from the Name hashtable if (e.valuePrevHash != null) { e.valuePrevHash.valueNextHash = e.valueNextHash; } else { valueEntries[getSlot(e.valueHashCode)] = e.valueNextHash; } if (e.valueNextHash != null) { e.valueNextHash.valuePrevHash = e.valuePrevHash; } // Decrease the map count size--; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy