| 231 | delete flash_file_; |
| 232 | } |
| 233 | Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const { |
| 234 | bool use_flash = false; |
| 235 | { |
| 236 | MutexLock l(&mutex_); |
| 237 | // evenry 30 seconds, check if flash file is identical to dfs file. |
| 238 | // if so, try open flash file; |
| 239 | // else, reschedule update it with a higher priority |
| 240 | if (flash_file_ == NULL && !flash_file_is_checking_ && |
| 241 | flash_file_last_check_micros_ + flash_file_check_interval_micros_ <= |
| 242 | Env::Default()->NowMicros()) { |
| 243 | flash_file_is_checking_ = true; |
| 244 | mutex_.Unlock(); |
| 245 | RandomAccessFile* tmp_file = NULL; |
| 246 | if (flash_env_->FlashFileIdentical(fname_, fsize_)) { |
| 247 | flash_env_->CacheEnv()->NewRandomAccessFile(local_fname_, &tmp_file, env_opt_); |
| 248 | } |
| 249 | mutex_.Lock(); |
| 250 | if (tmp_file != NULL) { |
| 251 | flash_file_ = tmp_file; |
| 252 | LOG(INFO) << "[env_flash] switch to local file: " << local_fname_.c_str(); |
| 253 | } else { |
| 254 | flash_env_->ScheduleUpdateFlash(fname_, fsize_, read_dfs_count_); |
| 255 | read_dfs_count_ = 0; |
| 256 | } |
| 257 | flash_file_is_checking_ = false; |
| 258 | flash_file_last_check_micros_ = Env::Default()->NowMicros(); |
| 259 | } |
| 260 | if (flash_file_ != NULL) { |
| 261 | use_flash = true; |
| 262 | } else { |
| 263 | ++read_dfs_count_; |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | if (use_flash) { |
| 268 | Status read_status = flash_file_->Read(offset, n, result, scratch); |
| 269 | if (read_status.ok()) { |
| 270 | ssd_read_counter.Inc(); |
| 271 | ssd_read_size_counter.Add(result->size()); |
| 272 | } |
| 273 | return read_status; |
| 274 | } |
| 275 | return dfs_file_->Read(offset, n, result, scratch); |
| 276 | } |
| 277 | |
| 278 | size_t GetRequiredBufferAlignment() const { return logical_sector_size_; } |
| 279 |
nothing calls this directly
no test coverage detected