001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.needle.coherence;
018:
019: import java.io.IOException;
020:
021: import org.apache.lucene.store.IndexInput;
022:
023: /**
024: * @author kimchy
025: */
026: class CoherenceIndexInput extends IndexInput {
027:
028: private CoherenceDirectory dir;
029:
030: private FileHeaderKey fileHeaderKey;
031:
032: private FileHeaderValue fileHeaderValue;
033:
034: private long position;
035:
036: private FileBucketKey fileBucketKey;
037:
038: private FileBucketValue fileBucketValue;
039:
040: private int currentBucketPosition;
041:
042: public CoherenceIndexInput(CoherenceDirectory dir,
043: FileHeaderKey fileHeaderKey, FileHeaderValue fileHeaderValue) {
044: this .dir = dir;
045: this .fileHeaderKey = fileHeaderKey;
046: this .fileHeaderValue = fileHeaderValue;
047: this .fileBucketKey = new FileBucketKey(fileHeaderKey
048: .getIndexName(), fileHeaderKey.getFileName(), -1);
049: }
050:
051: public void close() throws IOException {
052: }
053:
054: /**
055: * Returns the current position in this file, where the next read will
056: * occur.
057: *
058: * @see #seek(long)
059: */
060: public long getFilePointer() {
061: return this .position;
062: }
063:
064: /**
065: * The number of bytes in the file.
066: */
067: public long length() {
068: return fileHeaderValue.getSize();
069: }
070:
071: /**
072: * Reads and returns a single byte.
073: *
074: * @see org.apache.lucene.store.IndexOutput#writeByte(byte)
075: */
076: public byte readByte() throws IOException {
077: loadBucketIfNeeded();
078: position++;
079: return fileBucketValue.getData()[currentBucketPosition++];
080: }
081:
082: /**
083: * Reads a specified number of bytes into an array at the specified
084: * offset.
085: *
086: * @param b the array to read bytes into
087: * @param offset the offset in the array to start storing bytes
088: * @param len the number of bytes to read
089: * @see org.apache.lucene.store.IndexOutput#writeBytes(byte[],int)
090: */
091: public void readBytes(byte[] b, int offset, int len)
092: throws IOException {
093: loadBucketIfNeeded();
094: // if there is enough place to load at once
095: if (len <= (dir.getBucketSize() - currentBucketPosition)) {
096: if (len > 0) {
097: System.arraycopy(fileBucketValue.getData(),
098: currentBucketPosition, b, offset, len);
099: }
100: currentBucketPosition += len;
101: position += len;
102: return;
103: }
104:
105: // cycle through the reads
106: while (true) {
107: int available = dir.getBucketSize() - currentBucketPosition;
108: int sizeToRead = (len <= available) ? len : available;
109: System.arraycopy(fileBucketValue.getData(),
110: currentBucketPosition, b, offset, sizeToRead);
111: len -= sizeToRead;
112: offset += sizeToRead;
113: position += sizeToRead;
114: currentBucketPosition += sizeToRead;
115: // check if we read enough, if we did, bail
116: if (len <= 0) {
117: break;
118: }
119: loadBucketIfNeeded();
120: }
121: }
122:
123: /**
124: * Sets current position in this file, where the next read will occur.
125: *
126: * @see #getFilePointer()
127: */
128: public void seek(long pos) throws IOException {
129: position = pos;
130: }
131:
132: private void loadBucketIfNeeded() throws IOException {
133: currentBucketPosition = (int) position % dir.getBucketSize();
134: long bucketIndex = position / dir.getBucketSize();
135: // check if we need to load the bucket
136: if (bucketIndex == fileBucketKey.getBucketIndex()) {
137: return;
138: }
139: fileBucketKey = new FileBucketKey(fileHeaderKey.getIndexName(),
140: fileHeaderKey.getFileName(), bucketIndex);
141: try {
142: fileBucketValue = (FileBucketValue) dir.getCache().get(
143: fileBucketKey);
144: } catch (Exception e) {
145: throw new CoherenceDirectoryException(fileBucketKey
146: .getIndexName(), fileBucketKey.getFileName(),
147: "Failed to read bucket [" + bucketIndex + "]", e);
148: }
149: if (fileBucketValue == null) {
150: throw new CoherenceDirectoryException(fileBucketKey
151: .getIndexName(), fileBucketKey.getFileName(),
152: "Bucket [" + bucketIndex + "] not found");
153: }
154: }
155: }
|