package org.limewire.collection;
import java.util.HashMap;
import java.util.Map;
/**
* Implements a fixed size {@link HashMap}. If <code>FixedsizeHashMap</code>
* gets full, no new entry can be inserted into it, except by removing an
* entry first. An attempt to add new entry throws a {@link NoMoreStorageException}.
*
<pre>
try{
FixedsizeHashMap<String, String> fhm = new FixedsizeHashMap<String, String>(3);
fhm.put("myKey1", "Abby");
fhm.put("myKey2", "Bob");
fhm.put("myKey3", "Chris");
System.out.println(fhm);
String ret;
ret = fhm.put("myKey3", "replace");
if(ret != null)
System.out.println("put returned: " + ret);
System.out.println(fhm);
fhm.put("myKey4", "Dan");
} catch (Exception e) {
System.out.println("Exception because of maximum size upon put myKey4 ... " + e.toString() );
}
Output:
{myKey2=Bob, myKey3=Chris, myKey1=Abby}
put returned: Chris
{myKey2=Bob, myKey3=replace, myKey1=Abby}
Exception because of maximum size upon put myKey4 ... org.limewire.collection.NoMoreStorageException
</pre>
*
*/
public class FixedsizeHashMap<K, V> {
/**
* The underlying storage
*/
private final Map<K, V> hashMap;
/**
* The max number of elements that can be stored
*/
private final int maxSize;
/**
* Create a new hashMap that stores only the specified number of entries.
*
* @param size the number of entries to hold
* @exception IllegalArgumentException if size is less < 1.
*/
public FixedsizeHashMap(int size)
{
hashMap = new HashMap<K, V>(size * 4/3);
this.maxSize = size;
}
/**
* Maps the given key to the given value. If adding the key
* would make this contain more elements than the size given at
* construction, the passed entry is not stored and NoMoreStorageException
* gets thrown.
* @exception NoMoreStorageException when no more space left in the storage
* ideally, before calling put method, it should be checked whether the map is
* already full or not
*/
public synchronized V put(K key, V value) throws NoMoreStorageException
{
V retValue = null;
//check if the count is less than size, in that case no problem
//inserting this new entry
if(hashMap.size() < maxSize)
retValue = hashMap.put(key,value);
else {
//if the entry already existed, we can safely add this new pair
//without affecting the size
retValue = hashMap.get(key);
if(retValue != null) //mapping existed, so update the mapping
retValue = hashMap.put(key,value);
else //no space to enter anything more
throw new NoMoreStorageException();
}
return retValue;
}
/**
* Returns the value mapped to the given key.
* @param key the given key
* @return the value given key maps to
*/
public synchronized V get(K key) {
return hashMap.get(key);
}
/**
* Clears all entries from the map.
*/
public synchronized void clear() {
hashMap.clear();
}
/**
* @return the string representation of the mappings
*/
@Override
public synchronized String toString() {
return hashMap.toString();
}
}