@ -21,6 +21,7 @@
# include "util/file_reader_writer.h"
# include "util/perf_context_imp.h"
# include "util/stop_watch.h"
# include "util/sync_point.h"
namespace rocksdb {
@ -38,6 +39,11 @@ static void UnrefEntry(void* arg1, void* arg2) {
cache - > Release ( h ) ;
}
static void DeleteTableReader ( void * arg1 , void * arg2 ) {
TableReader * table_reader = reinterpret_cast < TableReader * > ( arg1 ) ;
delete table_reader ;
}
static Slice GetSliceForFileNumber ( const uint64_t * file_number ) {
return Slice ( reinterpret_cast < const char * > ( file_number ) ,
sizeof ( * file_number ) ) ;
@ -76,6 +82,33 @@ void TableCache::ReleaseHandle(Cache::Handle* handle) {
cache_ - > Release ( handle ) ;
}
Status TableCache : : GetTableReader (
const EnvOptions & env_options ,
const InternalKeyComparator & internal_comparator , const FileDescriptor & fd ,
bool advise_random_on_open , bool record_read_stats ,
HistogramImpl * file_read_hist , unique_ptr < TableReader > * table_reader ) {
std : : string fname =
TableFileName ( ioptions_ . db_paths , fd . GetNumber ( ) , fd . GetPathId ( ) ) ;
unique_ptr < RandomAccessFile > file ;
Status s = ioptions_ . env - > NewRandomAccessFile ( fname , & file , env_options ) ;
RecordTick ( ioptions_ . statistics , NO_FILE_OPENS ) ;
if ( s . ok ( ) ) {
if ( advise_random_on_open ) {
file - > Hint ( RandomAccessFile : : RANDOM ) ;
}
StopWatch sw ( ioptions_ . env , ioptions_ . statistics , TABLE_OPEN_IO_MICROS ) ;
std : : unique_ptr < RandomAccessFileReader > file_reader (
new RandomAccessFileReader ( std : : move ( file ) , ioptions_ . env ,
ioptions_ . statistics , record_read_stats ,
file_read_hist ) ) ;
s = ioptions_ . table_factory - > NewTableReader (
ioptions_ , env_options , internal_comparator , std : : move ( file_reader ) ,
fd . GetFileSize ( ) , table_reader ) ;
TEST_SYNC_POINT ( " TableCache::GetTableReader:0 " ) ;
}
return s ;
}
Status TableCache : : FindTable ( const EnvOptions & env_options ,
const InternalKeyComparator & internal_comparator ,
const FileDescriptor & fd , Cache : : Handle * * handle ,
@ -86,31 +119,17 @@ Status TableCache::FindTable(const EnvOptions& env_options,
uint64_t number = fd . GetNumber ( ) ;
Slice key = GetSliceForFileNumber ( & number ) ;
* handle = cache_ - > Lookup ( key ) ;
TEST_SYNC_POINT_CALLBACK ( " TableCache::FindTable:0 " ,
const_cast < bool * > ( & no_io ) ) ;
if ( * handle = = nullptr ) {
if ( no_io ) { // Dont do IO and return a not-found status
return Status : : Incomplete ( " Table not found in table_cache, no_io is set " ) ;
}
std : : string fname =
TableFileName ( ioptions_ . db_paths , fd . GetNumber ( ) , fd . GetPathId ( ) ) ;
unique_ptr < RandomAccessFile > file ;
unique_ptr < TableReader > table_reader ;
s = ioptions_ . env - > NewRandomAccessFile ( fname , & file , env_options ) ;
RecordTick ( ioptions_ . statistics , NO_FILE_OPENS ) ;
if ( s . ok ( ) ) {
if ( ioptions_ . advise_random_on_open ) {
file - > Hint ( RandomAccessFile : : RANDOM ) ;
}
StopWatch sw ( ioptions_ . env , ioptions_ . statistics , TABLE_OPEN_IO_MICROS ) ;
std : : unique_ptr < RandomAccessFileReader > file_reader (
new RandomAccessFileReader (
std : : move ( file ) , ioptions_ . env ,
record_read_stats ? ioptions_ . statistics : nullptr ,
SST_READ_MICROS , file_read_hist ) ) ;
s = ioptions_ . table_factory - > NewTableReader (
ioptions_ , env_options , internal_comparator , std : : move ( file_reader ) ,
fd . GetFileSize ( ) , & table_reader ) ;
}
s = GetTableReader ( env_options , internal_comparator , fd ,
ioptions_ . advise_random_on_open , record_read_stats ,
file_read_hist , & table_reader ) ;
if ( ! s . ok ( ) ) {
assert ( table_reader = = nullptr ) ;
RecordTick ( ioptions_ . statistics , NO_FILE_ERRORS ) ;
@ -136,30 +155,47 @@ Iterator* TableCache::NewIterator(const ReadOptions& options,
if ( table_reader_ptr ! = nullptr ) {
* table_reader_ptr = nullptr ;
}
TableReader * table_reader = fd . table_reader ;
TableReader * table_reader = nullptr ;
Cache : : Handle * handle = nullptr ;
Status s ;
bool create_new_table_reader =
( for_compaction & & ioptions_ . new_table_reader_for_compaction_inputs ) ;
if ( create_new_table_reader ) {
unique_ptr < TableReader > table_reader_unique_ptr ;
Status s = GetTableReader ( env_options , icomparator , fd , false , false ,
nullptr , & table_reader_unique_ptr ) ;
if ( ! s . ok ( ) ) {
return NewErrorIterator ( s , arena ) ;
}
table_reader = table_reader_unique_ptr . release ( ) ;
} else {
table_reader = fd . table_reader ;
if ( table_reader = = nullptr ) {
s = FindTable ( env_options , icomparator , fd , & handle ,
options . read_tier = = kBlockCacheTier , ! for_compaction ,
file_read_hist ) ;
Status s = FindTable ( env_options , icomparator , fd , & handle ,
options . read_tier = = kBlockCacheTier ,
! for_compaction , file_read_hist ) ;
if ( ! s . ok ( ) ) {
return NewErrorIterator ( s , arena ) ;
}
table_reader = GetTableReaderFromHandle ( handle ) ;
}
}
Iterator * result = table_reader - > NewIterator ( options , arena ) ;
if ( handle ! = nullptr ) {
if ( create_new_table_reader ) {
assert ( handle = = nullptr ) ;
result - > RegisterCleanup ( & DeleteTableReader , table_reader , nullptr ) ;
} else if ( handle ! = nullptr ) {
result - > RegisterCleanup ( & UnrefEntry , cache_ , handle ) ;
}
if ( table_reader_ptr ! = nullptr ) {
* table_reader_ptr = table_reader ;
}
if ( for_compaction ) {
table_reader - > SetupForCompaction ( ) ;
}
if ( table_reader_ptr ! = nullptr ) {
* table_reader_ptr = table_reader ;
}
return result ;
}