2022-02-26 22:51:22 +01:00
|
|
|
package it.cavallium.dbengine.lucene.directory;
|
|
|
|
|
2022-03-16 13:47:56 +01:00
|
|
|
import io.netty5.buffer.api.Buffer;
|
2022-02-26 22:51:22 +01:00
|
|
|
import org.apache.lucene.store.BufferedChecksum;
|
|
|
|
import org.apache.lucene.store.IndexOutput;
|
|
|
|
import org.apache.lucene.util.Accountable;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.zip.CRC32;
|
|
|
|
import java.util.zip.Checksum;
|
|
|
|
|
|
|
|
public class RocksdbOutputStream extends IndexOutput implements Accountable {
|
|
|
|
|
|
|
|
private final int bufferSize;
|
|
|
|
|
|
|
|
private long position;
|
|
|
|
|
2022-03-09 02:29:38 +01:00
|
|
|
private Buffer currentBuffer;
|
2022-02-26 22:51:22 +01:00
|
|
|
|
|
|
|
private boolean dirty;
|
|
|
|
|
|
|
|
private final Checksum crc;
|
|
|
|
|
|
|
|
private final RocksdbFileStore store;
|
|
|
|
|
|
|
|
private final String name;
|
|
|
|
|
|
|
|
public RocksdbOutputStream(String name, RocksdbFileStore store, int bufferSize, boolean checksum) {
|
|
|
|
super("RocksdbOutputStream(name=" + name + ")", name);
|
|
|
|
this.name = name;
|
|
|
|
this.store = store;
|
|
|
|
this.bufferSize = bufferSize;
|
2022-03-09 02:29:38 +01:00
|
|
|
this.currentBuffer = store.bufferAllocator.allocate(bufferSize);
|
2022-02-26 22:51:22 +01:00
|
|
|
this.position = 0;
|
|
|
|
this.dirty = false;
|
|
|
|
if (checksum) {
|
|
|
|
crc = new BufferedChecksum(new CRC32());
|
|
|
|
} else {
|
|
|
|
crc = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void close() throws IOException {
|
2022-02-28 03:20:24 +01:00
|
|
|
if (currentBuffer != null) {
|
|
|
|
if (dirty) {
|
|
|
|
flush();
|
|
|
|
}
|
2022-03-09 02:29:38 +01:00
|
|
|
currentBuffer.close();
|
2022-02-28 03:20:24 +01:00
|
|
|
currentBuffer = null;
|
2022-02-26 22:51:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void flush() throws IOException {
|
2022-03-09 02:29:38 +01:00
|
|
|
store.append(name, currentBuffer, 0, currentBuffer.writerOffset());
|
|
|
|
currentBuffer.writerOffset(0);
|
2022-02-26 22:51:22 +01:00
|
|
|
dirty = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public long getFilePointer() {
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public long getChecksum() {
|
|
|
|
if (crc != null) {
|
|
|
|
return crc.getValue();
|
|
|
|
} else {
|
|
|
|
throw new IllegalStateException("crc is null");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void writeByte(byte b) throws IOException {
|
|
|
|
|
|
|
|
|
|
|
|
if (crc != null) {
|
|
|
|
crc.update(b);
|
|
|
|
}
|
2022-03-09 02:29:38 +01:00
|
|
|
if (currentBuffer.writerOffset() == bufferSize) {
|
2022-02-26 22:51:22 +01:00
|
|
|
flush();
|
|
|
|
}
|
2022-02-28 03:20:24 +01:00
|
|
|
currentBuffer.writeByte(b);
|
2022-02-26 22:51:22 +01:00
|
|
|
position++;
|
|
|
|
dirty = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void writeBytes(byte[] b, int offset, int length) throws IOException {
|
|
|
|
|
|
|
|
if (crc != null) {
|
|
|
|
crc.update(b, offset, length);
|
|
|
|
}
|
|
|
|
int f = offset;
|
|
|
|
int n = length;
|
|
|
|
do {
|
2022-03-09 02:29:38 +01:00
|
|
|
if (currentBuffer.writerOffset() == bufferSize) {
|
2022-02-26 22:51:22 +01:00
|
|
|
flush();
|
|
|
|
}
|
2022-03-09 02:29:38 +01:00
|
|
|
int r = Math.min(bufferSize - currentBuffer.writerOffset(), n);
|
2022-02-28 03:20:24 +01:00
|
|
|
currentBuffer.writeBytes(b, f, r);
|
2022-02-26 22:51:22 +01:00
|
|
|
f += r;
|
|
|
|
position += r;
|
|
|
|
n -= r;
|
|
|
|
dirty = true;
|
|
|
|
|
|
|
|
|
|
|
|
} while (n != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public long ramBytesUsed() {
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<Accountable> getChildResources() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|