mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 12:58:00 +03:00
Merge branch 'dont-ask-the-disk-for-things-we-already-know' into 'master'
Avoid IO in resolveParentFileIndices See merge request OpenMW/openmw!4627
This commit is contained in:
commit
271ab2e109
4 changed files with 77 additions and 3 deletions
|
@ -88,4 +88,31 @@ namespace
|
||||||
EXPECT_EQ(reader->getFileOffset(), sInitialOffset);
|
EXPECT_EQ(reader->getFileOffset(), sInitialOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ESM3ReadersCacheWithContentFile, CachedSizeAndName)
|
||||||
|
{
|
||||||
|
ESM::ReadersCache readers(2);
|
||||||
|
{
|
||||||
|
readers.get(0)->openRaw(std::make_unique<std::istringstream>("123"), "closed0.omwaddon");
|
||||||
|
readers.get(1)->openRaw(std::make_unique<std::istringstream>("12345"), "closed1.omwaddon");
|
||||||
|
readers.get(2)->openRaw(std::make_unique<std::istringstream>("1234567"), "free.omwaddon");
|
||||||
|
}
|
||||||
|
auto busy = readers.get(3);
|
||||||
|
busy->openRaw(std::make_unique<std::istringstream>("123456789"), "busy.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(0), 3);
|
||||||
|
EXPECT_EQ(readers.getName(0), "closed0.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(1), 5);
|
||||||
|
EXPECT_EQ(readers.getName(1), "closed1.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(2), 7);
|
||||||
|
EXPECT_EQ(readers.getName(2), "free.omwaddon");
|
||||||
|
|
||||||
|
EXPECT_EQ(readers.getFileSize(3), 9);
|
||||||
|
EXPECT_EQ(readers.getName(3), "busy.omwaddon");
|
||||||
|
|
||||||
|
// not-yet-seen indices give zero for their size
|
||||||
|
EXPECT_EQ(readers.getFileSize(4), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,10 +73,10 @@ namespace ESM
|
||||||
int index = getIndex();
|
int index = getIndex();
|
||||||
for (int i = 0; i < getIndex(); i++)
|
for (int i = 0; i < getIndex(); i++)
|
||||||
{
|
{
|
||||||
const ESM::ReadersCache::BusyItem reader = readers.get(static_cast<std::size_t>(i));
|
if (readers.getFileSize(static_cast<std::size_t>(i)) == 0)
|
||||||
if (reader->getFileSize() == 0)
|
|
||||||
continue; // Content file in non-ESM format
|
continue; // Content file in non-ESM format
|
||||||
const auto fnamecandidate = Files::pathToUnicodeString(reader->getName().filename());
|
const auto fnamecandidate
|
||||||
|
= Files::pathToUnicodeString(readers.getName(static_cast<std::size_t>(i)).filename());
|
||||||
if (Misc::StringUtils::ciEqual(fname, fnamecandidate))
|
if (Misc::StringUtils::ciEqual(fname, fnamecandidate))
|
||||||
{
|
{
|
||||||
index = i;
|
index = i;
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace ESM
|
||||||
{
|
{
|
||||||
it->mReader.open(*it->mName);
|
it->mReader.open(*it->mName);
|
||||||
it->mName.reset();
|
it->mName.reset();
|
||||||
|
it->mFileSize.reset();
|
||||||
}
|
}
|
||||||
mBusyItems.splice(mBusyItems.end(), mClosedItems, it);
|
mBusyItems.splice(mBusyItems.end(), mClosedItems, it);
|
||||||
break;
|
break;
|
||||||
|
@ -57,6 +58,46 @@ namespace ESM
|
||||||
return BusyItem(*this, it);
|
return BusyItem(*this, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::filesystem::path& ReadersCache::getName(std::size_t index) const
|
||||||
|
{
|
||||||
|
const auto indexIt = mIndex.find(index);
|
||||||
|
if (indexIt == mIndex.end())
|
||||||
|
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has not been created yet");
|
||||||
|
switch (indexIt->second->mState)
|
||||||
|
{
|
||||||
|
case State::Busy:
|
||||||
|
case State::Free:
|
||||||
|
return indexIt->second->mReader.getName();
|
||||||
|
case State::Closed:
|
||||||
|
if (indexIt->second->mName)
|
||||||
|
return *indexIt->second->mName;
|
||||||
|
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has forgotten its filename");
|
||||||
|
default:
|
||||||
|
throw std::logic_error("ESMReader at index " + std::to_string(index) + " in unknown state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ReadersCache::getFileSize(std::size_t index)
|
||||||
|
{
|
||||||
|
const auto indexIt = mIndex.find(index);
|
||||||
|
if (indexIt == mIndex.end())
|
||||||
|
return 0;
|
||||||
|
switch (indexIt->second->mState)
|
||||||
|
{
|
||||||
|
case State::Busy:
|
||||||
|
case State::Free:
|
||||||
|
if (!indexIt->second->mReader.getName().empty())
|
||||||
|
return indexIt->second->mReader.getFileSize();
|
||||||
|
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has not been opened yet");
|
||||||
|
case State::Closed:
|
||||||
|
if (indexIt->second->mFileSize)
|
||||||
|
return *indexIt->second->mFileSize;
|
||||||
|
throw std::logic_error("ESMReader at index " + std::to_string(index) + " has forgotten its file size");
|
||||||
|
default:
|
||||||
|
throw std::logic_error("ESMReader at index " + std::to_string(index) + " in unknown state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ReadersCache::closeExtraReaders()
|
void ReadersCache::closeExtraReaders()
|
||||||
{
|
{
|
||||||
while (!mFreeItems.empty() && mBusyItems.size() + mFreeItems.size() + 1 > mCapacity)
|
while (!mFreeItems.empty() && mBusyItems.size() + mFreeItems.size() + 1 > mCapacity)
|
||||||
|
@ -65,6 +106,7 @@ namespace ESM
|
||||||
if (it->mReader.isOpen())
|
if (it->mReader.isOpen())
|
||||||
{
|
{
|
||||||
it->mName = it->mReader.getName();
|
it->mName = it->mReader.getName();
|
||||||
|
it->mFileSize = it->mReader.getFileSize();
|
||||||
it->mReader.close();
|
it->mReader.close();
|
||||||
}
|
}
|
||||||
mClosedItems.splice(mClosedItems.end(), mFreeItems, it);
|
mClosedItems.splice(mClosedItems.end(), mFreeItems, it);
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace ESM
|
||||||
State mState = State::Busy;
|
State mState = State::Busy;
|
||||||
ESMReader mReader;
|
ESMReader mReader;
|
||||||
std::optional<std::filesystem::path> mName;
|
std::optional<std::filesystem::path> mName;
|
||||||
|
std::optional<std::size_t> mFileSize;
|
||||||
|
|
||||||
Item() = default;
|
Item() = default;
|
||||||
};
|
};
|
||||||
|
@ -55,6 +56,10 @@ namespace ESM
|
||||||
|
|
||||||
BusyItem get(std::size_t index);
|
BusyItem get(std::size_t index);
|
||||||
|
|
||||||
|
const std::filesystem::path& getName(std::size_t index) const;
|
||||||
|
|
||||||
|
std::size_t getFileSize(std::size_t index);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue