//------------------------------------------------------------------------------ //! @file XrdCpPgRead.cc //! @author Elvin Sindrilaru - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2022 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #include "XrdCl/XrdClFile.hh" #include #include #include //------------------------------------------------------------------------------ //! This executable simulates a client that reads from a file using pgRead API. //------------------------------------------------------------------------------ int main(int argc, char* argv[]) { constexpr uint32_t max_length = 10 * 1024 * 1024; int retc = 0; if (argc != 4) { std::cerr << "Usage: " << argv[0] << " \n" << " - XRootD URL of file read\n" << " - read offset\n" << " - read offset\n"; exit(EINVAL); } std::string surl = argv[1]; XrdCl::URL url(surl); if (!url.IsValid()) { std::cerr << "error: given XRootD URL is not valid" << std::endl; exit(EINVAL); } uint64_t offset = 0ull; uint32_t length = 0ul; try { offset = std::stoull(std::string(argv[2])); length = std::stoul(std::string(argv[3])); } catch (...) { std::cerr << "error: failed to convert given input" << std::endl; exit(EINVAL); } if (length > max_length) { std::cerr << "error: length must be <= 10MB" << std::endl; exit(EINVAL); } // Allocate buffer used for transfer std::unique_ptr buffer {new char[length]}; XrdCl::File file; XrdCl::XRootDStatus status = file.Open(surl, XrdCl::OpenFlags::Read, XrdCl::Access::None); if (!status.IsOK()) { std::cerr << "error: unable to open file for reading, errno=" << status.errNo << std::endl; exit(status.errNo); } std::vector cksums; uint32_t bytes_read = 0ul; if ((offset == 0) && (length == 0)) { constexpr uint32_t max_buff = 4 * 1024 * 1024; buffer.reset(new char[max_buff]); std::mt19937_64 gen(12345678); std::uniform_int_distribution dist_off(0ull, 1235676367ull); std::uniform_int_distribution dist_len(4096ull, max_buff); uint32_t samples = 10000; for (unsigned int i = 0; i < samples; ++i) { cksums.clear(); uint64_t rand_off = dist_off(gen); uint32_t rand_len = dist_len(gen); std::cout << "index: " << i << " pgread: rand_off=" << rand_off << " rand_len=" << rand_len << std::endl; status = file.PgRead(rand_off, rand_len, buffer.get(), cksums, bytes_read); if (!status.IsOK()) { std::cerr << "error: failed pgread rand_off=" << rand_off << " rand_len=" << rand_len << std::endl; exit(status.errNo); } } } else { std::cout << " pgread: offset=" << offset << " length=" << length << std::endl; status = file.PgRead(offset, length, buffer.get(), cksums, bytes_read); if (!status.IsOK()) { std::cerr << "error: failed pgread offset=" << offset << " length=" << length << std::endl; exit(status.errNo); } } if (!file.Close().IsOK()) { std::cerr << "error: failed to close file" << std::endl; exit(EIO); } return retc; }