001: /*
002: Copyright (c) 2006, Matthew Estes
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright
009: notice, this list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright
011: notice, this list of conditions and the following disclaimer in the
012: documentation and/or other materials provided with the distribution.
013: * Neither the name of Metanotion Software nor the names of its
014: contributors may be used to endorse or promote products derived from this
015: software without specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018: IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
019: THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
020: PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029: package net.metanotion.io.block.index;
030:
031: import java.io.IOException;
032:
033: import net.metanotion.io.RandomAccessInterface;
034: import net.metanotion.io.block.BlockFile;
035: import net.metanotion.util.skiplist.SkipList;
036: import net.metanotion.util.skiplist.SkipLevels;
037: import net.metanotion.util.skiplist.SkipSpan;
038:
039: public class BSkipLevels extends SkipLevels {
040: public int levelPage;
041: public int spanPage;
042: public BlockFile bf;
043:
044: protected BSkipLevels() {
045: }
046:
047: public BSkipLevels(BlockFile bf, int levelPage, BSkipList bsl)
048: throws IOException {
049: this .levelPage = levelPage;
050: this .bf = bf;
051:
052: BlockFile.pageSeek(bf.file, levelPage);
053:
054: bsl.levelHash.put(new Integer(this .levelPage), this );
055:
056: int maxLen = bf.file.readShort();
057: int nonNull = bf.file.readShort();
058: spanPage = bf.file.readInt();
059: bottom = (BSkipSpan) bsl.spanHash.get(new Integer(spanPage));
060:
061: this .levels = new BSkipLevels[maxLen];
062: int lp;
063: for (int i = 0; i < nonNull; i++) {
064: lp = bf.file.readInt();
065: if (lp != 0) {
066: levels[i] = (BSkipLevels) bsl.levelHash
067: .get(new Integer(lp));
068: if (levels[i] == null) {
069: levels[i] = new BSkipLevels(bf, lp, bsl);
070: bsl.levelHash.put(new Integer(lp), levels[i]);
071: }
072: } else {
073: levels[i] = null;
074: }
075: }
076:
077: }
078:
079: public static void init(BlockFile bf, int page, int spanPage,
080: int maxHeight) throws IOException {
081: BlockFile.pageSeek(bf.file, page);
082: bf.file.writeShort((short) maxHeight);
083: bf.file.writeShort(0);
084: bf.file.writeInt(spanPage);
085: }
086:
087: public void flush() {
088: try {
089: BlockFile.pageSeek(bf.file, levelPage);
090: bf.file.writeShort((short) levels.length);
091: int i = 0;
092: for (i = 0; i < levels.length; i++) {
093: if (levels[i] == null) {
094: break;
095: }
096: }
097: bf.file.writeShort(i);
098: bf.file.writeInt(((BSkipSpan) bottom).page);
099: for (i = 0; i < levels.length; i++) {
100: if (levels[i] == null) {
101: break;
102: }
103: bf.file.writeInt(((BSkipLevels) levels[i]).levelPage);
104: }
105: } catch (IOException ioe) {
106: throw new Error();
107: }
108: }
109:
110: public void killInstance() {
111: try {
112: bf.freePage(levelPage);
113: } catch (IOException ioe) {
114: throw new Error();
115: }
116: }
117:
118: public SkipLevels newInstance(int levels, SkipSpan ss, SkipList sl) {
119: try {
120: BSkipSpan bss = (BSkipSpan) ss;
121: BSkipList bsl = (BSkipList) sl;
122: int page = bf.allocPage();
123: BSkipLevels.init(bf, page, bss.page, levels);
124: return new BSkipLevels(bf, page, bsl);
125: } catch (IOException ioe) {
126: throw new Error();
127: }
128: }
129: }
|