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;
}
public Iterator valuesIterator() {
return x_valuesIterator();
}
public Iterator keysIterator() {
return x_keysIterator();
}
// ---- 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;
}
};
}