001: package org.apache.lucene.store.db;
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: import org.apache.lucene.store.IndexOutput;
022:
023: /**
024: * @author Andi Vajda
025: */
026:
027: public class DbIndexOutput extends IndexOutput {
028:
029: /**
030: * The size of data blocks, currently 16k (2^14), is determined by this
031: * constant.
032: */
033: static public final int BLOCK_SHIFT = 14;
034: static public final int BLOCK_LEN = 1 << BLOCK_SHIFT;
035: static public final int BLOCK_MASK = BLOCK_LEN - 1;
036:
037: protected long position = 0L, length = 0L;
038: protected DbDirectory directory;
039: protected Block block;
040: protected File file;
041:
042: protected DbIndexOutput(DbDirectory directory, String name,
043: boolean create) throws IOException {
044: super ();
045:
046: this .directory = directory;
047:
048: file = new File(directory, name, create);
049: block = new Block(file);
050: length = file.getLength();
051:
052: seek(length);
053: block.get(directory);
054:
055: directory.openFiles.add(this );
056: }
057:
058: public void close() throws IOException {
059: flush();
060: file.modify(directory, length, System.currentTimeMillis());
061:
062: directory.openFiles.remove(this );
063: }
064:
065: public void flush() throws IOException {
066: if (length > 0)
067: block.put(directory);
068: }
069:
070: public void writeByte(byte b) throws IOException {
071: int blockPos = (int) (position++ & BLOCK_MASK);
072:
073: block.getData()[blockPos] = b;
074:
075: if (blockPos + 1 == BLOCK_LEN) {
076: block.put(directory);
077: block.seek(position);
078: block.get(directory);
079: }
080:
081: if (position > length)
082: length = position;
083: }
084:
085: public void writeBytes(byte[] b, int offset, int len)
086: throws IOException {
087: int blockPos = (int) (position & BLOCK_MASK);
088:
089: while (blockPos + len >= BLOCK_LEN) {
090: int blockLen = BLOCK_LEN - blockPos;
091:
092: System.arraycopy(b, offset, block.getData(), blockPos,
093: blockLen);
094: block.put(directory);
095:
096: len -= blockLen;
097: offset += blockLen;
098: position += blockLen;
099:
100: block.seek(position);
101: block.get(directory);
102: blockPos = 0;
103: }
104:
105: if (len > 0) {
106: System.arraycopy(b, offset, block.getData(), blockPos, len);
107: position += len;
108: }
109:
110: if (position > length)
111: length = position;
112: }
113:
114: public long length() throws IOException {
115: return length;
116: }
117:
118: public void seek(long pos) throws IOException {
119: if (pos > length)
120: throw new IOException("seeking past end of file");
121:
122: if ((pos >>> BLOCK_SHIFT) == (position >>> BLOCK_SHIFT))
123: position = pos;
124: else {
125: block.put(directory);
126: block.seek(pos);
127: block.get(directory);
128: position = pos;
129: }
130: }
131:
132: public long getFilePointer() {
133: return position;
134: }
135: }
|