Search in sources :

Example 16 with FMFileManagerException

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());
        }
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) MappedByteBuffer(java.nio.MappedByteBuffer) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) MappedByteBuffer(java.nio.MappedByteBuffer)

Example 17 with FMFileManagerException

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));
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) MappedByteBuffer(java.nio.MappedByteBuffer) FileChannel(java.nio.channels.FileChannel) ByteBuffer(java.nio.ByteBuffer) MappedByteBuffer(java.nio.MappedByteBuffer)

Example 18 with FMFileManagerException

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);
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException)

Example 19 with FMFileManagerException

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));
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) MappedByteBuffer(java.nio.MappedByteBuffer) FileChannel(java.nio.channels.FileChannel) ByteBuffer(java.nio.ByteBuffer) MappedByteBuffer(java.nio.MappedByteBuffer)

Example 20 with FMFileManagerException

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());
        }
    }
}
Also used : FMFileManagerException(com.biglybt.core.diskmanager.file.FMFileManagerException) MappedByteBuffer(java.nio.MappedByteBuffer) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) MappedByteBuffer(java.nio.MappedByteBuffer)

Aggregations

FMFileManagerException (com.biglybt.core.diskmanager.file.FMFileManagerException)35 FMFile (com.biglybt.core.diskmanager.file.FMFile)14 TOTorrentFile (com.biglybt.core.torrent.TOTorrentFile)8 File (java.io.File)7 IOException (java.io.IOException)7 ByteBuffer (java.nio.ByteBuffer)6 MappedByteBuffer (java.nio.MappedByteBuffer)6 FileChannel (java.nio.channels.FileChannel)6 CacheFileManagerException (com.biglybt.core.diskmanager.cache.CacheFileManagerException)3 LogEvent (com.biglybt.core.logging.LogEvent)3 RandomAccessFile (java.io.RandomAccessFile)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 FMFileOwner (com.biglybt.core.diskmanager.file.FMFileOwner)1 TOTorrent (com.biglybt.core.torrent.TOTorrent)1 FileNotFoundException (java.io.FileNotFoundException)1