From 96e2873bfa2c6b8823aed3b4190c43cd5dab54e6 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 24 Sep 2020 10:23:39 -0700 Subject: Rename lldiskcache.* to llfilesystem.* - i think this is the right name since it's responsible for performing file system operations and (will eventually) delegrate to a separate disk cache component to save/load data and keep track of metadata etc. --- indra/llfilesystem/llfilesystem.cpp | 387 ++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 indra/llfilesystem/llfilesystem.cpp (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp new file mode 100644 index 0000000000..af93049e07 --- /dev/null +++ b/indra/llfilesystem/llfilesystem.cpp @@ -0,0 +1,387 @@ +/** + * @file lldiskcache.cpp + * @brief Implementation of virtual file + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "lldiskcache.h" + +#include "llerror.h" +#include "llthread.h" +#include "lltimer.h" +#include "llfasttimer.h" +#include "llmemory.h" + +#include +#include "lldir.h" + +const S32 LLDiskCache::READ = 0x00000001; +const S32 LLDiskCache::WRITE = 0x00000002; +const S32 LLDiskCache::READ_WRITE = 0x00000003; // LLDiskCache::READ & LLDiskCache::WRITE +const S32 LLDiskCache::APPEND = 0x00000006; // 0x00000004 & LLDiskCache::WRITE + +static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); + +LLDiskCache::LLDiskCache(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) +{ + mFileType = file_type; + mFileID = file_id; + mPosition = 0; + mBytesRead = 0; + mReadComplete = FALSE; + mMode = mode; +} + +LLDiskCache::~LLDiskCache() +{ +} + +const std::string assetTypeToString(LLAssetType::EType at) +{ + /** + * Make use of the C++17 (or is it 14) feature that allows + * for inline initialization of an std::map<> + */ + typedef std::map asset_type_to_name_t; + asset_type_to_name_t asset_type_to_name = + { + { LLAssetType::AT_TEXTURE, "TEXTURE" }, + { LLAssetType::AT_SOUND, "SOUND" }, + { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" }, + { LLAssetType::AT_LANDMARK, "LANDMARK" }, + { LLAssetType::AT_SCRIPT, "SCRIPT" }, + { LLAssetType::AT_CLOTHING, "CLOTHING" }, + { LLAssetType::AT_OBJECT, "OBJECT" }, + { LLAssetType::AT_NOTECARD, "NOTECARD" }, + { LLAssetType::AT_CATEGORY, "CATEGORY" }, + { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" }, + { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" }, + { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" }, + { LLAssetType::AT_BODYPART, "BODYPART" }, + { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" }, + { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" }, + { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" }, + { LLAssetType::AT_ANIMATION, "ANIMATION" }, + { LLAssetType::AT_GESTURE, "GESTURE" }, + { LLAssetType::AT_SIMSTATE, "SIMSTATE" }, + { LLAssetType::AT_LINK, "LINK" }, + { LLAssetType::AT_LINK_FOLDER, "LINK_FOLDER" }, + { LLAssetType::AT_MARKETPLACE_FOLDER, "MARKETPLACE_FOLDER" }, + { LLAssetType::AT_WIDGET, "WIDGET" }, + { LLAssetType::AT_PERSON, "PERSON" }, + { LLAssetType::AT_MESH, "MESH" }, + { LLAssetType::AT_SETTINGS, "SETTINGS" }, + { LLAssetType::AT_UNKNOWN, "UNKNOWN" } + }; + + asset_type_to_name_t::iterator iter = asset_type_to_name.find(at); + if (iter != asset_type_to_name.end()) + { + return iter->second; + } + + return std::string("UNKNOWN"); +} + +const std::string idToFilepath(const std::string id, LLAssetType::EType at) +{ + /** + * For the moment this is just {UUID}_{ASSET_TYPE}.txt but of + * course, will be greatly expanded upon + */ + std::ostringstream ss; + ss << "00cache_"; + ss << id; + ss << "_"; + ss << assetTypeToString(at); + ss << ".txt"; + + const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ss.str()); + + return filepath; +} + +// static +bool LLDiskCache::getExists(const LLUUID &file_id, const LLAssetType::EType file_type) +{ + std::string id_str; + file_id.toString(id_str); + const std::string filename = idToFilepath(id_str, file_type); + + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) + { + file.seekg(0, std::ios::end); + return file.tellg() > 0; + } + return false; +} + +// static +bool LLDiskCache::removeFile(const LLUUID &file_id, const LLAssetType::EType file_type) +{ + std::string id_str; + file_id.toString(id_str); + const std::string filename = idToFilepath(id_str, file_type); + + std::remove(filename.c_str()); + + return true; +} + +// static +bool LLDiskCache::renameFile(const LLUUID &old_file_id, const LLAssetType::EType old_file_type, + const LLUUID &new_file_id, const LLAssetType::EType new_file_type) +{ + std::string old_id_str; + old_file_id.toString(old_id_str); + const std::string old_filename = idToFilepath(old_id_str, old_file_type); + + std::string new_id_str; + new_file_id.toString(new_id_str); + const std::string new_filename = idToFilepath(new_id_str, new_file_type); + + if (std::rename(old_filename.c_str(), new_filename.c_str())) + { + // We would like to return FALSE here indicating the operation + // failed but the original code does not and doing so seems to + // break a lot of things so we go with the flow... + //return FALSE; + } + + return TRUE; +} + +// static +S32 LLDiskCache::getFileSize(const LLUUID &file_id, const LLAssetType::EType file_type) +{ + std::string id_str; + file_id.toString(id_str); + const std::string filename = idToFilepath(id_str, file_type); + + S32 file_size = 0; + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) + { + file.seekg(0, std::ios::end); + file_size = file.tellg(); + } + + return file_size; +} + +BOOL LLDiskCache::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) +{ + BOOL success = TRUE; + + mReadComplete = FALSE; + + std::string id; + mFileID.toString(id); + const std::string filename = idToFilepath(id, mFileType); + + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) + { + file.seekg(mPosition, std::ios::beg); + + file.read((char*)buffer, bytes); + + if (file) + { + mBytesRead = bytes; + } + else + { + mBytesRead = file.gcount(); + } + + file.close(); + + mPosition += mBytesRead; + if (!mBytesRead) + { + success = FALSE; + } + + mReadComplete = TRUE; + } + + return success; +} + +BOOL LLDiskCache::isReadComplete() +{ + if (mReadComplete) + { + return TRUE; + } + + return FALSE; +} + +S32 LLDiskCache::getLastBytesRead() +{ + return mBytesRead; +} + +BOOL LLDiskCache::eof() +{ + return mPosition >= getSize(); +} + +BOOL LLDiskCache::write(const U8 *buffer, S32 bytes) +{ + std::string id_str; + mFileID.toString(id_str); + const std::string filename = idToFilepath(id_str, mFileType); + + BOOL success = FALSE; + + if (mMode == APPEND) + { + std::ofstream ofs(filename, std::ios::app | std::ios::binary); + if (ofs) + { + ofs.write((const char*)buffer, bytes); + + success = TRUE; + } + } + else + { + std::ofstream ofs(filename, std::ios::binary); + if (ofs) + { + ofs.write((const char*)buffer, bytes); + + mPosition += bytes; + + success = TRUE; + } + } + + return success; +} + +//static +BOOL LLDiskCache::writeFile(const U8 *buffer, S32 bytes, const LLUUID &uuid, LLAssetType::EType type) +{ + LLDiskCache file(uuid, type, LLDiskCache::WRITE); + file.setMaxSize(bytes); + return file.write(buffer, bytes); +} + +BOOL LLDiskCache::seek(S32 offset, S32 origin) +{ + if (-1 == origin) + { + origin = mPosition; + } + + S32 new_pos = origin + offset; + + S32 size = getSize(); + + if (new_pos > size) + { + LL_WARNS() << "Attempt to seek past end of file" << LL_ENDL; + + mPosition = size; + return FALSE; + } + else if (new_pos < 0) + { + LL_WARNS() << "Attempt to seek past beginning of file" << LL_ENDL; + + mPosition = 0; + return FALSE; + } + + mPosition = new_pos; + return TRUE; +} + +S32 LLDiskCache::tell() const +{ + return mPosition; +} + +S32 LLDiskCache::getSize() +{ + return LLDiskCache::getFileSize(mFileID, mFileType); +} + +S32 LLDiskCache::getMaxSize() +{ + // offer up a huge size since we don't care what the max is + return INT_MAX; +} + +BOOL LLDiskCache::setMaxSize(S32 size) +{ + // we don't care what the max size is so we do nothing + // and return true to indicate all was okay + return TRUE; +} + +BOOL LLDiskCache::rename(const LLUUID &new_id, const LLAssetType::EType new_type) +{ + LLDiskCache::renameFile(mFileID, mFileType, new_id, new_type); + + mFileID = new_id; + mFileType = new_type; + + return TRUE; +} + +BOOL LLDiskCache::remove() +{ + LLDiskCache::removeFile(mFileID, mFileType); + + return TRUE; +} + +// static +void LLDiskCache::initClass() +{ +} + +// static +void LLDiskCache::cleanupClass() +{ +} + +bool LLDiskCache::isLocked() +{ + // I don't think we care about this test since there is no locking + // TODO: remove this function and calling sites? + return FALSE; +} + +void LLDiskCache::waitForLock() +{ + // TODO: remove this function and calling sites? +} -- cgit v1.2.3 From 6be1f88a5ef99e1e40bb5701a250ba0728f56005 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Thu, 24 Sep 2020 14:45:39 -0700 Subject: Complete the change from lldiskcache -> llfilesystem and then addition of new lldiskcache implementation --- indra/llfilesystem/llfilesystem.cpp | 79 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index af93049e07..f0037c9a22 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -1,6 +1,9 @@ /** - * @file lldiskcache.cpp - * @brief Implementation of virtual file + * @file filesystem.h + * @brief Simulate local file system operations. + * @Note The initial implementation does actually use standard C++ + * file operations but eventually, there will be another + * layer that caches and manages file meta data too. * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code @@ -26,25 +29,21 @@ #include "linden_common.h" -#include "lldiskcache.h" - -#include "llerror.h" -#include "llthread.h" -#include "lltimer.h" +#include "lldir.h" +#include "llfilesystem.h" #include "llfasttimer.h" -#include "llmemory.h" +#include "lldiskcache.h" #include -#include "lldir.h" -const S32 LLDiskCache::READ = 0x00000001; -const S32 LLDiskCache::WRITE = 0x00000002; -const S32 LLDiskCache::READ_WRITE = 0x00000003; // LLDiskCache::READ & LLDiskCache::WRITE -const S32 LLDiskCache::APPEND = 0x00000006; // 0x00000004 & LLDiskCache::WRITE +const S32 LLFileSystem::READ = 0x00000001; +const S32 LLFileSystem::WRITE = 0x00000002; +const S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE +const S32 LLFileSystem::APPEND = 0x00000006; // 0x00000004 & LLFileSystem::WRITE static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); -LLDiskCache::LLDiskCache(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) +LLFileSystem::LLFileSystem(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) { mFileType = file_type; mFileID = file_id; @@ -54,7 +53,7 @@ LLDiskCache::LLDiskCache(const LLUUID &file_id, const LLAssetType::EType file_ty mMode = mode; } -LLDiskCache::~LLDiskCache() +LLFileSystem::~LLFileSystem() { } @@ -124,7 +123,7 @@ const std::string idToFilepath(const std::string id, LLAssetType::EType at) } // static -bool LLDiskCache::getExists(const LLUUID &file_id, const LLAssetType::EType file_type) +bool LLFileSystem::getExists(const LLUUID &file_id, const LLAssetType::EType file_type) { std::string id_str; file_id.toString(id_str); @@ -140,7 +139,7 @@ bool LLDiskCache::getExists(const LLUUID &file_id, const LLAssetType::EType file } // static -bool LLDiskCache::removeFile(const LLUUID &file_id, const LLAssetType::EType file_type) +bool LLFileSystem::removeFile(const LLUUID &file_id, const LLAssetType::EType file_type) { std::string id_str; file_id.toString(id_str); @@ -152,7 +151,7 @@ bool LLDiskCache::removeFile(const LLUUID &file_id, const LLAssetType::EType fil } // static -bool LLDiskCache::renameFile(const LLUUID &old_file_id, const LLAssetType::EType old_file_type, +bool LLFileSystem::renameFile(const LLUUID &old_file_id, const LLAssetType::EType old_file_type, const LLUUID &new_file_id, const LLAssetType::EType new_file_type) { std::string old_id_str; @@ -175,7 +174,7 @@ bool LLDiskCache::renameFile(const LLUUID &old_file_id, const LLAssetType::EType } // static -S32 LLDiskCache::getFileSize(const LLUUID &file_id, const LLAssetType::EType file_type) +S32 LLFileSystem::getFileSize(const LLUUID &file_id, const LLAssetType::EType file_type) { std::string id_str; file_id.toString(id_str); @@ -192,7 +191,7 @@ S32 LLDiskCache::getFileSize(const LLUUID &file_id, const LLAssetType::EType fil return file_size; } -BOOL LLDiskCache::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) +BOOL LLFileSystem::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) { BOOL success = TRUE; @@ -232,7 +231,7 @@ BOOL LLDiskCache::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) return success; } -BOOL LLDiskCache::isReadComplete() +BOOL LLFileSystem::isReadComplete() { if (mReadComplete) { @@ -242,17 +241,17 @@ BOOL LLDiskCache::isReadComplete() return FALSE; } -S32 LLDiskCache::getLastBytesRead() +S32 LLFileSystem::getLastBytesRead() { return mBytesRead; } -BOOL LLDiskCache::eof() +BOOL LLFileSystem::eof() { return mPosition >= getSize(); } -BOOL LLDiskCache::write(const U8 *buffer, S32 bytes) +BOOL LLFileSystem::write(const U8 *buffer, S32 bytes) { std::string id_str; mFileID.toString(id_str); @@ -287,14 +286,14 @@ BOOL LLDiskCache::write(const U8 *buffer, S32 bytes) } //static -BOOL LLDiskCache::writeFile(const U8 *buffer, S32 bytes, const LLUUID &uuid, LLAssetType::EType type) +BOOL LLFileSystem::writeFile(const U8 *buffer, S32 bytes, const LLUUID &uuid, LLAssetType::EType type) { - LLDiskCache file(uuid, type, LLDiskCache::WRITE); + LLFileSystem file(uuid, type, LLFileSystem::WRITE); file.setMaxSize(bytes); return file.write(buffer, bytes); } -BOOL LLDiskCache::seek(S32 offset, S32 origin) +BOOL LLFileSystem::seek(S32 offset, S32 origin) { if (-1 == origin) { @@ -324,32 +323,32 @@ BOOL LLDiskCache::seek(S32 offset, S32 origin) return TRUE; } -S32 LLDiskCache::tell() const +S32 LLFileSystem::tell() const { return mPosition; } -S32 LLDiskCache::getSize() +S32 LLFileSystem::getSize() { - return LLDiskCache::getFileSize(mFileID, mFileType); + return LLFileSystem::getFileSize(mFileID, mFileType); } -S32 LLDiskCache::getMaxSize() +S32 LLFileSystem::getMaxSize() { // offer up a huge size since we don't care what the max is return INT_MAX; } -BOOL LLDiskCache::setMaxSize(S32 size) +BOOL LLFileSystem::setMaxSize(S32 size) { // we don't care what the max size is so we do nothing // and return true to indicate all was okay return TRUE; } -BOOL LLDiskCache::rename(const LLUUID &new_id, const LLAssetType::EType new_type) +BOOL LLFileSystem::rename(const LLUUID &new_id, const LLAssetType::EType new_type) { - LLDiskCache::renameFile(mFileID, mFileType, new_id, new_type); + LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type); mFileID = new_id; mFileType = new_type; @@ -357,31 +356,31 @@ BOOL LLDiskCache::rename(const LLUUID &new_id, const LLAssetType::EType new_type return TRUE; } -BOOL LLDiskCache::remove() +BOOL LLFileSystem::remove() { - LLDiskCache::removeFile(mFileID, mFileType); + LLFileSystem::removeFile(mFileID, mFileType); return TRUE; } // static -void LLDiskCache::initClass() +void LLFileSystem::initClass() { } // static -void LLDiskCache::cleanupClass() +void LLFileSystem::cleanupClass() { } -bool LLDiskCache::isLocked() +bool LLFileSystem::isLocked() { // I don't think we care about this test since there is no locking // TODO: remove this function and calling sites? return FALSE; } -void LLDiskCache::waitForLock() +void LLFileSystem::waitForLock() { // TODO: remove this function and calling sites? } -- cgit v1.2.3 From 3092aa8aae496803707980eb456cddbb9960ef1c Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Tue, 6 Oct 2020 17:16:53 -0700 Subject: Add in the C++ filesystem based cache and clean up some indempotent functions in llfilesystem --- indra/llfilesystem/llfilesystem.cpp | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index f0037c9a22..ffc3dee12b 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -42,6 +42,8 @@ const S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFile const S32 LLFileSystem::APPEND = 0x00000006; // 0x00000004 & LLFileSystem::WRITE static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); +LLDiskCache* LLFileSystem::mDiskCache = 0; +std::string LLFileSystem::mCacheDirName = "cache"; LLFileSystem::LLFileSystem(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) { @@ -104,7 +106,7 @@ const std::string assetTypeToString(LLAssetType::EType at) return std::string("UNKNOWN"); } -const std::string idToFilepath(const std::string id, LLAssetType::EType at) +const std::string LLFileSystem::idToFilepath(const std::string id, LLAssetType::EType at) { /** * For the moment this is just {UUID}_{ASSET_TYPE}.txt but of @@ -117,7 +119,7 @@ const std::string idToFilepath(const std::string id, LLAssetType::EType at) ss << assetTypeToString(at); ss << ".txt"; - const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ss.str()); + const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mCacheDirName, ss.str()); return filepath; } @@ -289,7 +291,6 @@ BOOL LLFileSystem::write(const U8 *buffer, S32 bytes) BOOL LLFileSystem::writeFile(const U8 *buffer, S32 bytes, const LLUUID &uuid, LLAssetType::EType type) { LLFileSystem file(uuid, type, LLFileSystem::WRITE); - file.setMaxSize(bytes); return file.write(buffer, bytes); } @@ -339,13 +340,6 @@ S32 LLFileSystem::getMaxSize() return INT_MAX; } -BOOL LLFileSystem::setMaxSize(S32 size) -{ - // we don't care what the max size is so we do nothing - // and return true to indicate all was okay - return TRUE; -} - BOOL LLFileSystem::rename(const LLUUID &new_id, const LLAssetType::EType new_type) { LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type); @@ -366,21 +360,15 @@ BOOL LLFileSystem::remove() // static void LLFileSystem::initClass() { -} + const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mCacheDirName); -// static -void LLFileSystem::cleanupClass() -{ -} + LLFileSystem::mDiskCache = new LLDiskCache(cache_dir); -bool LLFileSystem::isLocked() -{ - // I don't think we care about this test since there is no locking - // TODO: remove this function and calling sites? - return FALSE; + mDiskCache->purge(); } -void LLFileSystem::waitForLock() +// static +void LLFileSystem::cleanupClass() { - // TODO: remove this function and calling sites? + delete LLFileSystem::mDiskCache; } -- cgit v1.2.3 From a0ea119623b8bda445f86afdb0ea7b5833c8e171 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Tue, 6 Oct 2020 18:18:18 -0700 Subject: Replace references to static writefile with write so we end up with only a single read and a single write function --- indra/llfilesystem/llfilesystem.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index ffc3dee12b..6d6ff3d7e1 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -230,6 +230,12 @@ BOOL LLFileSystem::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) mReadComplete = TRUE; } + // update the last access time for the file - this is required + // even though we are reading and not writing because this is the + // way the cache works - it relies on a valid "last accessed time" for + // each file so it knows how to remove the oldest, unused files + LLFileSystem::mDiskCache->updateFileAccessTime(filename); + return success; } @@ -287,13 +293,6 @@ BOOL LLFileSystem::write(const U8 *buffer, S32 bytes) return success; } -//static -BOOL LLFileSystem::writeFile(const U8 *buffer, S32 bytes, const LLUUID &uuid, LLAssetType::EType type) -{ - LLFileSystem file(uuid, type, LLFileSystem::WRITE); - return file.write(buffer, bytes); -} - BOOL LLFileSystem::seek(S32 offset, S32 origin) { if (-1 == origin) -- cgit v1.2.3 From 08dfc0836fb12855d0c07d811e2909400d5b74f3 Mon Sep 17 00:00:00 2001 From: Callum Prentice Date: Wed, 7 Oct 2020 15:25:12 -0700 Subject: This changeset hooks up many things that have been in progress and moves things about between llfilesystem and lldiskcache - there is still some bookkeeping work left but this is the first version that appears to work and actively manage the cache --- indra/llfilesystem/llfilesystem.cpp | 238 +++++++++++------------------------- 1 file changed, 73 insertions(+), 165 deletions(-) (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index 6d6ff3d7e1..c6b20caa69 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -1,4 +1,4 @@ -/** +/** * @file filesystem.h * @brief Simulate local file system operations. * @Note The initial implementation does actually use standard C++ @@ -8,21 +8,21 @@ * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,139 +36,74 @@ #include -const S32 LLFileSystem::READ = 0x00000001; -const S32 LLFileSystem::WRITE = 0x00000002; -const S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE -const S32 LLFileSystem::APPEND = 0x00000006; // 0x00000004 & LLFileSystem::WRITE +const S32 LLFileSystem::READ = 0x00000001; +const S32 LLFileSystem::WRITE = 0x00000002; +const S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE +const S32 LLFileSystem::APPEND = 0x00000006; // 0x00000004 & LLFileSystem::WRITE static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); -LLDiskCache* LLFileSystem::mDiskCache = 0; -std::string LLFileSystem::mCacheDirName = "cache"; -LLFileSystem::LLFileSystem(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode) +LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode) { - mFileType = file_type; - mFileID = file_id; - mPosition = 0; + mFileType = file_type; + mFileID = file_id; + mPosition = 0; mBytesRead = 0; - mReadComplete = FALSE; - mMode = mode; + mMode = mode; } LLFileSystem::~LLFileSystem() { } -const std::string assetTypeToString(LLAssetType::EType at) +// static +bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type) { - /** - * Make use of the C++17 (or is it 14) feature that allows - * for inline initialization of an std::map<> - */ - typedef std::map asset_type_to_name_t; - asset_type_to_name_t asset_type_to_name = - { - { LLAssetType::AT_TEXTURE, "TEXTURE" }, - { LLAssetType::AT_SOUND, "SOUND" }, - { LLAssetType::AT_CALLINGCARD, "CALLINGCARD" }, - { LLAssetType::AT_LANDMARK, "LANDMARK" }, - { LLAssetType::AT_SCRIPT, "SCRIPT" }, - { LLAssetType::AT_CLOTHING, "CLOTHING" }, - { LLAssetType::AT_OBJECT, "OBJECT" }, - { LLAssetType::AT_NOTECARD, "NOTECARD" }, - { LLAssetType::AT_CATEGORY, "CATEGORY" }, - { LLAssetType::AT_LSL_TEXT, "LSL_TEXT" }, - { LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" }, - { LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" }, - { LLAssetType::AT_BODYPART, "BODYPART" }, - { LLAssetType::AT_SOUND_WAV, "SOUND_WAV" }, - { LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" }, - { LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" }, - { LLAssetType::AT_ANIMATION, "ANIMATION" }, - { LLAssetType::AT_GESTURE, "GESTURE" }, - { LLAssetType::AT_SIMSTATE, "SIMSTATE" }, - { LLAssetType::AT_LINK, "LINK" }, - { LLAssetType::AT_LINK_FOLDER, "LINK_FOLDER" }, - { LLAssetType::AT_MARKETPLACE_FOLDER, "MARKETPLACE_FOLDER" }, - { LLAssetType::AT_WIDGET, "WIDGET" }, - { LLAssetType::AT_PERSON, "PERSON" }, - { LLAssetType::AT_MESH, "MESH" }, - { LLAssetType::AT_SETTINGS, "SETTINGS" }, - { LLAssetType::AT_UNKNOWN, "UNKNOWN" } - }; - - asset_type_to_name_t::iterator iter = asset_type_to_name.find(at); - if (iter != asset_type_to_name.end()) + std::string id_str; + file_id.toString(id_str); + const std::string extra_info = ""; + const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info); + + std::ifstream file(filename, std::ios::binary); + if (file.is_open()) { - return iter->second; + file.seekg(0, std::ios::end); + return file.tellg() > 0; } - - return std::string("UNKNOWN"); -} - -const std::string LLFileSystem::idToFilepath(const std::string id, LLAssetType::EType at) -{ - /** - * For the moment this is just {UUID}_{ASSET_TYPE}.txt but of - * course, will be greatly expanded upon - */ - std::ostringstream ss; - ss << "00cache_"; - ss << id; - ss << "_"; - ss << assetTypeToString(at); - ss << ".txt"; - - const std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mCacheDirName, ss.str()); - - return filepath; + return false; } // static -bool LLFileSystem::getExists(const LLUUID &file_id, const LLAssetType::EType file_type) -{ - std::string id_str; - file_id.toString(id_str); - const std::string filename = idToFilepath(id_str, file_type); - - std::ifstream file(filename, std::ios::binary); - if (file.is_open()) - { - file.seekg(0, std::ios::end); - return file.tellg() > 0; - } - return false; -} - -// static -bool LLFileSystem::removeFile(const LLUUID &file_id, const LLAssetType::EType file_type) +bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType file_type) { std::string id_str; file_id.toString(id_str); - const std::string filename = idToFilepath(id_str, file_type); - + const std::string extra_info = ""; + const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info); + std::remove(filename.c_str()); return true; } // static -bool LLFileSystem::renameFile(const LLUUID &old_file_id, const LLAssetType::EType old_file_type, - const LLUUID &new_file_id, const LLAssetType::EType new_file_type) +bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type, + const LLUUID& new_file_id, const LLAssetType::EType new_file_type) { std::string old_id_str; old_file_id.toString(old_id_str); - const std::string old_filename = idToFilepath(old_id_str, old_file_type); + const std::string extra_info = ""; + const std::string old_filename = LLDiskCache::getInstance()->metaDataToFilepath(old_id_str, old_file_type, extra_info); std::string new_id_str; new_file_id.toString(new_id_str); - const std::string new_filename = idToFilepath(new_id_str, new_file_type); + const std::string new_filename = LLDiskCache::getInstance()->metaDataToFilepath(new_id_str, new_file_type, extra_info); if (std::rename(old_filename.c_str(), new_filename.c_str())) { // We would like to return FALSE here indicating the operation // failed but the original code does not and doing so seems to - // break a lot of things so we go with the flow... + // break a lot of things so we go with the flow... //return FALSE; } @@ -176,11 +111,12 @@ bool LLFileSystem::renameFile(const LLUUID &old_file_id, const LLAssetType::ETyp } // static -S32 LLFileSystem::getFileSize(const LLUUID &file_id, const LLAssetType::EType file_type) +S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type) { std::string id_str; file_id.toString(id_str); - const std::string filename = idToFilepath(id_str, file_type); + const std::string extra_info = ""; + const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info); S32 file_size = 0; std::ifstream file(filename, std::ios::binary); @@ -193,15 +129,14 @@ S32 LLFileSystem::getFileSize(const LLUUID &file_id, const LLAssetType::EType fi return file_size; } -BOOL LLFileSystem::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) +BOOL LLFileSystem::read(U8* buffer, S32 bytes) { - BOOL success = TRUE; - - mReadComplete = FALSE; + BOOL success = TRUE; std::string id; mFileID.toString(id); - const std::string filename = idToFilepath(id, mFileType); + const std::string extra_info = ""; + const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id, mFileType, extra_info); std::ifstream file(filename, std::ios::binary); if (file.is_open()) @@ -226,44 +161,33 @@ BOOL LLFileSystem::read(U8 *buffer, S32 bytes, BOOL async, F32 priority) { success = FALSE; } - - mReadComplete = TRUE; } - // update the last access time for the file - this is required + // update the last access time for the file - this is required // even though we are reading and not writing because this is the // way the cache works - it relies on a valid "last accessed time" for // each file so it knows how to remove the oldest, unused files - LLFileSystem::mDiskCache->updateFileAccessTime(filename); + LLDiskCache::getInstance()->updateFileAccessTime(filename); return success; } -BOOL LLFileSystem::isReadComplete() -{ - if (mReadComplete) - { - return TRUE; - } - - return FALSE; -} - S32 LLFileSystem::getLastBytesRead() { - return mBytesRead; + return mBytesRead; } BOOL LLFileSystem::eof() { - return mPosition >= getSize(); + return mPosition >= getSize(); } -BOOL LLFileSystem::write(const U8 *buffer, S32 bytes) +BOOL LLFileSystem::write(const U8* buffer, S32 bytes) { std::string id_str; mFileID.toString(id_str); - const std::string filename = idToFilepath(id_str, mFileType); + const std::string extra_info = ""; + const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, mFileType, extra_info); BOOL success = FALSE; @@ -295,37 +219,37 @@ BOOL LLFileSystem::write(const U8 *buffer, S32 bytes) BOOL LLFileSystem::seek(S32 offset, S32 origin) { - if (-1 == origin) - { - origin = mPosition; - } + if (-1 == origin) + { + origin = mPosition; + } - S32 new_pos = origin + offset; + S32 new_pos = origin + offset; - S32 size = getSize(); + S32 size = getSize(); - if (new_pos > size) - { - LL_WARNS() << "Attempt to seek past end of file" << LL_ENDL; + if (new_pos > size) + { + LL_WARNS() << "Attempt to seek past end of file" << LL_ENDL; - mPosition = size; - return FALSE; - } - else if (new_pos < 0) - { - LL_WARNS() << "Attempt to seek past beginning of file" << LL_ENDL; + mPosition = size; + return FALSE; + } + else if (new_pos < 0) + { + LL_WARNS() << "Attempt to seek past beginning of file" << LL_ENDL; - mPosition = 0; - return FALSE; - } + mPosition = 0; + return FALSE; + } - mPosition = new_pos; - return TRUE; + mPosition = new_pos; + return TRUE; } S32 LLFileSystem::tell() const { - return mPosition; + return mPosition; } S32 LLFileSystem::getSize() @@ -335,11 +259,11 @@ S32 LLFileSystem::getSize() S32 LLFileSystem::getMaxSize() { - // offer up a huge size since we don't care what the max is + // offer up a huge size since we don't care what the max is return INT_MAX; } -BOOL LLFileSystem::rename(const LLUUID &new_id, const LLAssetType::EType new_type) +BOOL LLFileSystem::rename(const LLUUID& new_id, const LLAssetType::EType new_type) { LLFileSystem::renameFile(mFileID, mFileType, new_id, new_type); @@ -355,19 +279,3 @@ BOOL LLFileSystem::remove() return TRUE; } - -// static -void LLFileSystem::initClass() -{ - const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mCacheDirName); - - LLFileSystem::mDiskCache = new LLDiskCache(cache_dir); - - mDiskCache->purge(); -} - -// static -void LLFileSystem::cleanupClass() -{ - delete LLFileSystem::mDiskCache; -} -- cgit v1.2.3 From 3b4bd86a1de3fb1a9065024089fcfec2dae1da85 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 27 Oct 2020 16:46:31 +0200 Subject: SL-14182 remove old script asset file after saving changes and allow renaming files if destination file exists --- indra/llfilesystem/llfilesystem.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index c6b20caa69..932ef2a9c6 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -99,12 +99,16 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp new_file_id.toString(new_id_str); const std::string new_filename = LLDiskCache::getInstance()->metaDataToFilepath(new_id_str, new_file_type, extra_info); + // Rename needs the new file to not exist. + LLFileSystem::removeFile(new_file_id, new_file_type); + if (std::rename(old_filename.c_str(), new_filename.c_str())) { // We would like to return FALSE here indicating the operation // failed but the original code does not and doing so seems to // break a lot of things so we go with the flow... //return FALSE; + LL_WARNS() << "Failed to rename " << old_file_id << " to " << new_id_str << " reason: " << strerror(errno) << LL_ENDL; } return TRUE; -- cgit v1.2.3 From 53cae8b21f0f77fbb1be22c64deee9b6a3f237f7 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 11 Dec 2020 16:42:10 +0200 Subject: SL-14505 FIXED [Win10] The viewer isn't started on the non-English system locale --- indra/llfilesystem/llfilesystem.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'indra/llfilesystem/llfilesystem.cpp') diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index 932ef2a9c6..64e0b9f193 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -34,8 +34,6 @@ #include "llfasttimer.h" #include "lldiskcache.h" -#include - const S32 LLFileSystem::READ = 0x00000001; const S32 LLFileSystem::WRITE = 0x00000002; const S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE @@ -64,7 +62,7 @@ bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType fil const std::string extra_info = ""; const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info); - std::ifstream file(filename, std::ios::binary); + llifstream file(filename, std::ios::binary); if (file.is_open()) { file.seekg(0, std::ios::end); @@ -81,7 +79,7 @@ bool LLFileSystem::removeFile(const LLUUID& file_id, const LLAssetType::EType fi const std::string extra_info = ""; const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info); - std::remove(filename.c_str()); + LLFile::remove(filename.c_str()); return true; } @@ -102,7 +100,7 @@ bool LLFileSystem::renameFile(const LLUUID& old_file_id, const LLAssetType::ETyp // Rename needs the new file to not exist. LLFileSystem::removeFile(new_file_id, new_file_type); - if (std::rename(old_filename.c_str(), new_filename.c_str())) + if (LLFile::rename(old_filename, new_filename) != 0) { // We would like to return FALSE here indicating the operation // failed but the original code does not and doing so seems to @@ -123,7 +121,7 @@ S32 LLFileSystem::getFileSize(const LLUUID& file_id, const LLAssetType::EType fi const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id_str, file_type, extra_info); S32 file_size = 0; - std::ifstream file(filename, std::ios::binary); + llifstream file(filename, std::ios::binary); if (file.is_open()) { file.seekg(0, std::ios::end); @@ -142,7 +140,7 @@ BOOL LLFileSystem::read(U8* buffer, S32 bytes) const std::string extra_info = ""; const std::string filename = LLDiskCache::getInstance()->metaDataToFilepath(id, mFileType, extra_info); - std::ifstream file(filename, std::ios::binary); + llifstream file(filename, std::ios::binary); if (file.is_open()) { file.seekg(mPosition, std::ios::beg); @@ -197,7 +195,7 @@ BOOL LLFileSystem::write(const U8* buffer, S32 bytes) if (mMode == APPEND) { - std::ofstream ofs(filename, std::ios::app | std::ios::binary); + llofstream ofs(filename, std::ios::app | std::ios::binary); if (ofs) { ofs.write((const char*)buffer, bytes); @@ -207,7 +205,7 @@ BOOL LLFileSystem::write(const U8* buffer, S32 bytes) } else { - std::ofstream ofs(filename, std::ios::binary); + llofstream ofs(filename, std::ios::binary); if (ofs) { ofs.write((const char*)buffer, bytes); -- cgit v1.2.3