/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.db;

import java.util.*;

/**
 * Hash table based persistent implementation of the <tt>Map</tt> interface.<br>
 * This map allows only Integer objects instances as keys and {@link DbObject} as values.
 */
public final class DbIntKeyMap extends DbAbstractMap implements Map {

	DbIntKeyMap(final DbObject owner, final int[] image, final int fid) { //load from image during startup
		super(owner, fid);
		restoreFromImage(image);
	}

	DbIntKeyMap(final DbObject owner, final int fid) { // new object during runtime
		super(owner, fid);
	}

	void restoreFromImage(Object backupImage) {
		int[] image = backupImage == null ? DbConstants.ZERO_INT_ARRAY : (int[]) backupImage;
		final PainDB db = owner._getDB();
		final int len = image.length;
		nElements = len / 2;
		if (data == null || data.length < nElements || data.length > nElements * 2) {
			data = nElements == 0 ? ZERO_DATA : new AMapEntry[(int) (nElements / DEFAULT_LOAD_FACTOR)];
		}
		for (int i = 0; i < len; i += 2) {
			final int indexId = image[i + 1];
			new IntKeyMapEntry(image[i], indexId == -1 ? null : db.getObjectByIndexId(indexId));//key, value
		}
	}

	public Object createBackupImage() {
		if (nElements == 0) {
			return DbConstants.ZERO_INT_ARRAY;
		}
		final int imageLen = nElements * 2;
		final int[] image = new int[imageLen];
		int pos = 0;
		for (int i = 0; pos < imageLen; i++) {
			for (AMapEntry e = data[i]; e != null; e = e.next) {
				final DbObject obj = e.obj;
				image[pos] = ((IntKeyMapEntry) e).key;
				image[pos + 1] = obj.indexId;
				pos += 2;
			}
		}
		return image;
	}


// ---- DbAbstract Map impls ---- ///
	int a_getIndex(DbAbstractMap.UniversalKey key) {
		return _getIndex(key.intKey);
	}

	private int _getIndex(final int key) {
		return (key & 0x7FFFFFFF) % data.length;
	}


	Object a_get(Object key) {
		return get(key);
	}

	void a_addNewEntry(DbAbstractMap.UniversalKey key, DbObject value) {
		new IntKeyMapEntry(key.intKey, value);
	}

// --- map interface ------//

	public Object get(final Object key) {
		return get(((Integer) key).intValue());
	}

	public Object get(final int key) {
		ukey.intKey = key;
		return x_get(ukey);
	}


	public Object put(final Object key, final Object o) {
		return put(((Integer) key).intValue(), o);
	}

	public Object put(final int key, final Object o) {
		ukey.intKey = key;
		return x_put(ukey, o);
	}

	public Object remove(final Object key) {
		return remove(((Integer) key).intValue());
	}

	public Object remove(final int key) {
		ukey.intKey = key;
		return x_remove(ukey);
	}

	public int size() {
		return x_size();
	}

	public void clear() {
		x_clear();
	}

	public boolean isEmpty() {
		return x_isEmpty();
	}

	public boolean containsKey(Object key) {
		return containsKey(((Integer) key).intValue());
	}

	public boolean containsKey(int key) {
		ukey.intKey = key;
		return x_containsKey(ukey);
	}


	public boolean containsValue(Object value) {
		return x_containsValue(value);
	}

	public Collection values() {
		return x_values();
	}

	public void putAll(Map m) {
		x_putAll(m);
	}

	public Set entrySet() {
		return x_entrySet();
	}

	public Set keySet() {
		return x_keySet();
	}	

//----------------- inners -----------------------//

	final class IntKeyMapEntry extends AMapEntry {
		final int key;

		IntKeyMapEntry(final int key, final DbObject obj) {
			super(obj);
			this.key = key;
			linkToMap();
		}

		public Object getKey() {
			return new Integer(key);
		}

		int getIndex() {
			return _getIndex(key);
		}

		boolean hasSameKey(UniversalKey ukey) {
			return ukey.intKey == key;
		}
	};
}