* BBufferIO did not implement Seek() and Position() correctly; it just passed
it to the stream. This caused Read()/Write() to need two syscalls for nothing (this only caused the actual stream to share the same position with the BBufferIO, something you just cannot rely on when using buffered I/O). * Anyway, this reduces the time VirtualBox needs to open some RAW test images from over 4 minutes to less than 15 seconds... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28662 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _BUFFER_IO_H
|
||||
@@ -40,7 +40,8 @@ class BBufferIO : public BPositionIO {
|
||||
char* fBuffer;
|
||||
size_t fBufferSize;
|
||||
size_t fBufferUsed;
|
||||
uint32 _reserved_ints[6];
|
||||
off_t fPosition;
|
||||
uint32 _reserved_ints[4];
|
||||
bool fBufferIsDirty;
|
||||
bool fOwnsStream;
|
||||
bool _reserved_bools[6];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2007, Haiku
|
||||
* Copyright (c) 2001-2008, Haiku
|
||||
* Distributed under the terms of the MIT license
|
||||
*
|
||||
* Authors:
|
||||
@@ -24,10 +24,8 @@ BBufferIO::BBufferIO(BPositionIO *stream, size_t bufferSize, bool ownsStream)
|
||||
fOwnsStream(ownsStream)
|
||||
|
||||
{
|
||||
if (bufferSize < 512)
|
||||
bufferSize = 512;
|
||||
|
||||
fBufferSize = bufferSize;
|
||||
fBufferSize = max_c(bufferSize, 512);
|
||||
fPosition = stream->Position();
|
||||
|
||||
// What can we do if this malloc fails ?
|
||||
// I think R5 uses new, but doesn't catch the thrown exception
|
||||
@@ -59,13 +57,12 @@ BBufferIO::ReadAt(off_t pos, void *buffer, size_t size)
|
||||
// stream on construction.
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
if (buffer == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// If the amount of data we want doesn't fit in the buffer, just
|
||||
// read it directly from the disk (and don't touch the buffer).
|
||||
if (size > fBufferSize) {
|
||||
if (size > fBufferSize || fBuffer == NULL) {
|
||||
if (fBufferIsDirty)
|
||||
Flush();
|
||||
return fStream->ReadAt(pos, buffer, size);
|
||||
@@ -100,12 +97,11 @@ BBufferIO::WriteAt(off_t pos, const void *buffer, size_t size)
|
||||
{
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
if (buffer == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// If data doesn't fit into the buffer, write it directly to the stream
|
||||
if (size > fBufferSize)
|
||||
if (size > fBufferSize || fBuffer == NULL)
|
||||
return fStream->WriteAt(pos, buffer, size);
|
||||
|
||||
// If we have cached data in the buffer, whose offset into the stream
|
||||
@@ -147,17 +143,40 @@ BBufferIO::Seek(off_t position, uint32 seekMode)
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fStream->Seek(position, seekMode);
|
||||
switch (seekMode) {
|
||||
case SEEK_CUR:
|
||||
fPosition += position;
|
||||
if (fPosition < 0)
|
||||
fPosition = 0;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
if (position < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
fPosition = position;
|
||||
break;
|
||||
case SEEK_END:
|
||||
{
|
||||
off_t size;
|
||||
status_t status = fStream->GetSize(&size);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
fPosition = size - position;
|
||||
if (fPosition < 0)
|
||||
fPosition = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fPosition;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
BBufferIO::Position() const
|
||||
{
|
||||
if (fStream == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fStream->Position();
|
||||
return fPosition;
|
||||
}
|
||||
|
||||
|
||||
@@ -208,9 +227,9 @@ BBufferIO::OwnsStream() const
|
||||
|
||||
|
||||
void
|
||||
BBufferIO::SetOwnsStream(bool owns_stream)
|
||||
BBufferIO::SetOwnsStream(bool ownsStream)
|
||||
{
|
||||
fOwnsStream = owns_stream;
|
||||
fOwnsStream = ownsStream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user