use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.
the class FMFileAccessLinear method read.
@Override
public void read(RandomAccessFile raf, DirectByteBuffer[] buffers, long offset) throws FMFileManagerException {
if (raf == null) {
throw new FMFileManagerException("read: raf is null");
}
FileChannel fc = raf.getChannel();
if (!fc.isOpen()) {
Debug.out("FileChannel is closed: " + owner.getName());
throw (new FMFileManagerException("read - file is closed"));
}
AEThread2.setDebug(owner);
int[] original_positions = new int[buffers.length];
long read_start = SystemTime.getHighPrecisionCounter();
try {
if (USE_MMAP) {
long size = 0;
for (int i = 0; i < buffers.length; i++) {
size += buffers[i].remaining(DirectByteBuffer.SS_FILE);
original_positions[i] = buffers[i].position(DirectByteBuffer.SS_FILE);
}
size = Math.min(size, fc.size() - offset);
MappedByteBuffer buf = fc.map(MapMode.READ_ONLY, offset, size);
for (DirectByteBuffer b : buffers) {
buf.limit(buf.position() + b.remaining(DirectByteBuffer.SS_FILE));
b.put(DirectByteBuffer.SS_FILE, buf);
}
} else {
fc.position(offset);
ByteBuffer[] bbs = new ByteBuffer[buffers.length];
ByteBuffer last_bb = null;
for (int i = 0; i < bbs.length; i++) {
ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
int pos = original_positions[i] = bb.position();
if (pos != bb.limit()) {
last_bb = bbs[i];
}
}
if (last_bb != null) {
int loop = 0;
if (Constants.isAndroid) {
int bbs_index = 0;
while (fc.position() < fc.size() && last_bb.hasRemaining()) {
ByteBuffer current_bb = bbs[bbs_index];
if (!current_bb.hasRemaining()) {
bbs_index++;
} else {
long read = fc.read(current_bb);
if (read > 0) {
loop = 0;
} else {
loop++;
if (loop == READ_RETRY_LIMIT) {
Debug.out("FMFile::read: zero length read - abandoning");
throw (new FMFileManagerException("read fails: retry limit exceeded"));
}
if (DEBUG_VERBOSE)
Debug.out("FMFile::read: zero length read - retrying");
try {
Thread.sleep(READ_RETRY_DELAY * loop);
} catch (InterruptedException e) {
throw (new FMFileManagerException("read fails: interrupted"));
}
}
}
}
} else {
while (fc.position() < fc.size() && last_bb.hasRemaining()) {
long read = fc.read(bbs);
if (read > 0) {
loop = 0;
} else {
loop++;
if (loop == READ_RETRY_LIMIT) {
Debug.out("FMFile::read: zero length read - abandoning");
throw (new FMFileManagerException("read fails: retry limit exceeded"));
}
if (DEBUG_VERBOSE)
Debug.out("FMFile::read: zero length read - retrying");
try {
Thread.sleep(READ_RETRY_DELAY * loop);
} catch (InterruptedException e) {
throw (new FMFileManagerException("read fails: interrupted"));
}
}
}
}
}
}
} catch (Throwable e) {
try {
Debug.out("Read failed: " + owner.getString() + ": raf open=" + raf.getChannel().isOpen() + ", len=" + raf.length() + ",off=" + offset);
} catch (IOException f) {
}
Debug.printStackTrace(e);
if (original_positions != null) {
try {
for (int i = 0; i < original_positions.length; i++) {
buffers[i].position(DirectByteBuffer.SS_FILE, original_positions[i]);
}
} catch (Throwable e2) {
Debug.out(e2);
}
}
throw (new FMFileManagerException("read fails", e));
} finally {
long elapsed_millis = (SystemTime.getHighPrecisionCounter() - read_start) / 1000000;
if (elapsed_millis > 10 * 1000) {
System.out.println("read took " + elapsed_millis + " for " + owner.getString());
}
}
}
use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.
the class FMFileAccessLinear method write.
@Override
public void write(RandomAccessFile raf, DirectByteBuffer[] buffers, long position) throws FMFileManagerException {
if (raf == null) {
throw (new FMFileManagerException("write fails: raf is null"));
}
FileChannel fc = raf.getChannel();
if (!fc.isOpen()) {
Debug.out("FileChannel is closed: " + owner.getName());
throw (new FMFileManagerException("read - file is closed"));
}
AEThread2.setDebug(owner);
int[] original_positions = new int[buffers.length];
try {
if (USE_MMAP) {
long size = 0;
for (int i = 0; i < buffers.length; i++) {
size += buffers[i].remaining(DirectByteBuffer.SS_FILE);
original_positions[i] = buffers[i].position(DirectByteBuffer.SS_FILE);
}
if (position + size > fc.size()) {
fc.position(position + size - 1);
fc.write(ByteBuffer.allocate(1));
fc.force(true);
}
MappedByteBuffer buf = fc.map(MapMode.READ_WRITE, position, size);
for (DirectByteBuffer b : buffers) buf.put(b.getBuffer(DirectByteBuffer.SS_FILE));
buf.force();
} else {
long expected_write = 0;
long actual_write = 0;
boolean partial_write = false;
if (DEBUG) {
for (int i = 0; i < buffers.length; i++) {
expected_write += buffers[i].limit(DirectByteBuffer.SS_FILE) - buffers[i].position(DirectByteBuffer.SS_FILE);
}
}
fc.position(position);
ByteBuffer[] bbs = new ByteBuffer[buffers.length];
ByteBuffer last_bb = null;
for (int i = 0; i < bbs.length; i++) {
ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
int pos = original_positions[i] = bb.position();
if (pos != bb.limit()) {
last_bb = bbs[i];
}
}
if (last_bb != null) {
int loop = 0;
while (last_bb.position() != last_bb.limit()) {
long written = fc.write(bbs);
actual_write += written;
if (written > 0) {
loop = 0;
if (DEBUG) {
if (last_bb.position() != last_bb.limit()) {
partial_write = true;
if (DEBUG_VERBOSE) {
Debug.out("FMFile::write: **** partial write **** this = " + written + ", total = " + actual_write + ", target = " + expected_write);
}
}
}
} else {
loop++;
if (loop == WRITE_RETRY_LIMIT) {
Debug.out("FMFile::write: zero length write - abandoning");
throw (new FMFileManagerException("write fails: retry limit exceeded"));
}
if (DEBUG_VERBOSE)
Debug.out("FMFile::write: zero length write - retrying");
try {
Thread.sleep(WRITE_RETRY_DELAY * loop);
} catch (InterruptedException e) {
throw (new FMFileManagerException("write fails: interrupted"));
}
}
}
}
if (DEBUG) {
if (expected_write != actual_write) {
Debug.out("FMFile::write: **** partial write **** failed: expected = " + expected_write + ", actual = " + actual_write);
throw (new FMFileManagerException("write fails: expected write/actual write mismatch"));
}
if (partial_write && DEBUG_VERBOSE)
Debug.out("FMFile::write: **** partial write **** completed ok");
}
}
} catch (Throwable e) {
if (original_positions != null) {
try {
for (int i = 0; i < original_positions.length; i++) {
buffers[i].position(DirectByteBuffer.SS_FILE, original_positions[i]);
}
} catch (Throwable e2) {
Debug.out(e2);
}
}
throw (new FMFileManagerException("write fails", e));
}
}
use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.
the class FMFileAccessPieceReorderer method setPieceComplete.
@Override
public void setPieceComplete(RandomAccessFile raf, int piece_number, DirectByteBuffer piece_data) throws FMFileManagerException {
if (num_pieces >= MIN_PIECES_REORDERABLE) {
// note that it is possible to reduce the number of piece moves at the expense
// of complicating the allocation process. We have the advantage here of having
// the piece data already in memory. We also don't want to defer a mass of IO
// until the download completes, hence interfering with other stuff such as
// streaming. So I'm going to stick with this approach.
piece_number = piece_number - first_piece_number;
if (TRACE) {
System.out.println("pieceComplete: " + piece_number);
}
if (piece_number >= next_piece_index) {
return;
}
int store_index = getPieceIndex(raf, piece_number, false);
if (store_index == -1) {
throw (new FMFileManagerException("piece marked as complete but not yet allocated"));
}
if (piece_number == store_index) {
if (TRACE) {
System.out.println(" already in right place");
}
return;
}
// find out what's currently stored in the place this piece should be
int swap_piece_number = piece_reverse_map[piece_number];
if (swap_piece_number < 1) {
throw (new FMFileManagerException("Inconsistent: failed to find piece to swap"));
}
if (TRACE) {
System.out.println(" swapping " + piece_number + " and " + swap_piece_number + ": " + piece_number + " <-> " + store_index);
}
DirectByteBuffer temp_buffer = DirectByteBufferPool.getBuffer(SS_FILE, piece_size);
DirectByteBuffer[] temp_buffers = new DirectByteBuffer[] { temp_buffer };
try {
long store_offset = first_piece_length + ((store_index - 1) * (long) piece_size);
long swap_offset = first_piece_length + ((piece_number - 1) * (long) piece_size);
delegate.read(raf, temp_buffers, swap_offset);
piece_data.position(SS_FILE, 0);
delegate.write(raf, new DirectByteBuffer[] { piece_data }, swap_offset);
temp_buffer.position(SS_FILE, 0);
delegate.write(raf, temp_buffers, store_offset);
piece_map[piece_number] = piece_number;
piece_reverse_map[piece_number] = piece_number;
piece_map[swap_piece_number] = store_index;
piece_reverse_map[store_index] = swap_piece_number;
setDirty();
if (piece_number == num_pieces - 1) {
long file_length = swap_offset + last_piece_length;
if (delegate.getLength(raf) > file_length) {
if (TRACE) {
System.out.println(" truncating file to correct length of " + file_length);
}
delegate.setLength(raf, file_length);
}
}
} finally {
temp_buffer.returnToPool();
}
} else {
delegate.setPieceComplete(raf, piece_number, piece_data);
}
}
use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.
the class FMFileAccessLinear method write.
@Override
public void write(FileAccessor fa, DirectByteBuffer[] buffers, long position) throws FMFileManagerException {
if (fa == null) {
throw (new FMFileManagerException("write fails: raf is null"));
}
FileChannel fc = fa.getChannel();
if (!fc.isOpen()) {
Debug.out("FileChannel is closed: " + owner.getName());
throw (new FMFileManagerException("read - file is closed"));
}
AEThread2.setDebug(owner);
int[] original_positions = new int[buffers.length];
try {
if (USE_MMAP) {
long size = 0;
for (int i = 0; i < buffers.length; i++) {
size += buffers[i].remaining(DirectByteBuffer.SS_FILE);
original_positions[i] = buffers[i].position(DirectByteBuffer.SS_FILE);
}
if (position + size > fc.size()) {
fc.position(position + size - 1);
fc.write(ByteBuffer.allocate(1));
fc.force(true);
}
MappedByteBuffer buf = fc.map(MapMode.READ_WRITE, position, size);
for (DirectByteBuffer b : buffers) buf.put(b.getBuffer(DirectByteBuffer.SS_FILE));
buf.force();
} else {
long expected_write = 0;
long actual_write = 0;
boolean partial_write = false;
if (DEBUG) {
for (int i = 0; i < buffers.length; i++) {
expected_write += buffers[i].limit(DirectByteBuffer.SS_FILE) - buffers[i].position(DirectByteBuffer.SS_FILE);
}
}
fc.position(position);
ByteBuffer[] bbs = new ByteBuffer[buffers.length];
ByteBuffer last_bb = null;
for (int i = 0; i < bbs.length; i++) {
ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
int pos = original_positions[i] = bb.position();
if (pos != bb.limit()) {
last_bb = bbs[i];
}
}
if (last_bb != null) {
int loop = 0;
while (last_bb.position() != last_bb.limit()) {
long written = fc.write(bbs);
actual_write += written;
if (written > 0) {
loop = 0;
if (DEBUG) {
if (last_bb.position() != last_bb.limit()) {
partial_write = true;
if (DEBUG_VERBOSE) {
Debug.out("FMFile::write: **** partial write **** this = " + written + ", total = " + actual_write + ", target = " + expected_write);
}
}
}
} else {
loop++;
if (loop == WRITE_RETRY_LIMIT) {
Debug.out("FMFile::write: zero length write - abandoning");
throw (new FMFileManagerException("write fails: retry limit exceeded"));
}
if (DEBUG_VERBOSE)
Debug.out("FMFile::write: zero length write - retrying");
try {
Thread.sleep(WRITE_RETRY_DELAY * loop);
} catch (InterruptedException e) {
throw (new FMFileManagerException("write fails: interrupted"));
}
}
}
}
if (DEBUG) {
if (expected_write != actual_write) {
Debug.out("FMFile::write: **** partial write **** failed: expected = " + expected_write + ", actual = " + actual_write);
throw (new FMFileManagerException("write fails: expected write/actual write mismatch"));
}
if (partial_write && DEBUG_VERBOSE)
Debug.out("FMFile::write: **** partial write **** completed ok");
}
}
} catch (Throwable e) {
if (original_positions != null) {
try {
for (int i = 0; i < original_positions.length; i++) {
buffers[i].position(DirectByteBuffer.SS_FILE, original_positions[i]);
}
} catch (Throwable e2) {
Debug.out(e2);
}
}
throw (new FMFileManagerException("write fails", e));
}
}
use of com.biglybt.core.diskmanager.file.FMFileManagerException in project BiglyBT by BiglySoftware.
the class FMFileAccessLinear method read.
@Override
public void read(FileAccessor fa, DirectByteBuffer[] buffers, long offset) throws FMFileManagerException {
if (fa == null) {
throw new FMFileManagerException("read: fa is null");
}
FileChannel fc = fa.getChannel();
if (!fc.isOpen()) {
Debug.out("FileChannel is closed: " + owner.getName());
throw (new FMFileManagerException("read - file is closed"));
}
AEThread2.setDebug(owner);
int[] original_positions = new int[buffers.length];
long read_start = SystemTime.getHighPrecisionCounter();
try {
if (USE_MMAP) {
long size = 0;
for (int i = 0; i < buffers.length; i++) {
size += buffers[i].remaining(DirectByteBuffer.SS_FILE);
original_positions[i] = buffers[i].position(DirectByteBuffer.SS_FILE);
}
size = Math.min(size, fc.size() - offset);
MappedByteBuffer buf = fc.map(MapMode.READ_ONLY, offset, size);
for (DirectByteBuffer b : buffers) {
buf.limit(buf.position() + b.remaining(DirectByteBuffer.SS_FILE));
b.put(DirectByteBuffer.SS_FILE, buf);
}
} else {
fc.position(offset);
ByteBuffer[] bbs = new ByteBuffer[buffers.length];
ByteBuffer last_bb = null;
for (int i = 0; i < bbs.length; i++) {
ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
int pos = original_positions[i] = bb.position();
if (pos != bb.limit()) {
last_bb = bbs[i];
}
}
if (last_bb != null) {
int loop = 0;
if (Constants.isAndroid) {
int bbs_index = 0;
while (fc.position() < fc.size() && last_bb.hasRemaining()) {
ByteBuffer current_bb = bbs[bbs_index];
if (!current_bb.hasRemaining()) {
bbs_index++;
} else {
long read = fc.read(current_bb);
if (read > 0) {
loop = 0;
} else {
loop++;
if (loop == READ_RETRY_LIMIT) {
Debug.out("FMFile::read: zero length read - abandoning");
throw (new FMFileManagerException("read fails: retry limit exceeded"));
}
if (DEBUG_VERBOSE)
Debug.out("FMFile::read: zero length read - retrying");
try {
Thread.sleep(READ_RETRY_DELAY * loop);
} catch (InterruptedException e) {
throw (new FMFileManagerException("read fails: interrupted"));
}
}
}
}
} else {
while (fc.position() < fc.size() && last_bb.hasRemaining()) {
long read = fc.read(bbs);
if (read > 0) {
loop = 0;
} else {
loop++;
if (loop == READ_RETRY_LIMIT) {
Debug.out("FMFile::read: zero length read - abandoning");
throw (new FMFileManagerException("read fails: retry limit exceeded"));
}
if (DEBUG_VERBOSE)
Debug.out("FMFile::read: zero length read - retrying");
try {
Thread.sleep(READ_RETRY_DELAY * loop);
} catch (InterruptedException e) {
throw (new FMFileManagerException("read fails: interrupted"));
}
}
}
}
}
}
} catch (Throwable e) {
try {
Debug.out("Read failed: " + owner.getString() + ": raf open=" + fa.getChannel().isOpen() + ", len=" + fa.getLength() + ",off=" + offset);
} catch (IOException f) {
}
Debug.printStackTrace(e);
if (original_positions != null) {
try {
for (int i = 0; i < original_positions.length; i++) {
buffers[i].position(DirectByteBuffer.SS_FILE, original_positions[i]);
}
} catch (Throwable e2) {
Debug.out(e2);
}
}
throw (new FMFileManagerException("read fails", e));
} finally {
long elapsed_millis = (SystemTime.getHighPrecisionCounter() - read_start) / 1000000;
if (elapsed_millis > 10 * 1000) {
System.out.println("read took " + elapsed_millis + " for " + owner.getString());
}
}
}
Aggregations