The code works the Lucene Director way, so I don't know if it will fit your needs, but here it goes:
This is the bean , mapped to the db
Code:
public class LuceneFile implements Serializable {
private String name;
private long modified = System.currentTimeMillis();
private long length = 0;
private List buffers = new LinkedList();
public LuceneFile() {
}
public LuceneFile(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getModified() {
return modified;
}
public void setModified(long modified) {
this.modified = modified;
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
protected List getBuffers() {
return buffers;
}
protected void setBuffers(List buffers) {
this.buffers = buffers;
}
public void addBuffer(byte[] buffer) {
buffers.add(buffer);
}
public byte[] findBuffer(int index) {
return (byte[]) buffers.get(index);
}
Now, to implement a Lucene Directory I needed to implement org.apache.lucene.store.InputStream.readInternal to deal with reading the data parts:
Code:
public final void readInternal(byte[] dest, int destOffset, int len) {
int remainder = len;
int start = pointer;
while (remainder != 0) {
int bufferNumber = start / bufferSize;
int bufferOffset = start % bufferSize;
int bytesInBuffer = bufferSize - bufferOffset;
int bytesToCopy = bytesInBuffer >= remainder ? remainder : bytesInBuffer;
byte[] buffer = file.findBuffer(bufferNumber);
System.arraycopy(buffer, bufferOffset, dest, destOffset, bytesToCopy);
destOffset += bytesToCopy;
start += bytesToCopy;
remainder -= bytesToCopy;
}
pointer += len;
}
"pointer" is the current file pointer, "file" is the LuceneFile bean, and bufferSize is the data parts size.
The rest of the code to read a file is in org.apache.lucene.store.InputStream.
To deal with writes I needed to implement org.apache.lucene.store.OutputStream.flushBuffer
Code:
protected void flushBuffer(byte[] src, int len) {
int bufferNumber = pointer / bufferSize;
int bufferOffset = pointer % bufferSize;
int bytesInBuffer = bufferSize - bufferOffset;
int bytesToCopy = bytesInBuffer >= len ? len : bytesInBuffer;
if (bufferNumber == file.getBuffers().size()) {
file.addBuffer(new byte[bufferSize]);
}
byte[] buffer = file.findBuffer(bufferNumber);
System.arraycopy(src, 0, buffer, bufferOffset, bytesToCopy);
if (bytesToCopy < len) { // not all in one buffer
int srcOffset = bytesToCopy;
bytesToCopy = len - bytesToCopy; // remaining bytes
bufferNumber++;
if (bufferNumber == file.getBuffers().size()) {
file.addBuffer(new byte[bufferSize]);
}
buffer = file.findBuffer(bufferNumber);
System.arraycopy(src, srcOffset, buffer, 0, bytesToCopy);
}
pointer += len;
if (pointer > file.getLength())
file.setLength(pointer);
file.setModified(System.currentTimeMillis());
}
pointer, bufferSize and file are the same.
The rest of the code is in org.apache.lucene.store.OutputStream.
The code is an adaptation of the one in org.apache.lucene.store.RAMDirectory.