001: package org.apache.lucene.store.je;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import java.io.IOException;
021:
022: import org.apache.lucene.store.IndexOutput;
023:
024: /**
025: * Port of Andi Vajda's DbDirectory to Java Edition of Berkeley Database
026: *
027: * @author Aaron Donovan
028: */
029:
030: public class JEIndexOutput extends IndexOutput {
031:
032: /**
033: * The size of data blocks, currently 16k (2^14), is determined by this
034: * constant.
035: */
036: static public final int BLOCK_SHIFT = 14;
037:
038: static public final int BLOCK_LEN = 1 << BLOCK_SHIFT;
039:
040: static public final int BLOCK_MASK = BLOCK_LEN - 1;
041:
042: protected long position = 0L, length = 0L;
043:
044: protected JEDirectory directory;
045:
046: protected Block block;
047:
048: protected File file;
049:
050: protected JEIndexOutput(JEDirectory directory, String name,
051: boolean create) throws IOException {
052: super ();
053:
054: this .directory = directory;
055:
056: file = new File(directory, name, create);
057: block = new Block(file);
058: length = file.getLength();
059:
060: seek(length);
061: block.get(directory);
062:
063: directory.openFiles.add(this );
064: }
065:
066: public void close() throws IOException {
067: flush();
068: file.modify(directory, length, System.currentTimeMillis());
069:
070: directory.openFiles.remove(this );
071: }
072:
073: public void flush() throws IOException {
074: if (length > 0)
075: block.put(directory);
076: }
077:
078: public void writeByte(byte b) throws IOException {
079: int blockPos = (int) (position++ & BLOCK_MASK);
080:
081: block.getData()[blockPos] = b;
082:
083: if (blockPos + 1 == BLOCK_LEN) {
084: block.put(directory);
085: block.seek(position);
086: block.get(directory);
087: }
088:
089: if (position > length)
090: length = position;
091: }
092:
093: public void writeBytes(byte[] b, int offset, int len)
094: throws IOException {
095: int blockPos = (int) (position & BLOCK_MASK);
096:
097: while (blockPos + len >= BLOCK_LEN) {
098: int blockLen = BLOCK_LEN - blockPos;
099:
100: System.arraycopy(b, offset, block.getData(), blockPos,
101: blockLen);
102: block.put(directory);
103:
104: len -= blockLen;
105: offset += blockLen;
106: position += blockLen;
107:
108: block.seek(position);
109: block.get(directory);
110: blockPos = 0;
111: }
112:
113: if (len > 0) {
114: System.arraycopy(b, offset, block.getData(), blockPos, len);
115: position += len;
116: }
117:
118: if (position > length)
119: length = position;
120: }
121:
122: public long length() throws IOException {
123: return length;
124: }
125:
126: public void seek(long pos) throws IOException {
127: if (pos > length)
128: throw new IOException("seeking past end of file");
129:
130: if ((pos >>> BLOCK_SHIFT) == (position >>> BLOCK_SHIFT))
131: position = pos;
132: else {
133: block.put(directory);
134: block.seek(pos);
135: block.get(directory);
136: position = pos;
137: }
138: }
139:
140: public long getFilePointer() {
141: return position;
142: }
143: }
|