Skip to content

Commit 7709a8c

Browse files
committed
Changing things in File Archive class
1 parent ba669f7 commit 7709a8c

File tree

3 files changed

+70
-66
lines changed

3 files changed

+70
-66
lines changed

include/nbl/system/IFileArchive.h

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,41 +33,64 @@ class IFileArchive : public core::IReferenceCounted
3333
EAT_MALLOC // decompress to RAM
3434
};
3535
//! An entry in a list of items, can be a folder or a file.
36-
struct SListEntry
36+
struct SFileList
3737
{
38-
//! The name of the file including the path relative to archive root
39-
system::path pathRelativeToArchive;
40-
41-
//! The size of the file in bytes
42-
size_t size;
43-
44-
//! FileOffset inside an archive
45-
size_t offset;
46-
47-
//! The ID of the file in an archive, it maps it to a memory pool entry for CFileView
48-
uint32_t ID;
49-
50-
// `EAT_NONE` for directories
51-
E_ALLOCATOR_TYPE allocatorType;
52-
53-
//! The == operator is provided so that CFileList can slowly search the list!
54-
inline bool operator==(const struct SListEntry& other) const
55-
{
56-
return pathRelativeToArchive.string()==other.pathRelativeToArchive.string();
57-
}
58-
59-
//! The < operator is provided so that CFileList can sort and quickly search the list.
60-
inline bool operator<(const struct SListEntry& other) const
38+
struct SEntry
6139
{
62-
return pathRelativeToArchive<other.pathRelativeToArchive;
63-
}
40+
//same stuff as `SListEntry` right now
41+
//! The name of the file including the path relative to archive root
42+
system::path pathRelativeToArchive;
43+
44+
//! The size of the file in bytes
45+
size_t size;
46+
47+
//! FileOffset inside an archive
48+
size_t offset;
49+
50+
//! The ID of the file in an archive, it maps it to a memory pool entry for CFileView
51+
uint32_t ID;
52+
53+
// `EAT_NONE` for directories
54+
IFileArchive::E_ALLOCATOR_TYPE allocatorType;
55+
56+
//! The == operator is provided so that CFileList can slowly search the list!
57+
inline bool operator==(const struct SEntry& other) const
58+
{
59+
return pathRelativeToArchive.string() == other.pathRelativeToArchive.string();
60+
}
61+
62+
//! The < operator is provided so that CFileList can sort and quickly search the list.
63+
inline bool operator<(const struct SEntry& other) const
64+
{
65+
return pathRelativeToArchive < other.pathRelativeToArchive;
66+
}
67+
};
68+
using refctd_storage_t = std::shared_ptr<const std::vector<SEntry>>;
69+
using range_t = core::SRange<const SEntry>;
70+
71+
inline operator range_t() const { return m_range; }
72+
73+
SFileList(const SFileList&) = default;
74+
SFileList(SFileList&&) = default;
75+
SFileList& operator=(const SFileList&) = default;
76+
SFileList& operator=(SFileList&&) = default;
77+
78+
private:
79+
// default ctor full range
80+
SFileList(refctd_storage_t _data) : m_data(_data), m_range({ _data->data(),_data->data() + _data->size() }) {}
81+
82+
friend class IFileArchive;
83+
refctd_storage_t m_data;
84+
range_t m_range;
6485
};
6586

6687
//
67-
virtual core::SRange<const SListEntry> listAssets() const {return {m_items.data(),m_items.data()+m_items.size()};}
88+
virtual inline SFileList listAssets() const {
89+
return { m_items.load() };
90+
}
6891

6992
// List all files and directories in a specific dir of the archive
70-
virtual core::SRange<const SListEntry> listAssets(const path& asset_path) const;
93+
virtual SFileList listAssets(const path& pathRelativeToArchive) const;
7194

7295
//
7396
virtual core::smart_refctd_ptr<IFile> getFile(const path& pathRelativeToArchive, const std::string_view& password) = 0;
@@ -79,19 +102,20 @@ class IFileArchive : public core::IReferenceCounted
79102
IFileArchive(path&& _defaultAbsolutePath, system::logger_opt_smart_ptr&& logger) :
80103
m_defaultAbsolutePath(std::move(_defaultAbsolutePath)), m_logger(std::move(logger)) {}
81104

