diff options
| author | Callum Prentice <callum@gmail.com> | 2020-10-07 15:25:12 -0700 | 
|---|---|---|
| committer | Callum Prentice <callum@gmail.com> | 2020-10-07 15:25:12 -0700 | 
| commit | 08dfc0836fb12855d0c07d811e2909400d5b74f3 (patch) | |
| tree | 383c203f7084086ae5e3804cd126dc32c4048516 | |
| parent | a0ea119623b8bda445f86afdb0ea7b5833c8e171 (diff) | |
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
| -rw-r--r-- | indra/llfilesystem/lldiskcache.cpp | 134 | ||||
| -rw-r--r-- | indra/llfilesystem/lldiskcache.h | 82 | ||||
| -rw-r--r-- | indra/llfilesystem/llfilesystem.cpp | 238 | ||||
| -rw-r--r-- | indra/llfilesystem/llfilesystem.h | 82 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 26 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 15 | 
6 files changed, 307 insertions, 270 deletions
| diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index 4b2ba0dd79..4b82cf3cce 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -25,41 +25,31 @@   */  #include "linden_common.h" -#include "lluuid.h" +#include "llassettype.h"  #include "lldir.h" - -#include "lldiskcache.h" -  #include <boost/filesystem.hpp>  #include <boost/range/iterator_range.hpp> -  #include <chrono> -#include <thread> -#include <algorithm> -LLDiskCache::LLDiskCache(const std::string cache_dir) : +#include "lldiskcache.h" + +LLDiskCache::LLDiskCache(const std::string cache_dir, +                         const int max_size_bytes, +                         const bool enable_cache_debug_info) :      mCacheDir(cache_dir), -    mMaxSizeBytes(mDefaultSizeBytes) +    mMaxSizeBytes(max_size_bytes), +    mEnableCacheDebugInfo(enable_cache_debug_info)  { -    // no access to LLControlGroup / gSavedSettings so use the system environment -    // to trigger additional debugging on top of the default "we purged the cache" -    mCacheDebugInfo = true; -    if (getenv("LL_CACHE_DEBUGGING") != nullptr) -    { -        mCacheDebugInfo = true; -    } +    // the prefix used for cache filenames to disambiguate them from other files +    mCacheFilenamePrefix = "sl_cache";      // create cache dir if it does not exist      boost::filesystem::create_directory(cache_dir);  } -LLDiskCache::~LLDiskCache() -{ -} -  void LLDiskCache::purge()  { -    if (mCacheDebugInfo) +    if (mEnableCacheDebugInfo)      {          LL_INFOS() << "Total dir size before purge is " << dirFileSize(mCacheDir) << LL_ENDL;      } @@ -75,11 +65,14 @@ void LLDiskCache::purge()          {              if (boost::filesystem::is_regular_file(entry))              { -                uintmax_t file_size = boost::filesystem::file_size(entry); -                const std::string file_path = entry.path().string(); -                const std::time_t file_time = boost::filesystem::last_write_time(entry); +                if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos) +                { +                    uintmax_t file_size = boost::filesystem::file_size(entry); +                    const std::string file_path = entry.path().string(); +                    const std::time_t file_time = boost::filesystem::last_write_time(entry); -                file_info.push_back(file_info_t(file_time, { file_size, file_path })); +                    file_info.push_back(file_info_t(file_time, { file_size, file_path })); +                }              }          }      } @@ -107,7 +100,7 @@ void LLDiskCache::purge()              action = "  KEEP:";          } -        if (mCacheDebugInfo) +        if (mEnableCacheDebugInfo)          {              // have to do this because of LL_INFO/LL_END weirdness              std::ostringstream line; @@ -121,7 +114,7 @@ void LLDiskCache::purge()          }      } -    if (mCacheDebugInfo) +    if (mEnableCacheDebugInfo)      {          auto end_time = std::chrono::high_resolution_clock::now();          auto execute_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(); @@ -130,9 +123,78 @@ void LLDiskCache::purge()      }  } +const std::string LLDiskCache::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<LLAssetType::EType, std::string> 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 LLDiskCache::metaDataToFilepath(const std::string id, +        LLAssetType::EType at, +        const std::string extra_info) +{ +    std::ostringstream file_path; + +    file_path << mCacheDir; +    file_path << gDirUtilp->getDirDelimiter(); +    file_path << mCacheFilenamePrefix; +    file_path << "_"; +    file_path << id; +    file_path << "_"; +    file_path << (extra_info.empty() ? "0" : extra_info); +    file_path << "_"; +    file_path << assetTypeToString(at); +    file_path << ".asset"; + +    LL_INFOS() << "filepath.str() = " << file_path.str() << LL_ENDL; + +    return file_path.str(); +} +  /** - * Update the "last write time" of a file to "now". This must be called whenever a  - * file in the cache is read (not written) so that the last time the file was  + * Update the "last write time" of a file to "now". This must be called whenever a + * file in the cache is read (not written) so that the last time the file was   * accessed which is used in the mechanism for purging the cache, is up to date.   */  void LLDiskCache::updateFileAccessTime(const std::string file_path) @@ -144,8 +206,8 @@ void LLDiskCache::updateFileAccessTime(const std::string file_path)  /**   * Clear the cache by removing all the files in the cache directory   * individually. It's important to maintain control of which directory - * if passed in and not let the user inadvertently (or maliciously) set  - * it to an random location like your project source or OS system directory  + * if passed in and not let the user inadvertently (or maliciously) set + * it to an random location like your project source or OS system directory   */  void LLDiskCache::clearCache(const std::string cache_dir)  { @@ -155,7 +217,10 @@ void LLDiskCache::clearCache(const std::string cache_dir)          {              if (boost::filesystem::is_regular_file(entry))              { -                boost::filesystem::remove(entry); +                if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos) +                { +                    boost::filesystem::remove(entry); +                }              }          }      } @@ -181,7 +246,10 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir)          {              if (boost::filesystem::is_regular_file(entry))              { -                total_file_size += boost::filesystem::file_size(entry); +                if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos) +                { +                    total_file_size += boost::filesystem::file_size(entry); +                }              }          }      } diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h index 1618cec6a6..12599a132e 100644 --- a/indra/llfilesystem/lldiskcache.h +++ b/indra/llfilesystem/lldiskcache.h @@ -27,15 +27,50 @@  #ifndef _LLDISKCACHE  #define _LLDISKCACHE -class LLDiskCache +#include "llsingleton.h" + +class LLDiskCache : +    public LLParamSingleton<LLDiskCache>  {      public: -        LLDiskCache(const std::string cache_dir); -        ~LLDiskCache(); +        LLSINGLETON(LLDiskCache, +                    const std::string cache_dir, +                    const int max_size_bytes, +                    const bool enable_cache_debug_info); +        virtual ~LLDiskCache() = default; + +    public: +        ///** +        // * The location of the cache dir is set in llappviewer at startup via the +        // * saved settings parameters.  We do not have access to those saved settings +        // * here in LLCommon so we must provide an accessor for other classes to use +        // * when they need it - e.g. LLFilesystem needs the path so it can write files +        // * to it. +        // */ +        //const std::string getCacheDirName() { return mCacheDir; } + +        ///** +        // * Each cache filename has a prefix inserted (see definition of the +        // * mCacheFilenamePrefix variable below for why) but the LLFileSystem +        // * component needs access to it to in order to create the file so we +        // * expose it by a getter here. +        // */ +        //const std::string getCacheFilenamePrefix() { return mCacheFilenamePrefix; }          /** -         * Update the "last write time" of a file to "now". This must be called whenever a  -         * file in the cache is read (not written) so that the last time the file was  +         * Construct a filename and path to it based on the file meta data +         * (id, asset type, additional 'extra' info like discard level perhaps) +         * Worth pointing out that this function used to be in LLFileSystem but +         * so many things had to be pushed back there to accomodate it, that I +         * decided to move it here.  Still not sure that's completely right. +         */ +        const std::string metaDataToFilepath(const std::string id, +                                             LLAssetType::EType at, +                                             const std::string extra_info); + +        /** +         * Update the "last write time" of a file to "now". This must be called whenever a +         * file in the cache is read (not written) so that the last time the file was           * accessed which is used in the mechanism for purging the cache, is up to date.           */          void updateFileAccessTime(const std::string file_path); @@ -51,28 +86,26 @@ class LLDiskCache           */          void clearCache(const std::string cache_dir); -        /** -         * Manage max size in bytes of cache - use a discrete setter/getter so the value can -         * be changed in the preferences and cache cleared/purged without restarting viewer -         * to instantiate this class again. -         */ -        void setMaxSizeBytes(const uintmax_t size_bytes) { mMaxSizeBytes = size_bytes; } -        uintmax_t getMaxSizeBytes() const { return mMaxSizeBytes; } -      private:          /**           * Utility function to gather the total size the files in a given -         * directory. Primarily used here to determine the directory size  +         * directory. Primarily used here to determine the directory size           * before and after the cache purge           */          uintmax_t dirFileSize(const std::string dir); +        /** +         * Utility function to convert an LLAssetType enum into a +         * string that we use as part of the cache file filename +         */ +        const std::string assetTypeToString(LLAssetType::EType at); +      private:          /** -         * Default of 20MB seems reasonable - it will likely be reset -         * immediately anyway using a value from the Viewer settings +         * The maximum size of the cache in bytes. After purge is called, the +         * total size of the cache files in the cache directory will be +         * less than this value           */ -        const uintmax_t mDefaultSizeBytes = 20 * 1024 * 1024;          uintmax_t mMaxSizeBytes;          /** @@ -84,11 +117,20 @@ class LLDiskCache          std::string mCacheDir;          /** -         * This is set from the CacheDebugInfo global setting and -         * when enabled, displays additional debugging information in +         * The prefix inserted at the start of a cache file filename to +         * help identify it as a cache file. It's probably not required +         * (just the presence in the cache folder is enough) but I am +         * paranoid about the cache folder being set to something bad +         * like the users' OS system dir by mistake or maliciously and +         * this will help to offset any damage if that happens. +         */ +        std::string mCacheFilenamePrefix; + +        /** +         * When enabled, displays additional debugging information in           * various parts of the code           */ -        bool mCacheDebugInfo; +        bool mEnableCacheDebugInfo;  };  #endif // _LLDISKCACHE 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 <fstream> -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<LLAssetType::EType, std::string> 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; -} diff --git a/indra/llfilesystem/llfilesystem.h b/indra/llfilesystem/llfilesystem.h index 5d87de9bf8..46bf1bd775 100644 --- a/indra/llfilesystem/llfilesystem.h +++ b/indra/llfilesystem/llfilesystem.h @@ -1,5 +1,5 @@ -/**  -/**  +/** +/**   * @file filesystem.h   * @brief Simulate local file system operations.   * @Note The initial implementation does actually use standard C++ @@ -9,21 +9,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$   */ @@ -37,51 +37,43 @@  class LLFileSystem  { -public: -	LLFileSystem(const LLUUID &file_id, const LLAssetType::EType file_type, S32 mode = LLFileSystem::READ); -	~LLFileSystem(); +    public: +        LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode = LLFileSystem::READ); +        ~LLFileSystem(); -	BOOL read(U8 *buffer, S32 bytes, BOOL async = FALSE, F32 priority = 128.f);	/* Flawfinder: ignore */  -	BOOL isReadComplete(); -	S32  getLastBytesRead(); -	BOOL eof(); +        BOOL read(U8* buffer, S32 bytes); +        S32  getLastBytesRead(); +        BOOL eof(); -	BOOL write(const U8 *buffer, S32 bytes); -	BOOL seek(S32 offset, S32 origin = -1); -	S32  tell() const; +        BOOL write(const U8* buffer, S32 bytes); +        BOOL seek(S32 offset, S32 origin = -1); +        S32  tell() const; -	S32 getSize(); -	S32 getMaxSize(); -	BOOL rename(const LLUUID &new_id, const LLAssetType::EType new_type); -	BOOL remove(); +        S32 getSize(); +        S32 getMaxSize(); +        BOOL rename(const LLUUID& new_id, const LLAssetType::EType new_type); +        BOOL remove(); -    static bool getExists(const LLUUID &file_id, const LLAssetType::EType file_type); -    static bool removeFile(const LLUUID &file_id, const LLAssetType::EType file_type); -    static bool renameFile(const LLUUID &old_file_id, const LLAssetType::EType old_file_type, -                           const LLUUID &new_file_id, const LLAssetType::EType new_file_type); -    static S32 getFileSize(const LLUUID &file_id, const LLAssetType::EType file_type); -	 -	static void initClass(); -	static void cleanupClass(); +        static bool getExists(const LLUUID& file_id, const LLAssetType::EType file_type); +        static bool removeFile(const LLUUID& file_id, const LLAssetType::EType file_type); +        static bool renameFile(const LLUUID& old_file_id, const LLAssetType::EType old_file_type, +                               const LLUUID& new_file_id, const LLAssetType::EType new_file_type); +        static S32 getFileSize(const LLUUID& file_id, const LLAssetType::EType file_type); -public: -	static const S32 READ; -	static const S32 WRITE; -	static const S32 READ_WRITE; -	static const S32 APPEND; -	 -protected: -	LLAssetType::EType mFileType; -    BOOL    mReadComplete; -	LLUUID	mFileID; -	S32		mPosition; -	S32		mMode; -	S32		mBytesRead; +    public: +        static const S32 READ; +        static const S32 WRITE; +        static const S32 READ_WRITE; +        static const S32 APPEND; -private: -    static const std::string idToFilepath(const std::string id, LLAssetType::EType at); -    static std::string mCacheDirName; -    static LLDiskCache* mDiskCache; +    protected: +        LLAssetType::EType mFileType; +        LLUUID  mFileID; +        S32     mPosition; +        S32     mMode; +        S32     mBytesRead; +//private: +//    static const std::string idToFilepath(const std::string id, LLAssetType::EType at);  };  #endif  // LL_FILESYSTEM_H diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0123bc32af..2e65aef9a2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1351,10 +1351,10 @@        <key>Value</key>        <integer>23</integer>      </map> -    <key>CacheDebugInfo</key> +    <key>EnableCacheDebugInfo</key>      <map>        <key>Comment</key> -      <string>When enabled, display additional cache debugging information</string> +      <string>When set, display additional cache debugging information</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -1362,6 +1362,28 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>DiskCacheMaxSizeMB</key> +    <map> +      <key>Comment</key> +      <string>The maximum number of MB to use for the new disk cache</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>U32</string> +      <key>Value</key> +      <integer>10</integer> +    </map> +    <key>DiskCacheDirName</key> +    <map> +      <key>Comment</key> +      <string>The name of the disk cache (within the standard Viewer disk cache directory)</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>dcache</string> +    </map>      <key>CacheLocation</key>      <map>        <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0d25cb6dc8..1914ca89de 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -98,6 +98,7 @@  #include "lllogininstance.h"  #include "llprogressview.h"  #include "llvocache.h" +#include "lldiskcache.h"  #include "llvopartgroup.h"  #include "llweb.h"  #include "llfloatertexturefetchdebugger.h" @@ -115,7 +116,6 @@  #include "llprimitive.h"  #include "llurlaction.h"  #include "llurlentry.h" -#include "llfilesystem.h"  #include "llvolumemgr.h"  #include "llxfermanager.h"  #include "llphysicsextensions.h" @@ -1855,9 +1855,6 @@ bool LLAppViewer::cleanup()  	SUBSYSTEM_CLEANUP(LLWorldMapView);  	SUBSYSTEM_CLEANUP(LLFolderViewItem); -	LL_INFOS() << "Cleaning up disk cache" << LL_ENDL; -	SUBSYSTEM_CLEANUP(LLFileSystem); -  	LL_INFOS() << "Saving Data" << LL_ENDL;  	// Store the time of our current logoff @@ -4111,6 +4108,9 @@ bool LLAppViewer::initCache()  	{  		LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));  		purgeCache(); + +        // purge the new C++ file system based cache +        LLDiskCache::getInstance()->purge();  	}  	LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); @@ -4131,7 +4131,12 @@ bool LLAppViewer::initCache()  	LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); -	LLFileSystem::initClass(); +    // initialize the new disk cache using saved settings +    const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); +    const unsigned int cache_max_bytes = gSavedSettings.getU32("DiskCacheMaxSizeMB") * 1024 * 1024; +    const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); +    const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); +    LLDiskCache::initParamSingleton(cache_dir, cache_max_bytes, enable_cache_debug_info);      return true;  } | 
