| 3251 | // Read the physical extent at given pageID |
| 3252 | // NOTE that we use the same interface (<ArenaPage>) for the extent as the page |
| 3253 | ACTOR static Future<Reference<ArenaPage>> readPhysicalExtent(DWALPager* self, |
| 3254 | PhysicalPageID pageID, |
| 3255 | int readSize = 0) { |
| 3256 | // First take the concurrentExtentReads lock to avoid issuing too many reads concurrently |
| 3257 | wait(self->concurrentExtentReads->take()); |
| 3258 | |
| 3259 | ASSERT(!self->memoryOnly); |
| 3260 | |
| 3261 | if (g_network->getCurrentTask() > TaskPriority::DiskRead) { |
| 3262 | wait(delay(0, TaskPriority::DiskRead)); |
| 3263 | } |
| 3264 | |
| 3265 | // readSize may not be equal to the physical extent size (for the first and last extents) |
| 3266 | // but otherwise use the full physical extent size |
| 3267 | if (readSize == 0) { |
| 3268 | readSize = self->physicalExtentSize; |
| 3269 | } |
| 3270 | |
| 3271 | state Reference<ArenaPage> extent = makeReference<ArenaPage>(readSize, readSize); |
| 3272 | |
| 3273 | // physicalReadSize is the size of disk read we intend to issue |
| 3274 | auto physicalReadSize = SERVER_KNOBS->REDWOOD_DEFAULT_EXTENT_READ_SIZE; |
| 3275 | auto parallelReads = readSize / physicalReadSize; |
| 3276 | auto lastReadSize = readSize % physicalReadSize; |
| 3277 | |
| 3278 | debug_printf("DWALPager(%s) op=readPhysicalExtentStart %s readSize %d offset %" PRId64 |
| 3279 | " physicalReadSize %d parallelReads %d\n", |
| 3280 | self->filename.c_str(), |
| 3281 | toString(pageID).c_str(), |
| 3282 | readSize, |
| 3283 | (int64_t)pageID * (self->physicalPageSize), |
| 3284 | physicalReadSize, |
| 3285 | parallelReads); |
| 3286 | |
| 3287 | // we split the extent read into a number of parallel disk reads based on the determined physical |
| 3288 | // disk read size. All those reads are issued in parallel and their futures are stored into the following |
| 3289 | // reads vector |
| 3290 | std::vector<Future<int>> reads; |
| 3291 | int i; |
| 3292 | int64_t startOffset = (int64_t)pageID * (self->physicalPageSize); |
| 3293 | int64_t currentOffset; |
| 3294 | for (i = 0; i < parallelReads; i++) { |
| 3295 | currentOffset = i * physicalReadSize; |
| 3296 | debug_printf("DWALPager(%s) current offset %" PRId64 "\n", self->filename.c_str(), currentOffset); |
| 3297 | ++g_redwoodMetrics.metric.pagerDiskRead; |
| 3298 | reads.push_back(self->readPhysicalBlock( |
| 3299 | self, extent, currentOffset, physicalReadSize, startOffset + currentOffset, ioMaxPriority)); |
| 3300 | } |
| 3301 | |
| 3302 | // Handle the last read separately as it may be smaller than physicalReadSize |
| 3303 | if (lastReadSize) { |
| 3304 | currentOffset = i * physicalReadSize; |
| 3305 | debug_printf("DWALPager(%s) iter %d current offset %" PRId64 " lastReadSize %d\n", |
| 3306 | self->filename.c_str(), |
| 3307 | i, |
| 3308 | currentOffset, |
| 3309 | lastReadSize); |
| 3310 | ++g_redwoodMetrics.metric.pagerDiskRead; |
no test coverage detected