/* Copyright (C) 2003 Univ. of Massachusetts Amherst, Computer Science Dept.
This file is part of "MALLET" (MAchine Learning for LanguagE Toolkit).
http://www.cs.umass.edu/~mccallum/mallet
This software is provided under the terms of the Common Public License,
version 1.0, as published by http://www.opensource.org. For further
information, see the file `LICENSE' included with this distribution. */
package cc.mallet.grmm.util;
import gnu.trove.TIntObjectHashMap;
import gnu.trove.TObjectProcedure;
import gnu.trove.TIntObjectIterator;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* Hash map that maps integer pairs to objects.
* This uses much less space than an 2d array, if the mapping is sparse.
*
* Created: Dec 14, 2005
*
* @author <A HREF="mailto:casutton@cs.umass.edu>casutton@cs.umass.edu</A>
* @version $Id: MIntInt2ObjectMap.java,v 1.1 2007/10/22 21:37:58 mccallum Exp $
*/
public class MIntInt2ObjectMap implements Serializable {
private TIntObjectHashMap backing = new TIntObjectHashMap ();
public MIntInt2ObjectMap () { }
public MIntInt2ObjectMap (int initialCapacity) {
backing = new TIntObjectHashMap (initialCapacity);
}
public Object put (int key1, int key2, Object value)
{
TIntObjectHashMap inner;
if (backing.containsKey (key1)) {
inner = (TIntObjectHashMap) backing.get (key1);
} else {
inner = new TIntObjectHashMap ();
backing.put (key1, inner);
}
return inner.put (key2, value);
}
public Object get (int key1, int key2)
{
TIntObjectHashMap inner = (TIntObjectHashMap) backing.get (key1);
if (inner == null) {
return null;
} else {
return inner.get (key2);
}
}
/** Returns an iterator over the set of (key2, value) pairs that match (key1). */
public TIntObjectIterator curry (int key1)
{
final TIntObjectHashMap inner = (TIntObjectHashMap) backing.get (key1);
if (inner == null) {
return new TIntObjectIterator (new TIntObjectHashMap ());
} else {
return new TIntObjectIterator (inner);
}
}
/** Returns an array of first-level keys. */
public int[] keys1 () {
return backing.keys ();
}
public int size ()
{
final int[] N = new int[]{0};
backing.forEachValue (new TObjectProcedure() {
public boolean execute (Object object)
{
TIntObjectHashMap inner = (TIntObjectHashMap) object;
N[0] += inner.size ();
return true;
}
});
return N[0];
}
public int[] keys2 (int key1)
{
TIntObjectHashMap inner = (TIntObjectHashMap) backing.get (key1);
return inner.keys ();
}
private static final long serialVersionUID = 1;
private static final int CURRENT_SERIAL_VERSION = 1;
private void writeObject (ObjectOutputStream out) throws IOException
{
out.writeInt (CURRENT_SERIAL_VERSION);
int[] keys1 = keys1 ();
out.writeInt (keys1.length);
for (int i = 0; i < keys1.length; i++) {
int k1 = keys1[i];
out.writeInt (k1);
int[] keys2 = keys2 (k1);
out.writeInt (keys2.length);
for (int j = 0; j < keys2.length; j++) {
int k2 = keys2[j];
out.writeInt (k2);
out.writeObject (get (k1, k2));
}
}
}
private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException
{
in.readInt (); // version =
int N1 = in.readInt ();
backing = new TIntObjectHashMap (N1);
for (int i = 0; i < N1; i++) {
int k1 = in.readInt ();
int N2 = in.readInt ();
for (int j = 0; j < N2; j++) {
int k2 = in.readInt ();
Object value = in.readObject ();
put (k1, k2, value);
}
}
}
}