package edu.berkeley.nlp.lm.map;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import edu.berkeley.nlp.lm.WordIndexer;
import edu.berkeley.nlp.lm.collections.Iterators;
import edu.berkeley.nlp.lm.util.Logger;
/**
* Wraps an NgramMap as a Java Map, with ngrams of all orders mixed together.
* This collection is read-only. It is also uses a lot inefficient boxing and
* unboxing.
*
* @author adampauls
*
* @param <W>
* @param <V>
*/
public class NgramMapWrapper<W, V> extends AbstractMap<List<W>, V>
{
private final NgramsForOrderMapWrapper<W, V>[] ngramsForOrder;
private final WordIndexer<W> wordIndexer;
private final NgramMap<V> ngramMap;
public NgramMapWrapper(final NgramMap<V> map, final WordIndexer<W> wordIndexer) {
this(map, wordIndexer, map.getMaxNgramOrder());
}
/**
*
* @param map
* @param wordIndexer
* @param maxOrder
* this is 1-based (i.e. 1 means keep unigrams but not bigrams)
*/
public NgramMapWrapper(final NgramMap<V> map, final WordIndexer<W> wordIndexer, final int maxOrder) {
@SuppressWarnings("unchecked")
final NgramsForOrderMapWrapper<W, V>[] maps = new NgramsForOrderMapWrapper[maxOrder];
ngramsForOrder = maps;
for (int ngramOrder = 0; ngramOrder < maxOrder; ++ngramOrder) {
ngramsForOrder[ngramOrder] = new NgramsForOrderMapWrapper<W, V>(map, wordIndexer, ngramOrder);
}
this.wordIndexer = wordIndexer;
this.ngramMap = map;
}
@Override
public V get(final Object arg0) {
if (!(arg0 instanceof List)) return null;
@SuppressWarnings("unchecked")
final List<W> l = (List<W>) arg0;
if (l.size() > ngramsForOrder.length) return null;
return ngramsForOrder[l.size() - 1].get(l);
}
@Override
public boolean containsKey(final Object key) {
return get(key) != null;
}
@Override
public Set<java.util.Map.Entry<List<W>, V>> entrySet() {
return new AbstractSet<java.util.Map.Entry<List<W>, V>>()
{
@Override
public Iterator<java.util.Map.Entry<List<W>, V>> iterator() {
final Iterators.Transform<NgramsForOrderMapWrapper<W, V>, Iterator<java.util.Map.Entry<List<W>, V>>> transform = new Iterators.Transform<NgramsForOrderMapWrapper<W, V>, Iterator<java.util.Map.Entry<List<W>, V>>>(
Arrays.asList(ngramsForOrder).iterator())
{
@Override
protected Iterator<java.util.Map.Entry<List<W>, V>> transform(final NgramsForOrderMapWrapper<W, V> next) {
return next.entrySet().iterator();
}
};
return new Iterators.IteratorIterator<Map.Entry<List<W>, V>>(transform);
}
@Override
public int size() {
if (longSize() > Integer.MAX_VALUE)
Logger.warn(NgramMapWrapper.class.getSimpleName() + " doesn't like maps with size greater than Integer.MAX_VALUE");
return (int) longSize();
}
};
}
/**
*
* @param ngramOrder
* 0-based (0 means unigrams)
* @return
*/
public Map<List<W>, V> getMapForOrder(final int ngramOrder) {
return ngramsForOrder[ngramOrder];
}
/**
* @return
*/
public long longSize() {
long size = 0;
for (final NgramsForOrderMapWrapper<W, V> map : ngramsForOrder) {
size += map.size();
}
return size;
}
public WordIndexer<W> getWordIndexer() {
return wordIndexer;
}
public NgramMap<V> getNgramMap() {
return ngramMap;
}
}