82-
inline const SListEntry* getItemFromPath(const system::path& pathRelativeToArchive) const
105+
inline const SFileList::SEntry* getItemFromPath(const system::path& pathRelativeToArchive) const
83106
{
84-
const IFileArchive::SListEntry itemToFind = { pathRelativeToArchive };
85-
const auto found = std::lower_bound(m_items.begin(),m_items.end(),itemToFind);
86-
if (found==m_items.end() || found->pathRelativeToArchive!=pathRelativeToArchive)
107+
const SFileList::SEntry itemToFind = { pathRelativeToArchive };
108+
auto items = m_items.load();
109+
const auto found = std::lower_bound(items->begin(), items->end(),itemToFind);
110+
if (found== items->end() || found->pathRelativeToArchive != pathRelativeToArchive)
87111
return nullptr;
88112
return &(*found);
89113
}
90114

91115
mutable std::mutex itemMutex; // TODO: update to readers writer lock
92116
path m_defaultAbsolutePath;
93117
// files and directories
94-
mutable core::vector<SListEntry> m_items;
118+
mutable std::atomic<SFileList::refctd_storage_t> m_items;
95119
//
96120
system::logger_opt_smart_ptr m_logger;
97121
};

src/nbl/system/CMountDirectoryArchive.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,29 @@ class CMountDirectoryArchive : public IFileArchive
3030
return *file;
3131
}
3232

33-
core::SRange<const IFileArchive::SListEntry> listAssets(const path& asset_path) const override
33+
SFileList listAssets(const path& asset_path) const override
3434
{
3535
populateItemList(asset_path);
3636
return IFileArchive::listAssets(asset_path);
3737
}
38-
virtual core::SRange<const SListEntry> listAssets() const override {
38+
SFileList listAssets() const override {
3939
populateItemList(path());
4040
return IFileArchive::listAssets();
4141
}
4242

4343
void populateItemList(const path& p) const {
44-
std::unique_lock lock(itemMutex);
4544
auto items = m_system->listItemsInDirectory(m_defaultAbsolutePath/p);
46-
m_items.clear();
47-
45+
auto new_entries = std::make_shared< std::vector<SFileList::SEntry>>();
4846
for (auto item : items)
4947
{
5048
if (item.has_extension())
5149
{
5250
auto relpath = item.lexically_relative(m_defaultAbsolutePath);
53-
auto entry = SListEntry{ relpath, 0xdeadbeefu, 0xdeadbeefu, 0xdeadbeefu, EAT_NONE };
54-
m_items.push_back(entry);
51+
auto entry = SFileList::SEntry{ relpath, 0xdeadbeefu, 0xdeadbeefu, 0xdeadbeefu, EAT_NONE };
52+
new_entries->push_back(entry);
5553
}
5654
}
57-
lock.unlock();
55+
m_items.store({new_entries});
5856
}
5957
};
6058

src/nbl/system/IFileArchive.cpp

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,17 @@ using namespace nbl;
66
using namespace nbl::system;
77

88

9-
core::SRange<const IFileArchive::SListEntry> IFileArchive::listAssets(const path& asset_path) const
9+
IFileArchive::SFileList IFileArchive::listAssets(const path& pathRelativeToArchive) const
1010
{
11-
// TODO: use something from ISystem for this?
12-
constexpr auto isSubDir = [](path p, path root) -> bool
13-
{
14-
while (p != path())
11+
auto trimmedList = listAssets();
1512
{
16-
if (p==root)
17-
return true;
18-
p = p.parent_path();
13+
auto begin = trimmedList.m_data->begin();
14+
auto end = trimmedList.m_data->end();
15+
const SFileList::SEntry itemToFind = { pathRelativeToArchive };
16+
trimmedList.m_range = { &(*std::lower_bound(begin,end,itemToFind)),&(*std::upper_bound(begin,end,itemToFind)) };
1917
}
20-
return false;
21-
};
18+
return trimmedList;
2219

23-
const IFileArchive::SListEntry* begin = nullptr;
24-
const IFileArchive::SListEntry* end = nullptr;
25-
for (auto& entry : m_items)
26-
{
27-
if (isSubDir(entry.pathRelativeToArchive, asset_path))
28-
{
29-
if (begin)
30-
end = &entry;
31-
else
32-
begin = &entry;
33-
}
34-
else if (end)
35-
break;
36-
}
37-
return {begin,end};
3820

3921
/*
4022
// future, cause lower/upper bound don't work like that

0 commit comments

Comments
 (0)