
com.netflix.zeno.util.collections.heapfriendly.AbstractHeapFriendlyMap Maven / Gradle / Ivy
/*
*
* Copyright 2013 Netflix, Inc.
*
* 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.netflix.zeno.util.collections.heapfriendly;
import static com.netflix.zeno.util.collections.heapfriendly.HeapFriendlyMapArrayRecycler.INDIVIDUAL_OBJECT_ARRAY_SIZE;
import java.util.AbstractMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
/**
*
* The AbstractHeapFriendlyHashMap is an open-addressing, linear probing hash table. There are two implementations,
*
* HeapFriendlyHashMap - which uses two segmented arrays for keys and values
* HeapFriendlyDerivableKeyHashMap - which uses a single segmented array for values, and the keys are trivially derivable from the values.
*
* The segmented arrays are composed individual Object[] arrays which are each 4096 elements long.
*
* @see HeapFriendlyMapArrayRecycler
*
* @author dkoszewnik
*
*/
public abstract class AbstractHeapFriendlyMap extends AbstractMap {
@SuppressWarnings("unchecked")
protected Object segmentedGet(Object[][] segmentedArray, int bucket) {
int arrayIndex = bucket / INDIVIDUAL_OBJECT_ARRAY_SIZE;
int elementIndex = bucket % INDIVIDUAL_OBJECT_ARRAY_SIZE;
return (V) segmentedArray[arrayIndex][elementIndex];
}
protected void segmentedSet(Object[][] segmentedArray, int bucket, Object value) {
int arrayIndex = bucket / INDIVIDUAL_OBJECT_ARRAY_SIZE;
int elementIndex = bucket % INDIVIDUAL_OBJECT_ARRAY_SIZE;
segmentedArray[arrayIndex][elementIndex] = value;
}
public abstract void releaseObjectArrays();
protected void releaseObjectArrays(Object[][] segmentedArray) {
HeapFriendlyMapArrayRecycler recycler = HeapFriendlyMapArrayRecycler.get();
for(int i=0;i m) {
throw new UnsupportedOperationException("VMS error: HeapFriendlyMap cannot be added to with a specified key. Please use put(V value).");
}
@Override
public void clear() {
throw new UnsupportedOperationException("VMS error: Cannot clear a HeapFriendlyMap.");
}
protected class HeapFriendlyMapIterator implements Iterator {
protected final Object[][] segmentedArray;
protected final int numBuckets;
protected int current = -1;
protected HeapFriendlyMapIterator(Object[][] segmentedArray, int numBuckets) {
this.segmentedArray = segmentedArray;
this.numBuckets = numBuckets;
moveToNext();
}
public boolean hasNext() {
return current < numBuckets;
}
@SuppressWarnings("unchecked")
public T next() {
if(current >= numBuckets)
throw new NoSuchElementException();
T val = (T) segmentedGet(segmentedArray, current);
moveToNext();
return val;
}
protected void moveToNext() {
current++;
while(current < numBuckets && segmentedGet(segmentedArray, current) == null) {
current++;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException("VMS error: Cannot remove from a HeapFriendlyMapIterator");
}
}
protected static abstract class AbstractHeapFriendlyMapEntry implements Map.Entry {
@Override
public V setValue(V value) {
throw new UnsupportedOperationException("Cannot set value for HeapFriendlyMap Entry");
}
@Override
@SuppressWarnings("rawtypes")
public boolean equals(Object o) {
if(Entry.class.isAssignableFrom(o.getClass())) {
Entry other = (Entry)o;
return (getKey()==null ?
other.getKey()==null : getKey().equals(other.getKey())) &&
(getValue()==null ?
other.getValue()==null : getValue().equals(other.getValue()));
}
return false;
}
@Override
public int hashCode() {
return (getKey()==null ? 0 : getKey().hashCode()) ^
(getValue()==null ? 0 : getValue().hashCode());
}
public String toString() {
return getKey() + "=" + getValue();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy