6
6
namespace EGL3 ::Service {
7
7
using namespace Storage ;
8
8
9
- std::vector<MountedFile> GetMountFiles (const Game::ArchiveList<Game::RunlistId::File>& Files)
9
+ MountedArchive::MountedArchive (const std::filesystem::path& Path, Game::Archive&& Archive) :
10
+ Archive (std::move(Archive)),
11
+ ArchiveLists (this ->Archive),
12
+ LUT (ArchiveLists),
13
+ Disk (GetMountedFiles(), Utils::Random(), HandleCluster),
14
+ DriveLetter (0 )
10
15
{
11
- std::vector<MountedFile> MountedFiles;
12
- MountedFiles.reserve (Files.size ());
16
+ Disk.Initialize ();
13
17
14
- int Idx = 0 ;
15
- for (auto & File : Files) {
16
- MountedFiles.push_back ({
17
- .Path = File.Filename ,
18
- .FileSize = File.FileSize ,
19
- .UserContext = (void *)Idx++
20
- });
18
+ Disk.Create ();
19
+
20
+ Disk.Mount ();
21
+ }
22
+
23
+ MountedArchive::~MountedArchive ()
24
+ {
25
+ }
26
+
27
+ char MountedArchive::GetDriveLetter () const
28
+ {
29
+ if (!DriveLetter) {
30
+ DriveLetter = Disk.GetDriveLetter ();
21
31
}
32
+ return DriveLetter;
33
+ }
22
34
23
- return MountedFiles;
35
+ std::filesystem::path MountedArchive::GetArchivePath () const
36
+ {
37
+ return Archive.GetPath ();
24
38
}
25
39
26
- MountedArchive::MountedArchive (const std::filesystem::path& Path, Storage::Game::Archive&& Archive) :
27
- DriveLetter (0 ),
28
- Archive (std::move(Archive)),
29
- ArchiveLists (this ->Archive),
30
- Disk (GetMountFiles(ArchiveLists.Files), Utils::Random())
40
+ MountedArchive::Stats MountedArchive::QueryStats () const
31
41
{
32
- Disk.HandleFileCluster .Set ([this ](void * Ctx, uint64_t LCN, uint8_t Buffer[4096 ]) { HandleFileCluster (Ctx, LCN, Buffer); });
42
+ if (!Counter.IsValid ()) {
43
+ Counter = DriveCounter (GetDriveLetter ());
44
+ }
45
+ if (Counter.IsValid ()) {
46
+ return Counter.GetData ();
47
+ }
48
+ return Stats{};
49
+ }
33
50
34
- Disk.Initialize ();
51
+ MountedArchive::SectionLUT::SectionLUT (const Lists& ArchiveLists)
52
+ {
53
+ LUT.reserve (ArchiveLists.Files .size ());
35
54
36
- SectionLUT.reserve (ArchiveLists.Files .size ());
37
55
for (auto & File : ArchiveLists.Files ) {
38
- auto & Sections = SectionLUT .emplace_back ();
56
+ auto & Sections = LUT .emplace_back ();
39
57
uint32_t ClusterCount = Utils::Align<4096 >(File.FileSize ) / 4096 ;
40
58
Sections.reserve (ClusterCount);
41
59
@@ -50,70 +68,59 @@ namespace EGL3::Service {
50
68
for (uint32_t i = 0 ; i < ClusterCount; ++i) {
51
69
uint32_t BytesToSelect = std::min (4096llu, File.FileSize - i * 4096llu);
52
70
53
- Sections.emplace_back (SectionParts .size ());
71
+ Sections.emplace_back (Parts .size ());
54
72
do {
55
73
if (ItrDataOffset == Itr->Size ) {
56
74
++Itr;
57
75
ItrDataOffset = 0 ;
58
76
}
59
77
auto & ChunkPart = *Itr;
60
78
auto SectionPartSize = std::min (ChunkPart.Size - ItrDataOffset, BytesToSelect);
61
- SectionParts .emplace_back (
79
+ Parts .emplace_back (
62
80
GetDataItr (ChunkPart.ChunkIdx ) + ChunkPart.Offset + ItrDataOffset,
63
81
SectionPartSize
64
82
);
65
83
BytesToSelect -= SectionPartSize;
66
84
ItrDataOffset += SectionPartSize;
67
85
EGL3_VERIFY (ItrDataOffset <= Itr->Size , " Invalid data offset" );
68
86
} while (BytesToSelect);
69
- SectionParts .emplace_back ();
87
+ Parts .emplace_back ();
70
88
}
71
- }
72
-
73
- Disk.Create ();
74
89
75
- Disk.Mount ();
90
+ Contexts.emplace_back (Sections, Parts, ArchiveLists.ChunkDatas .begin ());
91
+ }
76
92
}
77
93
78
- MountedArchive::~MountedArchive ()
94
+ MountedArchive::SectionContext::SectionContext (const std::vector<uint32_t >& const LUT, const std::vector<SectionPart>& const Parts, const Storage::Game::ArchiveListIteratorReadonly<Storage::Game::RunlistId::ChunkData> DataBegin) :
95
+ LUT (LUT),
96
+ Parts (Parts),
97
+ DataBegin (DataBegin)
79
98
{
80
- }
81
99
82
- char MountedArchive::GetDriveLetter () const
83
- {
84
- if (!DriveLetter) {
85
- DriveLetter = Disk.GetDriveLetter ();
86
- }
87
- return DriveLetter;
88
100
}
89
101
90
- std::filesystem::path MountedArchive::GetArchivePath () const
102
+ std::vector<MountedFile> MountedArchive::GetMountedFiles ()
91
103
{
92
- return Archive. GetPath () ;
93
- }
104
+ std::vector<MountedFile> MountedFiles ;
105
+ MountedFiles. reserve (ArchiveLists. Files . size ());
94
106
95
- MountedArchive::Stats MountedArchive::QueryStats () const
96
- {
97
- if (!Counter. IsValid ()) {
98
- Counter = DriveCounter ( GetDriveLetter ());
99
- }
100
- if (Counter. IsValid ()) {
101
- return Counter. GetData ( );
107
+ size_t Idx = 0 ;
108
+ for ( auto & File : ArchiveLists. Files ) {
109
+ MountedFiles. push_back ( {
110
+ . Path = File. Filename ,
111
+ . FileSize = File. FileSize ,
112
+ . UserContext = ( void *)&LUT. Contexts [Idx++]
113
+ } );
102
114
}
103
- return Stats{};
104
- }
105
115
106
- void MountedArchive::HandleFileCluster (void * Ctx, uint64_t LCN, uint8_t Buffer[4096 ]) const noexcept
107
- {
108
- auto & File = SectionLUT[(size_t )Ctx];
116
+ return MountedFiles;
117
+ }
109
118
110
- if (File.size () < LCN) [[unlikely]] {
111
- ZeroMemory (Buffer, 4096 );
112
- return ;
113
- }
119
+ void MountedArchive::HandleCluster (void * CtxPtr, uint64_t LCN, uint8_t Buffer[4096 ]) noexcept {
120
+ auto & Ctx = *(MountedArchive::SectionContext*)CtxPtr;
114
121
115
- for (auto Itr = SectionParts. begin () + File [LCN]; Itr->IsValid (); ++Itr) {
116
- auto Ptr = ArchiveLists. ChunkDatas . begin () + Itr->GetPtr ();
122
+ for (auto Itr = Ctx. Parts . begin () + Ctx. LUT [LCN]; Itr->IsValid (); ++Itr) {
123
+ auto Ptr = Ctx. DataBegin + Itr->GetPtr ();
117
124
Ptr .FastCopy ((char *)Buffer, Itr->GetSize ());
118
125
Buffer = (uint8_t *)Buffer + Itr->GetSize ();
119
126
}
0 commit comments