Skip to content

Commit 271ab2e

Browse files
committed
Merge branch 'dont-ask-the-disk-for-things-we-already-know' into 'master'
Avoid IO in resolveParentFileIndices See merge request OpenMW/openmw!4627
2 parents 583620e + 31fcc5e commit 271ab2e

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

apps/components_tests/esm3/readerscache.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,31 @@ namespace
8888
EXPECT_EQ(reader->getFileOffset(), sInitialOffset);
8989
}
9090
}
91+
92+
TEST_F(ESM3ReadersCacheWithContentFile, CachedSizeAndName)
93+
{
94+
ESM::ReadersCache readers(2);
95+
{
96+
readers.get(0)->openRaw(std::make_unique<std::istringstream>("123"), "closed0.omwaddon");
97+
readers.get(1)->openRaw(std::make_unique<std::istringstream>("12345"), "closed1.omwaddon");
98+
readers.get(2)->openRaw(std::make_unique<std::istringstream>("1234567"), "free.omwaddon");
99+
}
100+
auto busy = readers.get(3);
101+
busy->openRaw(std::make_unique<std::istringstream>("123456789"), "busy.omwaddon");
102+
103+
EXPECT_EQ(readers.getFileSize(0), 3);
104+
EXPECT_EQ(readers.getName(0), "closed0.omwaddon");
105+
106+
EXPECT_EQ(readers.getFileSize(1), 5);
107+
EXPECT_EQ(readers.getName(1), "closed1.omwaddon");
108+
109+
EXPECT_EQ(readers.getFileSize(2), 7);
110+
EXPECT_EQ(readers.getName(2), "free.omwaddon");
111+
112+
EXPECT_EQ(readers.getFileSize(3), 9);
113+
EXPECT_EQ(readers.getName(3), "busy.omwaddon");
114+
115+
// not-yet-seen indices give zero for their size
116+
EXPECT_EQ(readers.getFileSize(4), 0);
117+
}
91118
}

components/esm3/esmreader.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ namespace ESM
7373
int index = getIndex();
7474
for (int i = 0; i < getIndex(); i++)
7575
{
76-
const ESM::ReadersCache::BusyItem reader = readers.get(static_cast<std::size_t>(i));
77-
if (reader->getFileSize() == 0)
76+
if (readers.getFileSize(static_cast<std::size_t>(i)) == 0)
7877
continue; // Content file in non-ESM format
79-
const auto fnamecandidate = Files::pathToUnicodeString(reader->getName().filename());
78+
const auto fnamecandidate
79+
= Files::pathToUnicodeString(readers.getName(static_cast<std::size_t>(i)).filename());
8080
if (Misc::StringUtils::ciEqual(fname, fnamecandidate))
8181
{
8282
index = i;

components/esm3/readerscache.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ namespace ESM
4747
{
4848
it->mReader.open(*it->mName);
4949
it->mName.reset();
50+
it->mFileSize.reset();
5051
}
5152
mBusyItems.splice(mBusyItems.end(), mClosedItems, it);
5253
break;
@@ -57,6 +58,46 @@ namespace ESM
5758
return BusyItem(*this, it);
5859
}
5960

61+
const std::filesystem::path& ReadersCache::getName(std::size_t index) const
62+
{
63+
const auto indexIt = mIndex.find(index);
64+
if (indexIt == mIndex.end())
65+
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has not been created yet");
66+
switch (indexIt->second->mState)
67+
{
68+
case State::Busy:
69+
case State::Free:
70+
return indexIt->second->mReader.getName();
71+
case State::Closed:
72+
if (indexIt->second->mName)
73+
return *indexIt->second->mName;
74+
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has forgotten its filename");
75+
default:
76+
throw std::logic_error("ESMReader at index " + std::to_string(index) + " in unknown state");
77+
}
78+
}
79+
80+
std::size_t ReadersCache::getFileSize(std::size_t index)
81+
{
82+
const auto indexIt = mIndex.find(index);
83+
if (indexIt == mIndex.end())
84+
return 0;
85+
switch (indexIt->second->mState)
86+
{
87+
case State::Busy:
88+
case State::Free:
89+
if (!indexIt->second->mReader.getName().empty())
90+
return indexIt->second->mReader.getFileSize();
91+
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has not been opened yet");
92+
case State::Closed:
93+
if (indexIt->second->mFileSize)
94+
return *indexIt->second->mFileSize;
95+
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has forgotten its file size");
96+
default:
97+
throw std::logic_error("ESMReader at index " + std::to_string(index) + " in unknown state");
98+
}
99+
}
100+
60101
void ReadersCache::closeExtraReaders()
61102
{
62103
while (!mFreeItems.empty() && mBusyItems.size() + mFreeItems.size() + 1 > mCapacity)
@@ -65,6 +106,7 @@ namespace ESM
65106
if (it->mReader.isOpen())
66107
{
67108
it->mName = it->mReader.getName();
109+
it->mFileSize = it->mReader.getFileSize();
68110
it->mReader.close();
69111
}
70112
mClosedItems.splice(mClosedItems.end(), mFreeItems, it);

components/esm3/readerscache.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace ESM
2626
State mState = State::Busy;
2727
ESMReader mReader;
2828
std::optional<std::filesystem::path> mName;
29+
std::optional<std::size_t> mFileSize;
2930

3031
Item() = default;
3132
};
@@ -55,6 +56,10 @@ namespace ESM
5556

5657
BusyItem get(std::size_t index);
5758

59+
const std::filesystem::path& getName(std::size_t index) const;
60+
61+
std::size_t getFileSize(std::size_t index);
62+
5863
void clear();
5964

6065
private:

0 commit comments

Comments
 (0)