mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-09 04:19:10 -04:00
metadata_v2: better view classes
This commit is contained in:
parent
00af55de55
commit
d052217f59
@ -25,12 +25,17 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boost/range/irange.hpp>
|
||||
|
||||
#include <thrift/lib/cpp2/frozen/FrozenUtil.h>
|
||||
|
||||
#include "fstypes.h"
|
||||
#include "logger.h"
|
||||
|
||||
@ -38,9 +43,33 @@
|
||||
|
||||
namespace dwarfs {
|
||||
|
||||
using entry_view = ::apache::thrift::frozen::View<thrift::metadata::entry>;
|
||||
using directory_view =
|
||||
::apache::thrift::frozen::View<thrift::metadata::directory>;
|
||||
class entry_view
|
||||
: public ::apache::thrift::frozen::View<thrift::metadata::entry> {
|
||||
public:
|
||||
entry_view(
|
||||
::apache::thrift::frozen::View<thrift::metadata::entry> ev,
|
||||
::apache::thrift::frozen::MappedFrozen<thrift::metadata::metadata> const*
|
||||
meta)
|
||||
: ::apache::thrift::frozen::View<thrift::metadata::entry>(ev)
|
||||
, meta_(meta) {}
|
||||
|
||||
std::string_view name() const;
|
||||
uint16_t mode() const;
|
||||
// size_t size() const;
|
||||
|
||||
private:
|
||||
::apache::thrift::frozen::MappedFrozen<thrift::metadata::metadata> const*
|
||||
meta_;
|
||||
};
|
||||
|
||||
class directory_view
|
||||
: public ::apache::thrift::frozen::View<thrift::metadata::directory> {
|
||||
public:
|
||||
directory_view(::apache::thrift::frozen::View<thrift::metadata::directory> dv)
|
||||
: ::apache::thrift::frozen::View<thrift::metadata::directory>(dv) {}
|
||||
|
||||
boost::integer_range<uint32_t> entry_range() const;
|
||||
};
|
||||
|
||||
class metadata_v2 {
|
||||
public:
|
||||
|
@ -227,12 +227,12 @@ void entry::update(global_entry_data& data) const {
|
||||
void entry::pack(thrift::metadata::entry& entry_v2,
|
||||
global_entry_data const& data) const {
|
||||
entry_v2.name_index = has_parent() ? data.get_name_index(name_) : 0;
|
||||
entry_v2.mode = data.get_mode_index(stat_.st_mode & 0xFFFF);
|
||||
entry_v2.owner = data.get_uid_index(stat_.st_uid);
|
||||
entry_v2.group = data.get_gid_index(stat_.st_gid);
|
||||
entry_v2.atime = data.get_time_offset(stat_.st_atime);
|
||||
entry_v2.mtime = data.get_time_offset(stat_.st_mtime);
|
||||
entry_v2.ctime = data.get_time_offset(stat_.st_ctime);
|
||||
entry_v2.mode_index = data.get_mode_index(stat_.st_mode & 0xFFFF);
|
||||
entry_v2.owner_index = data.get_uid_index(stat_.st_uid);
|
||||
entry_v2.group_index = data.get_gid_index(stat_.st_gid);
|
||||
entry_v2.atime_offset = data.get_time_offset(stat_.st_atime);
|
||||
entry_v2.mtime_offset = data.get_time_offset(stat_.st_mtime);
|
||||
entry_v2.ctime_offset = data.get_time_offset(stat_.st_ctime);
|
||||
entry_v2.inode = inode_num();
|
||||
}
|
||||
|
||||
|
@ -25,14 +25,9 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <boost/range/irange.hpp>
|
||||
|
||||
#include "dwarfs/metadata_v2.h"
|
||||
|
||||
#include "dwarfs/gen-cpp2/metadata_layouts.h"
|
||||
#include "dwarfs/gen-cpp2/metadata_types.h"
|
||||
#include "dwarfs/gen-cpp2/metadata_types_custom_protocol.h"
|
||||
#include <thrift/lib/cpp2/frozen/FrozenUtil.h>
|
||||
#include <thrift/lib/cpp2/protocol/DebugProtocol.h>
|
||||
#include <thrift/lib/thrift/gen-cpp2/frozen_types_custom_protocol.h>
|
||||
|
||||
@ -44,6 +39,17 @@ const uint16_t READ_ONLY_MASK = ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
|
||||
}
|
||||
|
||||
std::string_view entry_view::name() const {
|
||||
return meta_->names()[name_index()];
|
||||
}
|
||||
|
||||
uint16_t entry_view::mode() const { return meta_->modes()[mode_index()]; }
|
||||
|
||||
boost::integer_range<uint32_t> directory_view::entry_range() const {
|
||||
auto first = first_entry();
|
||||
return boost::irange(first, first + entry_count());
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
class metadata_v2_ : public metadata_v2::impl {
|
||||
public:
|
||||
@ -54,7 +60,7 @@ class metadata_v2_ : public metadata_v2::impl {
|
||||
: data_(std::move(meta))
|
||||
, meta_(::apache::thrift::frozen::mapFrozen<thrift::metadata::metadata>(
|
||||
data_))
|
||||
, root_(meta_.entries()[meta_.entry_index()[0]])
|
||||
, root_(meta_.entries()[meta_.entry_index()[0]], &meta_)
|
||||
, inode_offset_(inode_offset)
|
||||
, chunk_index_offset_(meta_.chunk_index_offset())
|
||||
, log_(lgr) {
|
||||
@ -108,6 +114,14 @@ class metadata_v2_ : public metadata_v2::impl {
|
||||
#endif
|
||||
|
||||
private:
|
||||
entry_view make_entry_view(size_t index) const {
|
||||
return entry_view(meta_.entries()[index], &meta_);
|
||||
}
|
||||
|
||||
directory_view make_directory_view(size_t index) const {
|
||||
return directory_view(meta_.directories()[index]);
|
||||
}
|
||||
|
||||
void dump(std::ostream& os, const std::string& indent, entry_view entry,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const;
|
||||
void dump(std::ostream& os, const std::string& indent, directory_view dir,
|
||||
@ -141,7 +155,7 @@ class metadata_v2_ : public metadata_v2::impl {
|
||||
}
|
||||
|
||||
directory_view getdir(entry_view entry) const {
|
||||
return meta_.directories()[entry.inode()];
|
||||
return make_directory_view(entry.inode());
|
||||
}
|
||||
|
||||
void
|
||||
@ -151,19 +165,11 @@ class metadata_v2_ : public metadata_v2::impl {
|
||||
inode -= inode_offset_;
|
||||
std::optional<entry_view> rv;
|
||||
if (inode >= 0 && inode < int(meta_.entry_index().size())) {
|
||||
rv = meta_.entries()[meta_.entry_index()[inode]];
|
||||
rv = make_entry_view(meta_.entry_index()[inode]);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint16_t entry_mode(entry_view entry) const {
|
||||
return meta_.modes()[entry.mode()];
|
||||
}
|
||||
|
||||
std::string_view entry_name(entry_view entry) const {
|
||||
return meta_.names()[entry.name_index()];
|
||||
}
|
||||
|
||||
std::string_view link_name(entry_view entry) const {
|
||||
return meta_
|
||||
.links()[meta_.link_index()[entry.inode()] - meta_.link_index_offset()];
|
||||
@ -187,13 +193,13 @@ template <typename LoggerPolicy>
|
||||
void metadata_v2_<LoggerPolicy>::dump(
|
||||
std::ostream& os, const std::string& indent, entry_view entry,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const {
|
||||
auto mode = entry_mode(entry);
|
||||
auto mode = entry.mode();
|
||||
auto inode = entry.inode();
|
||||
|
||||
os << indent << "<inode:" << inode << "> " << modestring(mode);
|
||||
|
||||
if (inode > 0) {
|
||||
os << " " << entry_name(entry);
|
||||
os << " " << entry.name();
|
||||
}
|
||||
|
||||
if (S_ISREG(mode)) {
|
||||
@ -203,7 +209,7 @@ void metadata_v2_<LoggerPolicy>::dump(
|
||||
os << " " << file_size(entry, mode) << "\n";
|
||||
icb(indent + " ", inode);
|
||||
} else if (S_ISDIR(mode)) {
|
||||
dump(os, indent + " ", meta_.directories()[inode], std::move(icb));
|
||||
dump(os, indent + " ", make_directory_view(inode), std::move(icb));
|
||||
} else if (S_ISLNK(mode)) {
|
||||
os << " -> " << link_name(entry) << "\n";
|
||||
} else {
|
||||
@ -220,7 +226,7 @@ void metadata_v2_<LoggerPolicy>::dump(
|
||||
os << indent << "(" << count << ") entries\n";
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
dump(os, indent, meta_.entries()[first + i], icb);
|
||||
dump(os, indent, make_entry_view(first + i), icb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,10 +264,8 @@ void metadata_v2_<LoggerPolicy>::walk(
|
||||
func(entry);
|
||||
if (S_ISDIR(entry.mode())) {
|
||||
auto dir = getdir(entry);
|
||||
auto cur = dir.first_entry();
|
||||
auto end = cur + dir.entry_count();
|
||||
while (cur < end) {
|
||||
walk(meta_.entries()[cur++], func);
|
||||
for (auto cur : dir.entry_range()) {
|
||||
walk(make_entry_view(cur), func);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,20 +280,19 @@ template <typename LoggerPolicy>
|
||||
std::optional<entry_view>
|
||||
metadata_v2_<LoggerPolicy>::find(directory_view dir,
|
||||
std::string_view name) const {
|
||||
auto first = dir.first_entry();
|
||||
auto range = boost::irange(first, first + dir.entry_count());
|
||||
auto range = dir.entry_range();
|
||||
|
||||
auto it = std::lower_bound(
|
||||
range.begin(), range.end(), name, [&](auto it, std::string_view name) {
|
||||
return entry_name(meta_.entries()[it]).compare(name);
|
||||
});
|
||||
auto it = std::lower_bound(range.begin(), range.end(), name,
|
||||
[&](auto ix, std::string_view name) {
|
||||
return make_entry_view(ix).name().compare(name);
|
||||
});
|
||||
|
||||
std::optional<entry_view> rv;
|
||||
|
||||
if (it != range.end()) {
|
||||
auto cand = meta_.entries()[*it];
|
||||
auto cand = make_entry_view(*it);
|
||||
|
||||
if (entry_name(cand) == name) {
|
||||
if (cand.name() == name) {
|
||||
rv = cand;
|
||||
}
|
||||
}
|
||||
@ -345,7 +348,7 @@ int metadata_v2_<LoggerPolicy>::getattr(entry_view entry,
|
||||
struct ::stat* stbuf) const {
|
||||
::memset(stbuf, 0, sizeof(*stbuf));
|
||||
|
||||
auto mode = entry_mode(entry);
|
||||
auto mode = entry.mode();
|
||||
|
||||
stbuf->st_mode = mode & READ_ONLY_MASK;
|
||||
stbuf->st_size = file_size(entry, mode);
|
||||
|
@ -57,7 +57,7 @@ struct entry {
|
||||
1: required UInt32 name_index,
|
||||
|
||||
// index into metadata.modes
|
||||
2: required UInt16 mode,
|
||||
2: required UInt16 mode_index,
|
||||
|
||||
/**
|
||||
* Inode number. Can be used in different ways:
|
||||
@ -72,19 +72,19 @@ struct entry {
|
||||
3: required UInt32 inode,
|
||||
|
||||
// index into metadata.uids
|
||||
4: required UInt16 owner,
|
||||
4: required UInt16 owner_index,
|
||||
|
||||
// index into metadata.gids
|
||||
5: required UInt16 group,
|
||||
5: required UInt16 group_index,
|
||||
|
||||
// atime relative to metadata.timestamp_base
|
||||
6: required UInt64 atime,
|
||||
6: required UInt64 atime_offset,
|
||||
|
||||
// mtime relative to metadata.timestamp_base
|
||||
7: required UInt64 mtime,
|
||||
7: required UInt64 mtime_offset,
|
||||
|
||||
// ctime relative to metadata.timestamp_base
|
||||
8: required UInt64 ctime,
|
||||
8: required UInt64 ctime_offset,
|
||||
}
|
||||
|
||||
struct metadata {
|
||||
|
Loading…
x
Reference in New Issue
Block a user