diff --git a/libraries/octree/src/OctreeDataUtils.cpp b/libraries/octree/src/OctreeDataUtils.cpp index 4b1700d593..a2b0d78209 100644 --- a/libraries/octree/src/OctreeDataUtils.cpp +++ b/libraries/octree/src/OctreeDataUtils.cpp @@ -18,30 +18,32 @@ #include #include -// Reads octree file and parses it into a QJsonDocument. Handles both gzipped and non-gzipped files. -// Returns true if the file was successfully opened and parsed, otherwise false. -// Example failures: file does not exist, gzipped file cannot be unzipped, invalid JSON. -bool readOctreeFile(QString path, QJsonDocument* doc) { - QFile file(path); - if (!file.open(QIODevice::ReadOnly)) { - qCritical() << "Cannot open json file for reading: " << path; - return false; - } +namespace { + // Reads octree file and parses it into a QJsonDocument. Handles both gzipped and non-gzipped files. + // Returns true if the file was successfully opened and parsed, otherwise false. + // Example failures: file does not exist, gzipped file cannot be unzipped, invalid JSON. + bool readOctreeFile(QString path, QJsonDocument* doc) { + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "Cannot open json file for reading: " << path; + return false; + } - QByteArray data = file.readAll(); - QByteArray jsonData; + QByteArray data = file.readAll(); + QByteArray jsonData; - if (!gunzip(data, jsonData)) { - jsonData = data; - } + if (!gunzip(data, jsonData)) { + jsonData = data; + } - QJsonParseError parserError; - *doc = QJsonDocument::fromJson(jsonData, &parserError); - if (parserError.error != QJsonParseError::NoError) { - qWarning() << "Error reading JSON file" << path << "-" << parserError.errorString(); + QJsonParseError parserError; + *doc = QJsonDocument::fromJson(jsonData, &parserError); + if (parserError.error != QJsonParseError::NoError) { + qWarning() << "Error reading JSON file" << path << "-" << parserError.errorString(); + } + return !doc->isNull(); } - return !doc->isNull(); -} +} // Anon namespace. bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromJSON(QJsonObject root) { if (root.contains("Id") && root.contains("DataVersion") && root.contains("Version")) { diff --git a/libraries/octree/src/OctreeDataUtils.h b/libraries/octree/src/OctreeDataUtils.h index 9060e7b460..ef96415044 100644 --- a/libraries/octree/src/OctreeDataUtils.h +++ b/libraries/octree/src/OctreeDataUtils.h @@ -46,6 +46,7 @@ public: }; class RawEntityData : public RawOctreeData { +public: PacketType dataPacketType() const override; void readSubclassData(const QJsonObject& root) override; void writeSubclassData(QJsonObject& root) const override; diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index 8b1d766418..0c78a1a797 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "OctreeLogging.h" #include "OctreeUtils.h" @@ -72,14 +73,27 @@ void OctreePersistThread::start() { OctreeUtils::RawOctreeData data; qCDebug(octree) << "Reading octree data from" << _filename; - if (data.readOctreeDataInfoFromFile(_filename)) { - qCDebug(octree) << "Current octree data: ID(" << data.id << ") DataVersion(" << data.version << ")"; - packet->writePrimitive(true); - auto id = data.id.toRfc4122(); - packet->write(id); - packet->writePrimitive(data.version); + QFile file(_filename); + if (file.open(QIODevice::ReadOnly)) { + QByteArray jsonData(file.readAll()); + file.close(); + if (!gunzip(jsonData, _cachedJSONData)) { + _cachedJSONData = jsonData; + } + + if (data.readOctreeDataInfoFromData(_cachedJSONData)) { + qCDebug(octree) << "Current octree data: ID(" << data.id << ") DataVersion(" << data.version << ")"; + packet->writePrimitive(true); + auto id = data.id.toRfc4122(); + packet->write(id); + packet->writePrimitive(data.version); + } else { + _cachedJSONData.clear(); + qCWarning(octree) << "No octree data found"; + packet->writePrimitive(false); + } } else { - qCWarning(octree) << "No octree data found"; + qCWarning(octree) << "Couldn't access file" << _filename << file.errorString(); packet->writePrimitive(false); } @@ -99,6 +113,7 @@ void OctreePersistThread::handleOctreeDataFileReply(QSharedPointerreadAll(); replaceData(replacementData); hasValidOctreeData = data.readOctreeDataInfoFromFile(_filename); @@ -108,7 +123,7 @@ void OctreePersistThread::handleOctreeDataFileReply(QSharedPointerwithWriteLock([&] { PerformanceWarning warn(true, "Loading Octree File", true); - persistentFileRead = _tree->readFromFile(_filename.toLocal8Bit().constData()); + if (_cachedJSONData.isEmpty()) { + persistentFileRead = _tree->readFromFile(_filename.toLocal8Bit().constData()); + } else { + QDataStream jsonStream(_cachedJSONData); + persistentFileRead = _tree->readFromStream(-1, QDataStream(_cachedJSONData)); + } _tree->pruneTree(); }); + _cachedJSONData.clear(); quint64 loadDone = usecTimestampNow(); _loadTimeUSecs = loadDone - loadStarted; diff --git a/libraries/octree/src/OctreePersistThread.h b/libraries/octree/src/OctreePersistThread.h index 0044a8fa5a..6a38a21a84 100644 --- a/libraries/octree/src/OctreePersistThread.h +++ b/libraries/octree/src/OctreePersistThread.h @@ -78,6 +78,7 @@ private: quint64 _lastTimeDebug; QString _persistAsFileType; + QByteArray _cachedJSONData; }; #endif // hifi_OctreePersistThread_h