void randomReads()

in velox/common/file/benchmark/ReadBenchmark.h [135:274]


  void randomReads(
      int32_t size,
      int32_t gap,
      int32_t count,
      int32_t repeats,
      Mode mode,
      bool parallel) {
    clearCache();
    std::vector<folly::Promise<bool>> promises;
    std::vector<folly::SemiFuture<bool>> futures;
    uint64_t usec = 0;
    std::string label;
    {
      MicrosecondTimer timer(&usec);
      int32_t rangeSize = size * count + gap * (count - 1);
      auto& globalScratch = getScratch(rangeSize);
      globalScratch.buffer.resize(rangeSize);
      globalScratch.bufferCopy.resize(rangeSize);
      for (auto repeat = 0; repeat < repeats; ++repeat) {
        std::unique_ptr<folly::Promise<bool>> promise;
        if (parallel) {
          auto [tempPromise, future] = folly::makePromiseContract<bool>();
          promise = std::make_unique<folly::Promise<bool>>();
          *promise = std::move(tempPromise);
          futures.push_back(std::move(future));
        }
        int64_t offset = folly::Random::rand64(rng_) % (fileSize_ - rangeSize);
        switch (mode) {
          case Mode::Pread:
            label = "1 pread";
            if (parallel) {
              executor_->add([offset,
                              gap,
                              size,
                              count,
                              rangeSize,
                              this,
                              capturedPromise = std::move(promise)]() {
                auto& scratch = getScratch(rangeSize);
                readFile_->pread(offset, rangeSize, scratch.buffer.data());
                for (auto i = 0; i < count; ++i) {
                  memcpy(
                      scratch.bufferCopy.data() + i * size,
                      scratch.buffer.data() + i * (size + gap),
                      size);
                }
                capturedPromise->setValue(true);
              }

              );
            } else {
              readFile_->pread(offset, rangeSize, globalScratch.buffer.data());
              for (auto i = 0; i < count; ++i) {
                memcpy(
                    globalScratch.bufferCopy.data() + i * size,
                    globalScratch.buffer.data() + i * (size + gap),
                    size);
              }
            }
            break;
          case Mode::Preadv: {
            label = "1 preadv";
            if (parallel) {
              executor_->add([offset,
                              gap,
                              size,
                              rangeSize,
                              this,
                              capturedPromise = std::move(promise)]() {
                auto& scratch = getScratch(rangeSize);
                std::vector<folly::Range<char*>> ranges;
                for (auto start = 0; start < rangeSize; start += size + gap) {
                  ranges.push_back(
                      folly::Range<char*>(scratch.buffer.data() + start, size));
                  if (gap && start + gap < rangeSize) {
                    ranges.push_back(folly::Range<char*>(nullptr, gap));
                  }
                }
                readFile_->preadv(offset, ranges);
                capturedPromise->setValue(true);
              });
            } else {
              std::vector<folly::Range<char*>> ranges;
              for (auto start = 0; start < rangeSize; start += size + gap) {
                ranges.push_back(folly::Range<char*>(
                    globalScratch.buffer.data() + start, size));
                if (gap && start + gap < rangeSize) {
                  ranges.push_back(folly::Range<char*>(nullptr, gap));
                }
              }
              readFile_->preadv(offset, ranges);
            }

            break;
          }
          case Mode::Multiple: {
            label = "multiple pread";
            if (parallel) {
              executor_->add([offset,
                              gap,
                              size,
                              count,
                              rangeSize,
                              this,
                              capturedPromise = std::move(promise)]() {
                auto& scratch = getScratch(rangeSize);
                for (auto counter = 0; counter < count; ++counter) {
                  readFile_->pread(
                      offset + counter * (size + gap),
                      size,
                      scratch.buffer.data() + counter * size);
                }
                capturedPromise->setValue(true);
              });
            } else {
              for (auto counter = 0; counter < count; ++counter) {
                readFile_->pread(
                    offset + counter * (size + gap),
                    size,
                    globalScratch.buffer.data() + counter * size);
              }
            }
            break;
          }
        }
      }
      if (parallel) {
        auto& exec = folly::QueuedImmediateExecutor::instance();
        for (int32_t i = futures.size() - 1; i >= 0; --i) {
          std::move(futures[i]).via(&exec).wait();
        }
      }
    }
    std::cout << fmt::format(
                     "{} MB/s {} {}",
                     (static_cast<float>(count) * size * repeats) / usec,
                     label,
                     parallel ? "mt" : "")
              << std::endl;
  }