From e7b483e4b673aa6bdfa8cb95d5904071cfc38f1a Mon Sep 17 00:00:00 2001 From: "Niall Douglas (s [underscore] sourceforge {at} nedprod [dot] com)" Date: Fri, 10 Feb 2023 14:43:51 -0800 Subject: [PATCH] Add read directory example #106 --- cmake/tests.cmake | 1 + example/read_directory.cpp | 105 +++++++++++++++++++++++++++++++++++++ example/read_stats.cpp | 1 + include/llfio/revision.hpp | 6 +-- 4 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 example/read_directory.cpp diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 23fb67d5..35d5e681 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -48,6 +48,7 @@ set(llfio_COMPILE_TESTS "example/malloc2.cpp" "example/map_file.cpp" "example/mapped_file.cpp" + "example/read_directory.cpp" "example/read_entire_file1.cpp" "example/read_stats.cpp" "example/scatter_write.cpp" diff --git a/example/read_directory.cpp b/example/read_directory.cpp new file mode 100644 index 00000000..9bf195cb --- /dev/null +++ b/example/read_directory.cpp @@ -0,0 +1,105 @@ +/* Examples of LLFIO use +(C) 2018 - 2022 Niall Douglas (2 commits) +File Created: Aug 2018 + + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License in the accompanying file +Licence.txt or at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +Distributed under the Boost Software License, Version 1.0. + (See accompanying file Licence.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include "../include/llfio.hpp" + +#include +#include + +// clang-format off + +void read_directory() +{ + //! [read_directory] + namespace llfio = LLFIO_V2_NAMESPACE; + + // Open the directory for read + llfio::directory_handle dh = llfio::directory( // + {}, // path_handle to base directory + "foo" // path_view to path fragment relative to base directory + // default mode is read only + // default creation is open existing + // default caching is all + // default flags is none + ).value(); // If failed, throw a filesystem_error exception + + // Read up to ten directory_entry + std::vector buffer(10); + + // Very similar to reading from a file handle, we need + // to achieve a single snapshot read to be race free. + llfio::directory_handle::buffers_type entries(buffer); + for(;;) + { + entries = dh.read( + {std::move(entries)} // buffers to fill + ).value(); // If failed, throw a filesystem_error exception + + // If there were fewer entries in the directory than buffers + // passed in, we are done. + if(entries.done()) + { + break; + } + // Otherwise double the size of the buffer + buffer.resize(buffer.size() << 1); + // Set the next read attempt to use the newly enlarged buffer. + // buffers_type may cache internally reusable state depending + // on platform, to efficiently reuse that state pass in the + // old entries by rvalue ref. + entries = { buffer, std::move(entries) }; + } + + std::cout << "The directory " << dh.current_path().value() << " has entries:"; + for(auto &entry : entries) + { + std::cout << "\n " << entry.leafname; + // Different platforms fill in different fields of the stat_t + // in directory_entry as some fields are fillable free of cost + // during directory enumeration. What the platform provides for + // free is given by metadata(). + if(!(entries.metadata() & llfio::stat_t::want::size)) + { + llfio::file_handle fh = llfio::file( + dh, // base directory for open + entry.leafname, // leaf name within that base directory + // don't need privs above minimum to read attributes + // (this is significantly faster than opening a file + // for read on some platforms) + llfio::file_handle::mode::attr_read + ).value(); + // Do the minimum work to fill in only the st_size member + // (other fields may get also filled if it is free of cost) + entry.stat.fill(fh, llfio::stat_t::want::size).value(); + } + std::cout << " maximum extent: " << entry.stat.st_size; + } + std::cout << std::endl; + //! [read_directory] +} + +int main() +{ + return 0; +} diff --git a/example/read_stats.cpp b/example/read_stats.cpp index 962a5555..3afc98c3 100644 --- a/example/read_stats.cpp +++ b/example/read_stats.cpp @@ -25,6 +25,7 @@ Distributed under the Boost Software License, Version 1.0. #include "../include/llfio.hpp" #include +#include #include auto print = [](std::chrono::system_clock::time_point ts) diff --git a/include/llfio/revision.hpp b/include/llfio/revision.hpp index 37883cb7..2fc282ff 100644 --- a/include/llfio/revision.hpp +++ b/include/llfio/revision.hpp @@ -1,4 +1,4 @@ // Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time -#define LLFIO_PREVIOUS_COMMIT_REF 7b782ebda1e847bf18899cbb64bb13209cd77ddd -#define LLFIO_PREVIOUS_COMMIT_DATE "2023-02-09 00:46:50 +00:00" -#define LLFIO_PREVIOUS_COMMIT_UNIQUE 7b782ebd +#define LLFIO_PREVIOUS_COMMIT_REF cf9824d8cc04c6a8adf89cac02014ce02736c06f +#define LLFIO_PREVIOUS_COMMIT_DATE "2023-02-10 21:57:52 +00:00" +#define LLFIO_PREVIOUS_COMMIT_UNIQUE cf9824d8