remote_handle.hpp
1 /*
2  * Copyright (c) 2024-2025, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * https://apache.ac.cn/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <cassert>
19 #include <cstddef>
20 #include <cstring>
21 #include <iostream>
22 #include <memory>
23 #include <optional>
24 #include <regex>
25 #include <sstream>
26 #include <stdexcept>
27 #include <string>
28 
29 #include <kvikio/defaults.hpp>
30 #include <kvikio/error.hpp>
31 #include <kvikio/parallel_operation.hpp>
32 #include <kvikio/posix_io.hpp>
33 #include <kvikio/utils.hpp>
34 
35 namespace kvikio {
36 
37 class CurlHandle; // Prototype
38 
48  public
56  virtual void setopt(CurlHandle& curl) = 0;
57 
63  virtual std::string str() const = 0;
64 
65  virtual ~RemoteEndpoint() = default;
66 };
67 
71 class HttpEndpoint : public RemoteEndpoint {
72  private
73  std::string _url;
74 
75  public
81  HttpEndpoint(std::string url);
82  void setopt(CurlHandle& curl) override;
83  std::string str() const override;
84  ~HttpEndpoint() override = default;
85 };
86 
90 class S3Endpoint : public RemoteEndpoint {
91  private
92  std::string _url;
93  std::string _aws_sigv4;
94  std::string _aws_userpwd;
95 
109  static std::string unwrap_or_default(std::optional<std::string> aws_arg,
110  std::string const& env_var,
111  std::string const& err_msg = "");
112 
113  public
129  static std::string url_from_bucket_and_object(std::string const& bucket_name,
130  std::string const& object_name,
131  std::optional<std::string> const& aws_region,
132  std::optional<std::string> aws_endpoint_url);
133 
142  [[nodiscard]] static std::pair<std::string, std::string> parse_s3_url(std::string const& s3_url);
143 
157  S3Endpoint(std::string url,
158  std::optional<std::string> aws_region = std::nullopt,
159  std::optional<std::string> aws_access_key = std::nullopt,
160  std::optional<std::string> aws_secret_access_key = std::nullopt);
161 
178  S3Endpoint(std::string const& bucket_name,
179  std::string const& object_name,
180  std::optional<std::string> aws_region = std::nullopt,
181  std::optional<std::string> aws_access_key = std::nullopt,
182  std::optional<std::string> aws_secret_access_key = std::nullopt,
183  std::optional<std::string> aws_endpoint_url = std::nullopt);
184 
185  void setopt(CurlHandle& curl) override;
186  std::string str() const override;
187  ~S3Endpoint() override = default;
188 };
189 
194  private
195  std::unique_ptr<RemoteEndpoint> _endpoint;
196  std::size_t _nbytes;
197 
198  public
205  RemoteHandle(std::unique_ptr<RemoteEndpoint> endpoint, std::size_t nbytes);
206 
214  RemoteHandle(std::unique_ptr<RemoteEndpoint> endpoint);
215 
216  // A remote handle is moveable but not copyable.
217  RemoteHandle(RemoteHandle&& o) = default;
218  RemoteHandle& operator=(RemoteHandle&& o) = default;
219  RemoteHandle(RemoteHandle const&) = delete;
220  RemoteHandle& operator=(RemoteHandle const&) = delete;
221 
229  [[nodiscard]] std::size_t nbytes() const noexcept;
230 
236  [[nodiscard]] RemoteEndpoint const& endpoint() const noexcept;
237 
250  std::size_t read(void* buf, std::size_t size, std::size_t file_offset = 0);
251 
264  std::future<std::size_t> pread(void* buf,
265  std::size_t size,
266  std::size_t file_offset = 0,
267  std::size_t task_size = defaults::task_size());
268 };
269 
270 } // namespace kvikio
curl easy handle 指针及其操作的表示。
定义: libcurl.hpp:91
使用 HTTP 的远程端点。
std::string str() const override
获取此远程点实例的描述。
HttpEndpoint(std::string url)
从 URL 创建一个 HTTP 端点。
void setopt(CurlHandle &curl) override
在 curl handle 上设置所需的连接选项。
远程端点的抽象基类。
virtual void setopt(CurlHandle &curl)=0
在 curl handle 上设置所需的连接选项。
virtual std::string str() const =0
获取此远程点实例的描述。
远程文件的句柄。
std::size_t read(void *buf, std::size_t size, std::size_t file_offset=0)
从远程源读取到缓冲区(主机内存或设备内存)。
RemoteEndpoint const & endpoint() const noexcept
获取底层远程端点的常量引用。
std::size_t nbytes() const noexcept
获取文件大小。
RemoteHandle(std::unique_ptr< RemoteEndpoint > endpoint)
从端点创建一个新的远程句柄(推断文件大小)。
std::future< std::size_t > pread(void *buf, std::size_t size, std::size_t file_offset=0, std::size_t task_size=defaults::task_size())
从远程源并行读取到缓冲区(主机内存或设备内存)。
RemoteHandle(std::unique_ptr< RemoteEndpoint > endpoint, std::size_t nbytes)
从端点和文件大小创建一个新的远程句柄。
使用 AWS S3 协议的远程端点。
S3Endpoint(std::string const &bucket_name, std::string const &object_name, std::optional< std::string > aws_region=std::nullopt, std::optional< std::string > aws_access_key=std::nullopt, std::optional< std::string > aws_secret_access_key=std::nullopt, std::optional< std::string > aws_endpoint_url=std::nullopt)
从存储桶和对象名称创建一个 S3 端点。
static std::string url_from_bucket_and_object(std::string const &bucket_name, std::string const &object_name, std::optional< std::string > const &aws_region, std::optional< std::string > aws_endpoint_url)
从 AWS S3 存储桶和对象名称获取 URL。
void setopt(CurlHandle &curl) override
在 curl handle 上设置所需的连接选项。
S3Endpoint(std::string url, std::optional< std::string > aws_region=std::nullopt, std::optional< std::string > aws_access_key=std::nullopt, std::optional< std::string > aws_secret_access_key=std::nullopt)
从 URL 创建一个 S3 端点。
static std::pair< std::string, std::string > parse_s3_url(std::string const &s3_url)
给定形如 "s3://<bucket>/<object>" 的 URL,返回存储桶和对象的名称。
std::string str() const override
获取此远程点实例的描述。
KvikIO 中使用的默认值的单例类。
定义: defaults.hpp:63
KvikIO 命名空间。
定义: batch.hpp:27