001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.util;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.message.Message;
011: import org.h2.store.DataHandler;
012: import org.h2.value.Value;
013: import org.h2.value.ValueNull;
014:
015: /**
016: * This hash map supports keys of type Value and values of type Object.
017: */
018: public class ValueHashMap extends HashBase {
019:
020: private Value[] keys;
021: private Object[] values;
022: private DataHandler database;
023:
024: public ValueHashMap(DataHandler database) {
025: this .database = database;
026: }
027:
028: protected void reset(int newLevel) {
029: super .reset(newLevel);
030: keys = new Value[len];
031: values = new Object[len];
032: }
033:
034: protected void rehash(int newLevel) throws SQLException {
035: Value[] oldKeys = keys;
036: Object[] oldValues = values;
037: reset(newLevel);
038: for (int i = 0; i < oldKeys.length; i++) {
039: Value k = oldKeys[i];
040: if (k != null && k != ValueNull.DELETED) {
041: put(k, oldValues[i]);
042: }
043: }
044: }
045:
046: private int getIndex(Value key) {
047: return key.hashCode() & mask;
048: }
049:
050: public void put(Value key, Object value) throws SQLException {
051: checkSizePut();
052: int index = getIndex(key);
053: int plus = 1;
054: int deleted = -1;
055: do {
056: Value k = keys[index];
057: if (k == null) {
058: // found an empty record
059: if (deleted >= 0) {
060: index = deleted;
061: deletedCount--;
062: }
063: size++;
064: keys[index] = key;
065: values[index] = value;
066: return;
067: } else if (k == ValueNull.DELETED) {
068: // found a deleted record
069: if (deleted < 0) {
070: deleted = index;
071: }
072: } else if (database.compareTypeSave(k, key) == 0) {
073: // update existing
074: values[index] = value;
075: return;
076: }
077: index = (index + plus++) & mask;
078: } while (plus <= len);
079: // no space
080: throw Message.getInternalError("hashmap is full");
081: }
082:
083: public void remove(Value key) throws SQLException {
084: checkSizeRemove();
085: int index = getIndex(key);
086: int plus = 1;
087: do {
088: Value k = keys[index];
089: if (k == null) {
090: // found an empty record
091: return;
092: } else if (k == ValueNull.DELETED) {
093: // found a deleted record
094: } else if (database.compareTypeSave(k, key) == 0) {
095: // found the record
096: keys[index] = ValueNull.DELETED;
097: values[index] = null;
098: deletedCount++;
099: size--;
100: return;
101: }
102: index = (index + plus++) & mask;
103: k = keys[index];
104: } while (plus <= len);
105: // not found
106: }
107:
108: public Object get(Value key) throws SQLException {
109: int index = getIndex(key);
110: int plus = 1;
111: do {
112: Value k = keys[index];
113: if (k == null) {
114: // found an empty record
115: return null;
116: } else if (k == ValueNull.DELETED) {
117: // found a deleted record
118: } else if (database.compareTypeSave(k, key) == 0) {
119: // found it
120: return values[index];
121: }
122: index = (index + plus++) & mask;
123: } while (plus <= len);
124: return null;
125: }
126:
127: public ObjectArray keys() {
128: ObjectArray list = new ObjectArray(size);
129: for (int i = 0; i < keys.length; i++) {
130: Value k = keys[i];
131: if (k != null && k != ValueNull.DELETED) {
132: list.add(k);
133: }
134: }
135: return list;
136: }
137:
138: public ObjectArray values() {
139: ObjectArray list = new ObjectArray(size);
140: for (int i = 0; i < keys.length; i++) {
141: Value k = keys[i];
142: if (k != null && k != ValueNull.DELETED) {
143: list.add(values[i]);
144: }
145: }
146: return list;
147: }
148:
149: }
|