@ -638,71 +638,6 @@ Status WinSequentialFile::InvalidateCache(size_t offset, size_t length) {
//////////////////////////////////////////////////////////////////////////////////////////////////
/// WinRandomAccessBase
// Helper
void CalculateReadParameters ( size_t alignment , uint64_t offset ,
size_t bytes_requested ,
size_t & actual_bytes_toread ,
uint64_t & first_page_start ) {
first_page_start = TruncateToPageBoundary ( alignment , offset ) ;
const uint64_t last_page_start =
TruncateToPageBoundary ( alignment , offset + bytes_requested - 1 ) ;
actual_bytes_toread = ( last_page_start - first_page_start ) + alignment ;
}
SSIZE_T WinRandomAccessImpl : : ReadIntoBuffer ( uint64_t user_offset ,
uint64_t first_page_start ,
size_t bytes_to_read , size_t & left ,
AlignedBuffer & buffer , char * dest ) const {
assert ( buffer . CurrentSize ( ) = = 0 ) ;
assert ( buffer . Capacity ( ) > = bytes_to_read ) ;
SSIZE_T read =
PositionedReadInternal ( buffer . Destination ( ) , bytes_to_read ,
first_page_start ) ;
if ( read > 0 ) {
buffer . Size ( read ) ;
// Let's figure out how much we read from the users standpoint
if ( ( first_page_start + buffer . CurrentSize ( ) ) > user_offset ) {
assert ( first_page_start < = user_offset ) ;
size_t buffer_offset = user_offset - first_page_start ;
read = buffer . Read ( dest , buffer_offset , left ) ;
} else {
read = 0 ;
}
left - = read ;
}
return read ;
}
SSIZE_T WinRandomAccessImpl : : ReadIntoOneShotBuffer ( uint64_t user_offset ,
uint64_t first_page_start ,
size_t bytes_to_read , size_t & left ,
char * dest ) const {
AlignedBuffer bigBuffer ;
bigBuffer . Alignment ( buffer_ . Alignment ( ) ) ;
bigBuffer . AllocateNewBuffer ( bytes_to_read ) ;
return ReadIntoBuffer ( user_offset , first_page_start , bytes_to_read , left ,
bigBuffer , dest ) ;
}
SSIZE_T WinRandomAccessImpl : : ReadIntoInstanceBuffer ( uint64_t user_offset ,
uint64_t first_page_start ,
size_t bytes_to_read , size_t & left ,
char * dest ) const {
SSIZE_T read = ReadIntoBuffer ( user_offset , first_page_start , bytes_to_read ,
left , buffer_ , dest ) ;
if ( read > 0 ) {
buffered_start_ = first_page_start ;
}
return read ;
}
SSIZE_T WinRandomAccessImpl : : PositionedReadInternal ( char * src ,
size_t numBytes ,
uint64_t offset ) const {
@ -714,17 +649,9 @@ WinRandomAccessImpl::WinRandomAccessImpl(WinFileData* file_base,
size_t alignment ,
const EnvOptions & options ) :
file_base_ ( file_base ) ,
read_ahead_ ( false ) ,
compaction_readahead_size_ ( options . compaction_readahead_size ) ,
random_access_max_buffer_size_ ( options . random_access_max_buffer_size ) ,
buffer_ ( ) ,
buffered_start_ ( 0 ) {
alignment_ ( alignment ) {
assert ( ! options . use_mmap_reads ) ;
// Do not allocate the buffer either until the first request or
// until there is a call to allocate a read-ahead buffer
buffer_ . Alignment ( alignment ) ;
}
inline
@ -732,94 +659,26 @@ Status WinRandomAccessImpl::ReadImpl(uint64_t offset, size_t n, Slice* result,
char * scratch ) const {
Status s ;
SSIZE_T r = - 1 ;
size_t left = n ;
char * dest = scratch ;
if ( n = = 0 ) {
* result = Slice ( scratch , 0 ) ;
return s ;
}
// When in direct I/O mode we need to do the following changes:
// - use our own aligned buffer
// - always read at the offset of that is a multiple of alignment
// Check buffer alignment
if ( file_base_ - > use_direct_io ( ) ) {
uint64_t first_page_start = 0 ;
size_t actual_bytes_toread = 0 ;
size_t bytes_requested = left ;
if ( ! read_ahead_ & & random_access_max_buffer_size_ = = 0 ) {
CalculateReadParameters ( buffer_ . Alignment ( ) , offset , bytes_requested ,
actual_bytes_toread ,
first_page_start ) ;
assert ( actual_bytes_toread > 0 ) ;
r = ReadIntoOneShotBuffer ( offset , first_page_start ,
actual_bytes_toread , left , dest ) ;
} else {
std : : unique_lock < std : : mutex > lock ( buffer_mut_ ) ;
// Let's see if at least some of the requested data is already
// in the buffer
if ( offset > = buffered_start_ & &
offset < ( buffered_start_ + buffer_ . CurrentSize ( ) ) ) {
size_t buffer_offset = offset - buffered_start_ ;
r = buffer_ . Read ( dest , buffer_offset , left ) ;
assert ( r > = 0 ) ;
left - = size_t ( r ) ;
offset + = r ;
dest + = r ;
if ( ! IsAligned ( alignment_ , scratch ) ) {
return Status : : InvalidArgument ( " WinRandomAccessImpl::ReadImpl: scratch is not properly aligned " ) ;
}
// Still some left or none was buffered
if ( left > 0 ) {
// Figure out the start/end offset for reading and amount to read
bytes_requested = left ;
if ( read_ahead_ & & bytes_requested < compaction_readahead_size_ ) {
bytes_requested = compaction_readahead_size_ ;
}
CalculateReadParameters ( buffer_ . Alignment ( ) , offset , bytes_requested ,
actual_bytes_toread ,
first_page_start ) ;
if ( n = = 0 ) {
* result = Slice ( scratch , 0 ) ;
return s ;
}
assert ( actual_bytes_toread > 0 ) ;
size_t left = n ;
char * dest = scratch ;
if ( buffer_ . Capacity ( ) < actual_bytes_toread ) {
// If we are in read-ahead mode or the requested size
// exceeds max buffer size then use one-shot
// big buffer otherwise reallocate main buffer
if ( read_ahead_ | |
( actual_bytes_toread > random_access_max_buffer_size_ ) ) {
// Unlock the mutex since we are not using instance buffer
lock . unlock ( ) ;
r = ReadIntoOneShotBuffer ( offset , first_page_start ,
actual_bytes_toread , left , dest ) ;
} else {
buffer_ . AllocateNewBuffer ( actual_bytes_toread ) ;
r = ReadIntoInstanceBuffer ( offset , first_page_start ,
actual_bytes_toread , left , dest ) ;
}
} else {
buffer_ . Clear ( ) ;
r = ReadIntoInstanceBuffer ( offset , first_page_start ,
actual_bytes_toread , left , dest ) ;
}
}
}
} else {
r = PositionedReadInternal ( scratch , left , offset ) ;
SSIZE_T r = PositionedReadInternal ( scratch , left , offset ) ;
if ( r > 0 ) {
left - = r ;
}
}
if ( r < 0 ) {
} else if ( r < 0 ) {
auto lastError = GetLastError ( ) ;
// Posix impl wants to treat reads from beyond
// of the file as OK.
@ -833,23 +692,6 @@ Status WinRandomAccessImpl::ReadImpl(uint64_t offset, size_t n, Slice* result,
return s ;
}
inline
void WinRandomAccessImpl : : HintImpl ( RandomAccessFile : : AccessPattern pattern ) {
if ( pattern = = RandomAccessFile : : SEQUENTIAL & & file_base_ - > use_direct_io ( ) & &
compaction_readahead_size_ > 0 ) {
std : : lock_guard < std : : mutex > lg ( buffer_mut_ ) ;
if ( ! read_ahead_ ) {
read_ahead_ = true ;
// This would allocate read-ahead size + 2 alignments
// - one for memory alignment which added implicitly by AlignedBuffer
// - We add one more alignment because we will read one alignment more
// from disk
buffer_ . AllocateNewBuffer ( compaction_readahead_size_ +
buffer_ . Alignment ( ) ) ;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/// WinRandomAccessFile
@ -867,18 +709,6 @@ Status WinRandomAccessFile::Read(uint64_t offset, size_t n, Slice* result,
return ReadImpl ( offset , n , result , scratch ) ;
}
void WinRandomAccessFile : : EnableReadAhead ( ) {
HintImpl ( SEQUENTIAL ) ;
}
bool WinRandomAccessFile : : ShouldForwardRawRequest ( ) const {
return true ;
}
void WinRandomAccessFile : : Hint ( AccessPattern pattern ) {
HintImpl ( pattern ) ;
}
Status WinRandomAccessFile : : InvalidateCache ( size_t offset , size_t length ) {
return Status : : OK ( ) ;
}
@ -1136,14 +966,6 @@ size_t WinRandomRWFile::GetRequiredBufferAlignment() const {
return GetAlignement ( ) ;
}
bool WinRandomRWFile : : ShouldForwardRawRequest ( ) const {
return true ;
}
void WinRandomRWFile : : EnableReadAhead ( ) {
HintImpl ( RandomAccessFile : : SEQUENTIAL ) ;
}
Status WinRandomRWFile : : Write ( uint64_t offset , const Slice & data ) {
return PositionedAppendImpl ( data , offset ) ;
}