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.index;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.engine.Session;
011: import org.h2.store.DataPage;
012: import org.h2.store.Record;
013: import org.h2.util.ObjectArray;
014: import org.h2.value.Value;
015:
016: /**
017: * A index page of a linear hash index.
018: */
019: public class LinearHashBucket extends Record {
020: private LinearHashIndex index;
021: private int nextBucket;
022: private ObjectArray records;
023: private boolean writePos;
024:
025: public LinearHashBucket(LinearHashIndex index, DataPage s)
026: throws SQLException {
027: this .index = index;
028: writePos = s.readByte() == 'P';
029: nextBucket = s.readInt();
030: int len = s.readInt();
031: records = new ObjectArray();
032: for (int i = 0; i < len; i++) {
033: LinearHashEntry entry = new LinearHashEntry();
034: if (!writePos) {
035: Value key = s.readValue();
036: entry.key = key;
037: }
038: entry.hash = s.readInt();
039: entry.value = s.readInt();
040: entry.home = index.getPos(entry.hash);
041: records.add(entry);
042: }
043: }
044:
045: public LinearHashBucket(LinearHashIndex index) {
046: this .index = index;
047: this .records = new ObjectArray();
048: this .nextBucket = -1;
049: }
050:
051: private void update(Session session) throws SQLException {
052: index.updateBucket(session, this );
053: }
054:
055: void setNext(Session session, int nextBucket) throws SQLException {
056: this .nextBucket = nextBucket;
057: update(session);
058: }
059:
060: int getNextBucket() {
061: return nextBucket;
062: }
063:
064: LinearHashEntry getRecord(int i) {
065: return (LinearHashEntry) records.get(i);
066: }
067:
068: void addRecord(Session session, LinearHashEntry r)
069: throws SQLException {
070: records.add(r);
071: update(session);
072: }
073:
074: void removeRecord(Session session, int i) throws SQLException {
075: records.remove(i);
076: update(session);
077: }
078:
079: int getRecordSize() {
080: return records.size();
081: }
082:
083: public void write(DataPage buff) throws SQLException {
084: getRealByteCount(buff);
085: buff.writeByte((byte) 'B');
086: if (writePos) {
087: buff.writeByte((byte) 'P');
088: } else {
089: buff.writeByte((byte) 'D');
090: }
091: buff.writeInt(nextBucket);
092: buff.writeInt(records.size());
093: for (int i = 0; i < records.size(); i++) {
094: LinearHashEntry record = (LinearHashEntry) records.get(i);
095: // TODO index: just add the hash if the key is too large
096: if (!writePos) {
097: buff.writeValue(record.key);
098: }
099: buff.writeInt(record.hash);
100: buff.writeInt(record.value);
101: }
102: }
103:
104: public int getByteCount(DataPage dummy) throws SQLException {
105: return index.getBucketSize();
106: }
107:
108: public int getRealByteCount(DataPage dummy) throws SQLException {
109: int size = 2 + dummy.getIntLen() + dummy.getIntLen();
110: int dataSize = 0;
111: for (int i = 0; i < records.size(); i++) {
112: LinearHashEntry record = (LinearHashEntry) records.get(i);
113: // TODO index: just add the hash if the key is too large
114: dataSize += dummy.getValueLen(record.key);
115: size += 2 * dummy.getIntLen();
116: }
117: if (size + dataSize >= index.getBucketSize()) {
118: writePos = true;
119: return size;
120: } else {
121: writePos = false;
122: return size + dataSize;
123: }
124: }
125:
126: public boolean isEmpty() {
127: return false;
128: }
129:
130: }
|