From 9b91d68df0a812b2fa0dd3da3f06ff0724033a46 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 17 May 2016 13:05:26 +0200 Subject: assimp plugin: replace QMap with a C array The keys are statically known, short, and few, so replace the QMap with a C array of a {char[2]; OpenMode} struct, which occupies just 40B in read-only memory. We don't even need to sort the list, as binary search in a list of ten entries is slower than linear search (five comparisons each, on average, with the linear scan having a predictable memory access pattern. This is a port of dd1d8f51e67ec93031fdd7f7930d63761d1238e6 to the other copy of this code, which shows that arguments like 'this is just a tool, not a library' are ill-advised. Code _will_ be copied. Change-Id: Ie04137f94e487ce998ec077daf655b09bcbbcfc7 Reviewed-by: Paul Lemire --- src/plugins/sceneparsers/assimp/assimphelpers.cpp | 57 +++++++++++------------ src/plugins/sceneparsers/assimp/assimphelpers.h | 6 --- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/plugins/sceneparsers/assimp/assimphelpers.cpp b/src/plugins/sceneparsers/assimp/assimphelpers.cpp index ce6619541..77209a7a9 100644 --- a/src/plugins/sceneparsers/assimp/assimphelpers.cpp +++ b/src/plugins/sceneparsers/assimp/assimphelpers.cpp @@ -157,29 +157,29 @@ void AssimpIOStream::Flush() * */ -/*! - * Builds a new instance of AssimpIOSystem. - */ -AssimpIOSystem::AssimpIOSystem() : - Assimp::IOSystem() -{ - m_openModeMaps[QByteArrayLiteral("r")] = QIODevice::ReadOnly; - m_openModeMaps[QByteArrayLiteral("r+")] = QIODevice::ReadWrite; - m_openModeMaps[QByteArrayLiteral("w")] = QIODevice::WriteOnly | QIODevice::Truncate; - m_openModeMaps[QByteArrayLiteral("w+")] = QIODevice::ReadWrite | QIODevice::Truncate; - m_openModeMaps[QByteArrayLiteral("a")] = QIODevice::WriteOnly | QIODevice::Append; - m_openModeMaps[QByteArrayLiteral("a+")] = QIODevice::ReadWrite | QIODevice::Append; - m_openModeMaps[QByteArrayLiteral("wb")] = QIODevice::WriteOnly; - m_openModeMaps[QByteArrayLiteral("wt")] = QIODevice::WriteOnly | QIODevice::Text; - m_openModeMaps[QByteArrayLiteral("rb")] = QIODevice::ReadOnly; - m_openModeMaps[QByteArrayLiteral("rt")] = QIODevice::ReadOnly | QIODevice::Text; -} - -/*! - * Clears an AssimpIOSystem instance before deletion. - */ -AssimpIOSystem::~AssimpIOSystem() +static QIODevice::OpenMode openModeFromText(const char *name) noexcept { + static const struct OpenModeMapping { + char name[2]; + ushort mode; + } openModeMapping[] = { + { { 'r', 0 }, QIODevice::ReadOnly }, + { { 'r', '+' }, QIODevice::ReadWrite }, + { { 'w', 0 }, QIODevice::WriteOnly | QIODevice::Truncate }, + { { 'w', '+' }, QIODevice::ReadWrite | QIODevice::Truncate }, + { { 'a', 0 }, QIODevice::WriteOnly | QIODevice::Append }, + { { 'a', '+' }, QIODevice::ReadWrite | QIODevice::Append }, + { { 'w', 'b' }, QIODevice::WriteOnly }, + { { 'w', 't' }, QIODevice::WriteOnly | QIODevice::Text }, + { { 'r', 'b' }, QIODevice::ReadOnly }, + { { 'r', 't' }, QIODevice::ReadOnly | QIODevice::Text }, + }; + + for (auto e : openModeMapping) { + if (qstrncmp(e.name, name, sizeof(OpenModeMapping::name)) == 0) + return static_cast(e.mode); + } + return QIODevice::NotOpen; } /*! @@ -205,14 +205,13 @@ char AssimpIOSystem::getOsSeparator() const Assimp::IOStream *AssimpIOSystem::Open(const char *pFile, const char *pMode) { const QString fileName(QString::fromUtf8(pFile)); - const QByteArray cleanedMode(QByteArray(pMode).trimmed()); - - const QIODevice::OpenMode openMode = m_openModeMaps.value(cleanedMode, QIODevice::NotOpen); - - QScopedPointer file(new QFile(fileName)); - if (file->open(openMode)) - return new AssimpIOStream(file.take()); + const QLatin1String cleanedMode = QLatin1String{pMode}.trimmed(); + if (const QIODevice::OpenMode openMode = openModeFromText(cleanedMode.data())) { + QScopedPointer file(new QFile(fileName)); + if (file->open(openMode)) + return new AssimpIOStream(file.take()); + } return nullptr; } diff --git a/src/plugins/sceneparsers/assimp/assimphelpers.h b/src/plugins/sceneparsers/assimp/assimphelpers.h index 0db22ce7b..fd102213c 100644 --- a/src/plugins/sceneparsers/assimp/assimphelpers.h +++ b/src/plugins/sceneparsers/assimp/assimphelpers.h @@ -55,7 +55,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -84,15 +83,10 @@ private: class AssimpIOSystem : public Assimp::IOSystem { public : - AssimpIOSystem(); - ~AssimpIOSystem(); bool Exists(const char *pFile) const override; char getOsSeparator() const override; Assimp::IOStream *Open(const char *pFile, const char *pMode) override; void Close(Assimp::IOStream *pFile) override; - -private: - QMap m_openModeMaps; }; } // namespace AssimpHelper -- cgit v1.2.3