This is an automated email from the ASF dual-hosted git repository.
bkietz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/main by this push:
new fd75cbdb38 GH-40342: [C++] move LocalFileSystem to the registry
(#40356)
fd75cbdb38 is described below
commit fd75cbdb38836b66dbae81094cf06821e5d25cb1
Author: Benjamin Kietzman <[email protected]>
AuthorDate: Wed Apr 24 10:27:17 2024 -0400
GH-40342: [C++] move LocalFileSystem to the registry (#40356)
### Rationale for this change
Moving LocalFileSystem into the registry is a good first usage and will
help us hammer out which aspects of built in file systems should remain public.
### What changes are included in this PR?
A factory for LocalFileSystem is added to the registry.
`FileSystem::MakeUri` ( https://github.com/apache/arrow/issues/18316 ) is added
to enable roundtripping filesystems through URIs. `file://` URIs now support a
use_mmap query parameter, and `local://` URIs are also supported as an alias.
<h6 id="reduce">Reducing the set of bound classes</h6>
Some unnecessary bindings to the LocalFileSystem concrete class are
removed. This demonstrates that with a registered factory pattern, it is no
longer necessary to keep a class hierarchy public for binding. Eventually (if
desired), we can move concrete subclasses of FileSystem entirely out of public
headers.
### Are these changes tested?
Yes, all existing tests for file:// URIs continue to pass
### Are there any user-facing changes?
For consistency, local:// URIs will now be considered equivalent to
corresponding file:// URIs
* GitHub Issue: #40342
Authored-by: Benjamin Kietzman <[email protected]>
Signed-off-by: Benjamin Kietzman <[email protected]>
---
.../arrow/filesystem_definition_example.cc | 4 +--
cpp/src/arrow/filesystem/CMakeLists.txt | 4 ++-
cpp/src/arrow/filesystem/filesystem.cc | 35 ++++++++++----------
cpp/src/arrow/filesystem/filesystem.h | 30 ++++++++++++++++--
cpp/src/arrow/filesystem/localfs.cc | 37 ++++++++++++++++++++--
cpp/src/arrow/filesystem/localfs.h | 1 +
cpp/src/arrow/filesystem/localfs_test.cc | 29 ++++++++++-------
cpp/src/arrow/testing/examplefs.cc | 4 +--
docs/source/cpp/io.rst | 7 ++--
python/pyarrow/_fs.pxd | 3 --
python/pyarrow/_fs.pyx | 34 ++++++++------------
python/pyarrow/includes/libarrow_fs.pxd | 16 ++--------
r/R/arrowExports.R | 4 ---
r/R/filesystem.R | 3 +-
r/src/arrowExports.cpp | 8 -----
r/src/filesystem.cpp | 14 +++-----
16 files changed, 130 insertions(+), 103 deletions(-)
diff --git a/cpp/examples/arrow/filesystem_definition_example.cc
b/cpp/examples/arrow/filesystem_definition_example.cc
index efe1bd1047..65301bb843 100644
--- a/cpp/examples/arrow/filesystem_definition_example.cc
+++ b/cpp/examples/arrow/filesystem_definition_example.cc
@@ -138,7 +138,7 @@ class ExampleFileSystem : public fs::FileSystem {
}
};
-fs::FileSystemRegistrar kExampleFileSystemModule{
+auto kExampleFileSystemModule = ARROW_REGISTER_FILESYSTEM(
"example",
[](const arrow::util::Uri& uri, const io::IOContext& io_context,
std::string* out_path) -> Result<std::shared_ptr<fs::FileSystem>> {
@@ -148,4 +148,4 @@ fs::FileSystemRegistrar kExampleFileSystemModule{
}
return fs;
},
-};
+ {});
diff --git a/cpp/src/arrow/filesystem/CMakeLists.txt
b/cpp/src/arrow/filesystem/CMakeLists.txt
index deac04af72..0a31a64b7a 100644
--- a/cpp/src/arrow/filesystem/CMakeLists.txt
+++ b/cpp/src/arrow/filesystem/CMakeLists.txt
@@ -28,7 +28,9 @@ add_arrow_test(filesystem-test
EXTRA_LABELS
filesystem
DEFINITIONS
-
ARROW_FILESYSTEM_EXAMPLE_LIBPATH="$<TARGET_FILE:arrow_filesystem_example>")
+
ARROW_FILESYSTEM_EXAMPLE_LIBPATH="$<TARGET_FILE:arrow_filesystem_example>"
+ EXTRA_DEPENDENCIES
+ arrow_filesystem_example)
if(ARROW_BUILD_BENCHMARKS)
add_arrow_benchmark(localfs_benchmark
diff --git a/cpp/src/arrow/filesystem/filesystem.cc
b/cpp/src/arrow/filesystem/filesystem.cc
index c96a5fd2cf..b79af08385 100644
--- a/cpp/src/arrow/filesystem/filesystem.cc
+++ b/cpp/src/arrow/filesystem/filesystem.cc
@@ -56,16 +56,13 @@
#include "arrow/util/visibility.h"
#include "arrow/util/windows_fixup.h"
-namespace arrow {
-
-using internal::checked_pointer_cast;
-using internal::TaskHints;
-using io::internal::SubmitIO;
-using util::Uri;
-
-namespace fs {
+namespace arrow::fs {
+using arrow::internal::checked_pointer_cast;
using arrow::internal::GetEnvVar;
+using arrow::internal::TaskHints;
+using arrow::io::internal::SubmitIO;
+using arrow::util::Uri;
using internal::ConcatAbstractPath;
using internal::EnsureTrailingSlash;
using internal::GetAbstractPathParent;
@@ -273,6 +270,11 @@ Result<std::string> FileSystem::PathFromUri(const
std::string& uri_string) const
return Status::NotImplemented("PathFromUri is not yet supported on this
filesystem");
}
+Result<std::string> FileSystem::MakeUri(std::string path) const {
+ return Status::NotImplemented("MakeUri is not yet supported for ",
type_name(),
+ " filesystems");
+}
+
//////////////////////////////////////////////////////////////////////////
// SubTreeFileSystem implementation
@@ -726,6 +728,10 @@ class FileSystemFactoryRegistry {
main_registry->scheme_to_factory_.emplace(std::move(scheme),
registered);
if (success) continue;
+ if (it->second.ok()) {
+ if (registered->factory == it->second->factory) continue;
+ }
+
duplicated_schemes.emplace_back(it->first);
}
scheme_to_factory_.clear();
@@ -852,18 +858,10 @@ Result<std::shared_ptr<FileSystem>>
FileSystemFromUriReal(const Uri& uri,
auto* factory,
FileSystemFactoryRegistry::GetInstance()->FactoryForScheme(scheme));
if (factory != nullptr) {
- return (*factory)(uri, io_context, out_path);
+ return factory->function(uri, io_context, out_path);
}
}
- if (scheme == "file") {
- std::string path;
- ARROW_ASSIGN_OR_RAISE(auto options, LocalFileSystemOptions::FromUri(uri,
&path));
- if (out_path != nullptr) {
- *out_path = path;
- }
- return std::make_shared<LocalFileSystem>(options, io_context);
- }
if (scheme == "abfs" || scheme == "abfss") {
#ifdef ARROW_AZURE
ARROW_ASSIGN_OR_RAISE(auto options, AzureOptions::FromUri(uri, out_path));
@@ -969,5 +967,4 @@ Status Initialize(const FileSystemGlobalOptions& options) {
return Status::OK();
}
-} // namespace fs
-} // namespace arrow
+} // namespace arrow::fs
diff --git a/cpp/src/arrow/filesystem/filesystem.h
b/cpp/src/arrow/filesystem/filesystem.h
index 272e42256a..d4f62f86a7 100644
--- a/cpp/src/arrow/filesystem/filesystem.h
+++ b/cpp/src/arrow/filesystem/filesystem.h
@@ -197,6 +197,11 @@ class ARROW_EXPORT FileSystem
/// \return The path inside the filesystem that is indicated by the URI.
virtual Result<std::string> PathFromUri(const std::string& uri_string) const;
+ /// \brief Make a URI from which FileSystemFromUri produces an equivalent
filesystem
+ /// \param path The path component to use in the resulting URI
+ /// \return A URI string, or an error if an equivalent URI cannot be produced
+ virtual Result<std::string> MakeUri(std::string path) const;
+
virtual bool Equals(const FileSystem& other) const = 0;
virtual bool Equals(const std::shared_ptr<FileSystem>& other) const {
@@ -352,8 +357,23 @@ class ARROW_EXPORT FileSystem
bool default_async_is_sync_ = true;
};
-using FileSystemFactory = std::function<Result<std::shared_ptr<FileSystem>>(
- const Uri& uri, const io::IOContext& io_context, std::string* out_path)>;
+struct FileSystemFactory {
+ std::function<Result<std::shared_ptr<FileSystem>>(
+ const Uri& uri, const io::IOContext& io_context, std::string* out_path)>
+ function;
+ std::string_view file;
+ int line;
+
+ bool operator==(const FileSystemFactory& other) const {
+ // In the case where libarrow is linked statically both to the executable
and to a
+ // dynamically loaded filesystem implementation library, the library
contains a
+ // duplicate definition of the registry and duplicate definitions of any
+ // FileSystemRegistrars which are statically linked to libarrow. When
retrieving
+ // factories from the filesystem implementation library, we use the file
and line
+ // of the registrar's definition to determine equivalence of the duplicate
factories.
+ return file == other.file && line == other.line;
+ }
+};
/// \brief A FileSystem implementation that delegates to another
/// implementation after prepending a fixed base path.
@@ -645,6 +665,12 @@ struct ARROW_EXPORT FileSystemRegistrar {
std::function<void()> finalizer = {});
};
+#define ARROW_REGISTER_FILESYSTEM(scheme, factory_function, finalizer)
\
+ ::arrow::fs::FileSystemRegistrar {
\
+ scheme, ::arrow::fs::FileSystemFactory{factory_function, __FILE__,
__LINE__}, \
+ finalizer
\
+ }
+
/// @}
namespace internal {
diff --git a/cpp/src/arrow/filesystem/localfs.cc
b/cpp/src/arrow/filesystem/localfs.cc
index fbb33fd008..25ac04b758 100644
--- a/cpp/src/arrow/filesystem/localfs.cc
+++ b/cpp/src/arrow/filesystem/localfs.cc
@@ -39,6 +39,7 @@
#include "arrow/io/type_fwd.h"
#include "arrow/util/async_generator.h"
#include "arrow/util/io_util.h"
+#include "arrow/util/string.h"
#include "arrow/util/uri.h"
#include "arrow/util/windows_fixup.h"
@@ -246,8 +247,20 @@ Result<LocalFileSystemOptions>
LocalFileSystemOptions::FromUri(
std::string(internal::RemoveTrailingSlash(uri.path(),
/*preserve_root=*/true));
}
- // TODO handle use_mmap option
- return LocalFileSystemOptions();
+ LocalFileSystemOptions options;
+ ARROW_ASSIGN_OR_RAISE(auto params, uri.query_items());
+ for (const auto& [key, value] : params) {
+ if (key == "use_mmap") {
+ if (value.empty()) {
+ options.use_mmap = true;
+ continue;
+ } else {
+ ARROW_ASSIGN_OR_RAISE(options.use_mmap,
::arrow::internal::ParseBoolean(value));
+ }
+ break;
+ }
+ }
+ return options;
}
LocalFileSystem::LocalFileSystem(const io::IOContext& io_context)
@@ -273,6 +286,11 @@ Result<std::string> LocalFileSystem::PathFromUri(const
std::string& uri_string)
authority_handling);
}
+Result<std::string> LocalFileSystem::MakeUri(std::string path) const {
+ ARROW_ASSIGN_OR_RAISE(path, DoNormalizePath(std::move(path)));
+ return "file://" + path + (options_.use_mmap ? "?use_mmap" : "");
+}
+
bool LocalFileSystem::Equals(const FileSystem& other) const {
if (other.type_name() != type_name()) {
return false;
@@ -686,4 +704,19 @@ Result<std::shared_ptr<io::OutputStream>>
LocalFileSystem::OpenAppendStream(
return OpenOutputStreamGeneric(path, truncate, append);
}
+static Result<std::shared_ptr<fs::FileSystem>> LocalFileSystemFactory(
+ const arrow::util::Uri& uri, const io::IOContext& io_context, std::string*
out_path) {
+ std::string path;
+ ARROW_ASSIGN_OR_RAISE(auto options, LocalFileSystemOptions::FromUri(uri,
&path));
+ if (out_path != nullptr) {
+ *out_path = std::move(path);
+ }
+ return std::make_shared<LocalFileSystem>(options, io_context);
+}
+
+FileSystemRegistrar kLocalFileSystemModule[]{
+ ARROW_REGISTER_FILESYSTEM("file", LocalFileSystemFactory, {}),
+ ARROW_REGISTER_FILESYSTEM("local", LocalFileSystemFactory, {}),
+};
+
} // namespace arrow::fs
diff --git a/cpp/src/arrow/filesystem/localfs.h
b/cpp/src/arrow/filesystem/localfs.h
index 45a3da317f..d72e8f7d74 100644
--- a/cpp/src/arrow/filesystem/localfs.h
+++ b/cpp/src/arrow/filesystem/localfs.h
@@ -83,6 +83,7 @@ class ARROW_EXPORT LocalFileSystem : public FileSystem {
Result<std::string> NormalizePath(std::string path) override;
Result<std::string> PathFromUri(const std::string& uri_string) const
override;
+ Result<std::string> MakeUri(std::string path) const override;
bool Equals(const FileSystem& other) const override;
diff --git a/cpp/src/arrow/filesystem/localfs_test.cc
b/cpp/src/arrow/filesystem/localfs_test.cc
index b76c7ebad4..1a20e44bc3 100644
--- a/cpp/src/arrow/filesystem/localfs_test.cc
+++ b/cpp/src/arrow/filesystem/localfs_test.cc
@@ -15,8 +15,6 @@
// specific language governing permissions and limitations
// under the License.
-#include <cerrno>
-#include <chrono>
#include <memory>
#include <sstream>
#include <string>
@@ -113,10 +111,8 @@ Result<std::shared_ptr<FileSystem>>
SlowFileSystemFactory(const Uri& uri,
}
return std::make_shared<SlowFileSystemPublicProps>(base_fs, average_latency,
seed);
}
-FileSystemRegistrar kSlowFileSystemModule{
- "slowfile",
- SlowFileSystemFactory,
-};
+auto kSlowFileSystemModule =
+ ARROW_REGISTER_FILESYSTEM("slowfile", SlowFileSystemFactory, {});
TEST(FileSystemFromUri, LinkedRegisteredFactory) {
// Since the registrar's definition is in this translation unit (which is
linked to the
@@ -158,23 +154,24 @@ TEST(FileSystemFromUri, RuntimeRegisteredFactory) {
EXPECT_THAT(FileSystemFromUri("slowfile2:///hey/yo", &path),
Raises(StatusCode::Invalid));
- EXPECT_THAT(RegisterFileSystemFactory("slowfile2", SlowFileSystemFactory),
Ok());
+ EXPECT_THAT(RegisterFileSystemFactory("slowfile2", {SlowFileSystemFactory,
"", 0}),
+ Ok());
ASSERT_OK_AND_ASSIGN(auto fs, FileSystemFromUri("slowfile2:///hey/yo",
&path));
EXPECT_EQ(path, "/hey/yo");
EXPECT_EQ(fs->type_name(), "slow");
EXPECT_THAT(
- RegisterFileSystemFactory("slowfile2", SlowFileSystemFactory),
+ RegisterFileSystemFactory("slowfile2", {SlowFileSystemFactory, "", 0}),
Raises(StatusCode::KeyError,
testing::HasSubstr("Attempted to register factory for scheme
'slowfile2' "
"but that scheme is already registered")));
}
FileSystemRegistrar kSegfaultFileSystemModule[]{
- {"segfault", nullptr},
- {"segfault", nullptr},
- {"segfault", nullptr},
+ ARROW_REGISTER_FILESYSTEM("segfault", nullptr, {}),
+ ARROW_REGISTER_FILESYSTEM("segfault", nullptr, {}),
+ ARROW_REGISTER_FILESYSTEM("segfault", nullptr, {}),
};
TEST(FileSystemFromUri, LinkedRegisteredFactoryNameCollision) {
// Since multiple registrars are defined in this translation unit which all
@@ -312,6 +309,7 @@ class TestLocalFS : public LocalFSTestMixin {
std::string path;
ASSERT_OK_AND_ASSIGN(fs_, fs_from_uri(uri, &path));
ASSERT_EQ(fs_->type_name(), "local");
+ local_fs_ = ::arrow::internal::checked_pointer_cast<LocalFileSystem>(fs_);
ASSERT_EQ(path, expected_path);
ASSERT_OK_AND_ASSIGN(path, fs_->PathFromUri(uri));
ASSERT_EQ(path, expected_path);
@@ -423,8 +421,17 @@ TYPED_TEST(TestLocalFS, FileSystemFromUriFile) {
// Variations
this->TestLocalUri("file:/foo/bar", "/foo/bar");
+ ASSERT_FALSE(this->local_fs_->options().use_mmap);
this->TestLocalUri("file:///foo/bar", "/foo/bar");
this->TestLocalUri("file:///some%20path/%25percent", "/some path/%percent");
+
+ this->TestLocalUri("file:///_?use_mmap", "/_");
+ if (this->path_formatter_.supports_uri()) {
+ ASSERT_TRUE(this->local_fs_->options().use_mmap);
+ ASSERT_OK_AND_ASSIGN(auto uri, this->fs_->MakeUri("/_"));
+ EXPECT_EQ(uri, "file:///_?use_mmap");
+ }
+
#ifdef _WIN32
this->TestLocalUri("file:/C:/foo/bar", "C:/foo/bar");
this->TestLocalUri("file:///C:/foo/bar", "C:/foo/bar");
diff --git a/cpp/src/arrow/testing/examplefs.cc
b/cpp/src/arrow/testing/examplefs.cc
index d3e7e3b03f..5c9d5f9d90 100644
--- a/cpp/src/arrow/testing/examplefs.cc
+++ b/cpp/src/arrow/testing/examplefs.cc
@@ -24,7 +24,7 @@
namespace arrow::fs {
-FileSystemRegistrar kExampleFileSystemModule{
+auto kExampleFileSystemModule = ARROW_REGISTER_FILESYSTEM(
"example",
[](const Uri& uri, const io::IOContext& io_context,
std::string* out_path) -> Result<std::shared_ptr<FileSystem>> {
@@ -33,6 +33,6 @@ FileSystemRegistrar kExampleFileSystemModule{
auto local_uri = "file" + uri.ToString().substr(kScheme.size());
return FileSystemFromUri(local_uri, io_context, out_path);
},
-};
+ {});
} // namespace arrow::fs
diff --git a/docs/source/cpp/io.rst b/docs/source/cpp/io.rst
index 2a05473852..2312132b1a 100644
--- a/docs/source/cpp/io.rst
+++ b/docs/source/cpp/io.rst
@@ -116,15 +116,15 @@ scope, which will register a factory whenever the
instance is loaded:
.. code-block:: cpp
- arrow::fs::FileSystemRegistrar kExampleFileSystemModule{
+ auto kExampleFileSystemModule = ARROW_REGISTER_FILESYSTEM(
"example",
[](const Uri& uri, const io::IOContext& io_context,
std::string* out_path) ->
Result<std::shared_ptr<arrow::fs::FileSystem>> {
EnsureExampleFileSystemInitialized();
return std::make_shared<ExampleFileSystem>();
},
- &EnsureExampleFileSystemFinalized,
- };
+ &EnsureExampleFileSystemFinalized
+ );
If a filesystem implementation requires initialization before any instances
may be constructed, this should be included in the corresponding factory or
@@ -144,4 +144,3 @@ should have exactly one of its sources
``#include "arrow/filesystem/filesystem_library.h"``
in order to ensure the presence of the symbol on which
:func:`~arrow::fs::LoadFileSystemFactories` depends.
-
diff --git a/python/pyarrow/_fs.pxd b/python/pyarrow/_fs.pxd
index 4504b78b83..0df75530bb 100644
--- a/python/pyarrow/_fs.pxd
+++ b/python/pyarrow/_fs.pxd
@@ -67,9 +67,6 @@ cdef class FileSystem(_Weakrefable):
cdef class LocalFileSystem(FileSystem):
- cdef:
- CLocalFileSystem* localfs
-
cdef init(self, const shared_ptr[CFileSystem]& wrapped)
diff --git a/python/pyarrow/_fs.pyx b/python/pyarrow/_fs.pyx
index 86cf39e993..0e635b2c8a 100644
--- a/python/pyarrow/_fs.pyx
+++ b/python/pyarrow/_fs.pyx
@@ -18,7 +18,6 @@
# cython: language_level = 3
from cpython.datetime cimport datetime, PyDateTime_DateTime
-from cython cimport binding
from pyarrow.includes.common cimport *
from pyarrow.includes.libarrow_python cimport PyDateTime_to_TimePoint
@@ -421,6 +420,11 @@ cdef class FileSystem(_Weakrefable):
"the subclasses instead: LocalFileSystem or "
"SubTreeFileSystem")
+ @staticmethod
+ def _from_uri(uri):
+ fs, _path = FileSystem.from_uri(uri)
+ return fs
+
@staticmethod
def from_uri(uri):
"""
@@ -1097,30 +1101,18 @@ cdef class LocalFileSystem(FileSystem):
def __init__(self, *, use_mmap=False):
cdef:
- CLocalFileSystemOptions opts
- shared_ptr[CLocalFileSystem] fs
-
- opts = CLocalFileSystemOptions.Defaults()
- opts.use_mmap = use_mmap
+ shared_ptr[CFileSystem] fs
+ c_string c_uri
- fs = make_shared[CLocalFileSystem](opts)
+ # from_uri needs a non-empty path, so just use a placeholder of /_
+ c_uri = tobytes(f"file:///_?use_mmap={int(use_mmap)}")
+ with nogil:
+ fs = GetResultValue(CFileSystemFromUri(c_uri))
self.init(<shared_ptr[CFileSystem]> fs)
- cdef init(self, const shared_ptr[CFileSystem]& c_fs):
- FileSystem.init(self, c_fs)
- self.localfs = <CLocalFileSystem*> c_fs.get()
-
- @staticmethod
- @binding(True) # Required for cython < 3
- def _reconstruct(kwargs):
- # __reduce__ doesn't allow passing named arguments directly to the
- # reconstructor, hence this wrapper.
- return LocalFileSystem(**kwargs)
-
def __reduce__(self):
- cdef CLocalFileSystemOptions opts = self.localfs.options()
- return LocalFileSystem._reconstruct, (dict(
- use_mmap=opts.use_mmap),)
+ uri = frombytes(GetResultValue(self.fs.MakeUri(b"/_")))
+ return FileSystem._from_uri, (uri,)
cdef class SubTreeFileSystem(FileSystem):
diff --git a/python/pyarrow/includes/libarrow_fs.pxd
b/python/pyarrow/includes/libarrow_fs.pxd
index 328b426a49..f1f2985f65 100644
--- a/python/pyarrow/includes/libarrow_fs.pxd
+++ b/python/pyarrow/includes/libarrow_fs.pxd
@@ -61,6 +61,7 @@ cdef extern from "arrow/filesystem/api.h" namespace
"arrow::fs" nogil:
shared_ptr[CFileSystem] shared_from_this()
c_string type_name() const
CResult[c_string] NormalizePath(c_string path)
+ CResult[c_string] MakeUri(c_string path)
CResult[CFileInfo] GetFileInfo(const c_string& path)
CResult[vector[CFileInfo]] GetFileInfo(
const vector[c_string]& paths)
@@ -84,6 +85,8 @@ cdef extern from "arrow/filesystem/api.h" namespace
"arrow::fs" nogil:
c_bool Equals(const CFileSystem& other)
c_bool Equals(shared_ptr[CFileSystem] other)
+ CResult[shared_ptr[CFileSystem]] CFileSystemFromUri \
+ "arrow::fs::FileSystemFromUri"(const c_string& uri)
CResult[shared_ptr[CFileSystem]] CFileSystemFromUri \
"arrow::fs::FileSystemFromUri"(const c_string& uri, c_string* out_path)
CResult[shared_ptr[CFileSystem]] CFileSystemFromUriOrPath \
@@ -98,19 +101,6 @@ cdef extern from "arrow/filesystem/api.h" namespace
"arrow::fs" nogil:
CStatus CFileSystemsInitialize "arrow::fs::Initialize" \
(const CFileSystemGlobalOptions& options)
- cdef cppclass CLocalFileSystemOptions "arrow::fs::LocalFileSystemOptions":
- c_bool use_mmap
-
- @staticmethod
- CLocalFileSystemOptions Defaults()
-
- c_bool Equals(const CLocalFileSystemOptions& other)
-
- cdef cppclass CLocalFileSystem "arrow::fs::LocalFileSystem"(CFileSystem):
- CLocalFileSystem()
- CLocalFileSystem(CLocalFileSystemOptions)
- CLocalFileSystemOptions options()
-
cdef cppclass CSubTreeFileSystem \
"arrow::fs::SubTreeFileSystem"(CFileSystem):
CSubTreeFileSystem(const c_string& base_path,
diff --git a/r/R/arrowExports.R b/r/R/arrowExports.R
index 967caba727..752d3a266b 100644
--- a/r/R/arrowExports.R
+++ b/r/R/arrowExports.R
@@ -1352,10 +1352,6 @@ fs___FileSystem__type_name <- function(file_system) {
.Call(`_arrow_fs___FileSystem__type_name`, file_system)
}
-fs___LocalFileSystem__create <- function() {
- .Call(`_arrow_fs___LocalFileSystem__create`)
-}
-
fs___SubTreeFileSystem__create <- function(base_path, base_fs) {
.Call(`_arrow_fs___SubTreeFileSystem__create`, base_path, base_fs)
}
diff --git a/r/R/filesystem.R b/r/R/filesystem.R
index 0e4484d1b5..0176cdf846 100644
--- a/r/R/filesystem.R
+++ b/r/R/filesystem.R
@@ -390,7 +390,8 @@ are_urls <- function(x) if (!is.character(x)) FALSE else
grepl("://", x)
#' @export
LocalFileSystem <- R6Class("LocalFileSystem", inherit = FileSystem)
LocalFileSystem$create <- function() {
- fs___LocalFileSystem__create()
+ # from_uri needs a non-empty path, so just use a placeholder of /_
+ FileSystem$from_uri("file:///_")$fs
}
#' @usage NULL
diff --git a/r/src/arrowExports.cpp b/r/src/arrowExports.cpp
index 5031c79f20..a4c4b614d6 100644
--- a/r/src/arrowExports.cpp
+++ b/r/src/arrowExports.cpp
@@ -3472,13 +3472,6 @@ BEGIN_CPP11
END_CPP11
}
// filesystem.cpp
-std::shared_ptr<fs::LocalFileSystem> fs___LocalFileSystem__create();
-extern "C" SEXP _arrow_fs___LocalFileSystem__create(){
-BEGIN_CPP11
- return cpp11::as_sexp(fs___LocalFileSystem__create());
-END_CPP11
-}
-// filesystem.cpp
std::shared_ptr<fs::SubTreeFileSystem> fs___SubTreeFileSystem__create(const
std::string& base_path, const std::shared_ptr<fs::FileSystem>& base_fs);
extern "C" SEXP _arrow_fs___SubTreeFileSystem__create(SEXP base_path_sexp,
SEXP base_fs_sexp){
BEGIN_CPP11
@@ -6014,7 +6007,6 @@ static const R_CallMethodDef CallEntries[] = {
{ "_arrow_fs___FileSystem__OpenOutputStream", (DL_FUNC)
&_arrow_fs___FileSystem__OpenOutputStream, 2},
{ "_arrow_fs___FileSystem__OpenAppendStream", (DL_FUNC)
&_arrow_fs___FileSystem__OpenAppendStream, 2},
{ "_arrow_fs___FileSystem__type_name", (DL_FUNC)
&_arrow_fs___FileSystem__type_name, 1},
- { "_arrow_fs___LocalFileSystem__create", (DL_FUNC)
&_arrow_fs___LocalFileSystem__create, 0},
{ "_arrow_fs___SubTreeFileSystem__create", (DL_FUNC)
&_arrow_fs___SubTreeFileSystem__create, 2},
{ "_arrow_fs___SubTreeFileSystem__base_fs", (DL_FUNC)
&_arrow_fs___SubTreeFileSystem__base_fs, 1},
{ "_arrow_fs___SubTreeFileSystem__base_path", (DL_FUNC)
&_arrow_fs___SubTreeFileSystem__base_path, 1},
diff --git a/r/src/filesystem.cpp b/r/src/filesystem.cpp
index 23bcb81e8f..2274a3d7ff 100644
--- a/r/src/filesystem.cpp
+++ b/r/src/filesystem.cpp
@@ -238,13 +238,6 @@ std::string fs___FileSystem__type_name(
return file_system->type_name();
}
-// [[arrow::export]]
-std::shared_ptr<fs::LocalFileSystem> fs___LocalFileSystem__create() {
- // Affects OpenInputFile/OpenInputStream
- auto io_context = MainRThread::GetInstance().CancellableIOContext();
- return std::make_shared<fs::LocalFileSystem>(io_context);
-}
-
// [[arrow::export]]
std::shared_ptr<fs::SubTreeFileSystem> fs___SubTreeFileSystem__create(
const std::string& base_path, const std::shared_ptr<fs::FileSystem>&
base_fs) {
@@ -268,9 +261,10 @@ cpp11::writable::list fs___FileSystemFromUri(const
std::string& path) {
using cpp11::literals::operator"" _nm;
std::string out_path;
- return cpp11::writable::list(
- {"fs"_nm = cpp11::to_r6(ValueOrStop(fs::FileSystemFromUri(path,
&out_path))),
- "path"_nm = out_path});
+ auto io_context = MainRThread::GetInstance().CancellableIOContext();
+ return cpp11::writable::list({"fs"_nm = cpp11::to_r6(ValueOrStop(
+ fs::FileSystemFromUri(path, io_context,
&out_path))),
+ "path"_nm = out_path});
}
// [[arrow::export]]