VeloGraphX
High-performance dynamic graph analytics in C++20
Loading...
Searching...
No Matches
io_uring_prefetch.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <filesystem>
6#include <vector>
7
8#if defined(VELOGRAPHX_ENABLE_IO_URING) && defined(__linux__) && __has_include(<liburing.h>)
9#include <fcntl.h>
10#include <liburing.h>
11#include <sys/stat.h>
12#include <unistd.h>
13#endif
14
15namespace velographx {
16
18 bool compiled{false};
19 bool attempted{false};
20 bool succeeded{false};
21 std::size_t bytes_requested{0};
22 int error_code{0};
23};
24
26 public:
27 [[nodiscard]] static constexpr bool compiled() noexcept {
28#if defined(VELOGRAPHX_ENABLE_IO_URING) && defined(__linux__) && __has_include(<liburing.h>)
29 return true;
30#else
31 return false;
32#endif
33 }
34
35 static IoUringPrefetchResult prefetch(const std::filesystem::path& path,
36 std::size_t max_bytes = 1U << 20U) noexcept {
38 result.compiled = compiled();
39#if defined(VELOGRAPHX_ENABLE_IO_URING) && defined(__linux__) && __has_include(<liburing.h>)
40 result.attempted = true;
41 const int fd = ::open(path.c_str(), O_RDONLY | O_CLOEXEC);
42 if (fd < 0) {
43 result.error_code = errno;
44 return result;
45 }
46
47 struct stat st {};
48 if (::fstat(fd, &st) != 0 || st.st_size <= 0) {
49 result.error_code = errno;
50 ::close(fd);
51 return result;
52 }
53
54 const auto bytes = static_cast<std::size_t>(st.st_size) < max_bytes
55 ? static_cast<std::size_t>(st.st_size)
56 : max_bytes;
57 result.bytes_requested = bytes;
58 std::vector<std::uint8_t> buffer(bytes);
59
60 io_uring ring {};
61 int rc = io_uring_queue_init(2, &ring, 0);
62 if (rc < 0) {
63 result.error_code = -rc;
64 ::close(fd);
65 return result;
66 }
67
68 io_uring_sqe* sqe = io_uring_get_sqe(&ring);
69 if (sqe == nullptr) {
70 result.error_code = EBUSY;
71 io_uring_queue_exit(&ring);
72 ::close(fd);
73 return result;
74 }
75
76 io_uring_prep_read(sqe, fd, buffer.data(), static_cast<unsigned>(buffer.size()), 0);
77 rc = io_uring_submit(&ring);
78 if (rc < 0) {
79 result.error_code = -rc;
80 io_uring_queue_exit(&ring);
81 ::close(fd);
82 return result;
83 }
84
85 io_uring_cqe* cqe = nullptr;
86 rc = io_uring_wait_cqe(&ring, &cqe);
87 if (rc < 0) {
88 result.error_code = -rc;
89 } else if (cqe->res < 0) {
90 result.error_code = -cqe->res;
91 io_uring_cqe_seen(&ring, cqe);
92 } else {
93 result.succeeded = true;
94 io_uring_cqe_seen(&ring, cqe);
95 }
96
97 io_uring_queue_exit(&ring);
98 ::close(fd);
99#else
100 (void)path;
101 (void)max_bytes;
102#endif
103 return result;
104 }
105};
106
107} // namespace velographx
static constexpr bool compiled() noexcept
static IoUringPrefetchResult prefetch(const std::filesystem::path &path, std::size_t max_bytes=1U<< 20U) noexcept