1616
1717#include " paimon/fs/jindo/jindo_file_system.h"
1818
19+ #include < atomic>
1920#include < cassert>
21+ #include < string_view>
2022#include < utility>
2123
2224#include " JdoFileInfo.hpp" // NOLINT(build/include_subdir)
2628#include " fmt/format.h"
2729#include " jdo_error.h" // NOLINT(build/include_subdir)
2830#include " paimon/common/utils/math.h"
31+ #include " paimon/common/utils/path_util.h"
2932#include " paimon/fs/jindo/jindo_file_status.h"
3033#include " paimon/fs/jindo/jindo_utils.h"
3134
@@ -52,6 +55,29 @@ class JindoFileSystemImpl {
5255 std::unique_ptr<JdoFileSystem> fs_;
5356};
5457
58+ namespace {
59+
60+ class AsyncReadState {
61+ public:
62+ explicit AsyncReadState (std::function<void (Status)>&& callback)
63+ : callback_(std::move(callback)) {}
64+
65+ void Complete (JdoStatus status) {
66+ if (completed_.exchange (true )) {
67+ return ;
68+ }
69+ callback_ (status.ok () ? Status::OK () : Status::IOError (status.errMsg ()));
70+ }
71+
72+ std::string_view result;
73+
74+ private:
75+ std::atomic<bool > completed_{false };
76+ std::function<void (Status)> callback_;
77+ };
78+
79+ } // namespace
80+
5581JindoFileSystem::JindoFileSystem (std::unique_ptr<JdoFileSystem>&& fs)
5682 : impl_(std::make_shared<JindoFileSystemImpl>(std::move(fs))) {}
5783
@@ -68,6 +94,18 @@ Result<std::unique_ptr<OutputStream>> JindoFileSystem::Create(const std::string&
6894 return Status::Invalid (
6995 fmt::format (" do not allow overwrite, but the file {} already exists" , path));
7096 }
97+ const std::string parent_path = PathUtil::GetParentDirPath (path);
98+ if (!parent_path.empty ()) {
99+ PAIMON_ASSIGN_OR_RAISE (Path parent, PathUtil::ToPath (parent_path));
100+ // Do not issue mkdir for scheme-only or authority-only URI parents.
101+ if (!parent.path .empty ()) {
102+ PAIMON_RETURN_NOT_OK (Mkdirs (parent_path));
103+ }
104+ }
105+ return OpenWriter (path);
106+ }
107+
108+ Result<std::unique_ptr<OutputStream>> JindoFileSystem::OpenWriter (const std::string& path) const {
71109 std::unique_ptr<JdoWriter> writer;
72110 PAIMON_RETURN_NOT_OK_FROM_JINDO (impl_->GetFileSystem ()->openWriter (path, &writer));
73111 return std::make_unique<JindoOutputStream>(impl_, std::move (writer));
@@ -215,15 +253,17 @@ Result<int64_t> JindoInputStream::Length() const {
215253
216254Result<int64_t > JindoInputStream::Read (char * buffer, int64_t size) {
217255 PAIMON_RETURN_NOT_OK (ValidateValueNonNegative (size, " read length" ));
218- PAIMON_RETURN_NOT_OK_FROM_JINDO (reader_->read (size, &result_, buffer));
219- return result_.length ();
256+ std::string_view result;
257+ PAIMON_RETURN_NOT_OK_FROM_JINDO (reader_->read (size, &result, buffer));
258+ return result.length ();
220259}
221260
222261Result<int64_t > JindoInputStream::Read (char * buffer, int64_t size, int64_t offset) {
223262 PAIMON_RETURN_NOT_OK (ValidateValueNonNegative (size, " read length" ));
224263 PAIMON_RETURN_NOT_OK (ValidateValueNonNegative (offset, " read offset" ));
225- PAIMON_RETURN_NOT_OK_FROM_JINDO (reader_->pread (offset, size, &result_, buffer));
226- return result_.length ();
264+ std::string_view result;
265+ PAIMON_RETURN_NOT_OK_FROM_JINDO (reader_->pread (offset, size, &result, buffer));
266+ return result.length ();
227267}
228268
229269void JindoInputStream::ReadAsync (char * buffer, int64_t size, int64_t offset,
@@ -238,12 +278,17 @@ void JindoInputStream::ReadAsync(char* buffer, int64_t size, int64_t offset,
238278 callback (validate_status);
239279 return ;
240280 }
241- auto outer_callback = [=](JdoStatus status) {
242- callback (status.ok () ? Status::OK () : Status::IOError (status.errMsg ()));
243- };
244- auto task = reader_->preadAsync (offset, size, &result_, buffer, outer_callback);
281+ std::shared_ptr<AsyncReadState> state = std::make_shared<AsyncReadState>(std::move (callback));
282+ auto task = reader_->preadAsync (offset, size, &state->result , buffer,
283+ [state](JdoStatus status) { state->Complete (status); });
245284 assert (task);
246- [[maybe_unused]] auto perform_status = task->perform ();
285+
286+ auto perform_status = task->perform ();
287+ if (!perform_status.ok ()) {
288+ state->Complete (perform_status);
289+ [[maybe_unused]] auto status = task->cancel ();
290+ return ;
291+ }
247292}
248293
249294Status JindoInputStream::Close () {
0 commit comments