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; } }; }