From ce3a3537d0c3865e590c45a62a4de61e74541e12 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sat, 17 Dec 2011 01:43:41 -0500 Subject: [PATCH] Exposing access to the worlds' ChunkCaches. --- SubstrateCS/Source/BetaWorld.cs | 28 ++++++++++++++ SubstrateCS/Source/Core/ChunkCache.cs | 54 +++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/SubstrateCS/Source/BetaWorld.cs b/SubstrateCS/Source/BetaWorld.cs index edfbc40..8e2193c 100644 --- a/SubstrateCS/Source/BetaWorld.cs +++ b/SubstrateCS/Source/BetaWorld.cs @@ -26,6 +26,8 @@ namespace Substrate private Dictionary _chunkMgrs; private Dictionary _blockMgrs; + private Dictionary _caches; + private PlayerManager _playerMan; private BetaDataManager _dataMan; @@ -36,6 +38,8 @@ namespace Substrate _regionMgrs = new Dictionary(); _chunkMgrs = new Dictionary(); _blockMgrs = new Dictionary(); + + _caches = new Dictionary(); } /// @@ -152,6 +156,28 @@ namespace Substrate } } + /// + /// Gets the currently managing chunks in the default dimension. + /// + /// The for the default dimension, or null if the dimension was not found. + public ChunkCache GetChunkCache () + { + return GetChunkCache(Dimension.DEFAULT); + } + + /// + /// Gets the currently managing chunks in the given dimension. + /// + /// The id of a dimension to look up. + /// The for the given dimension, or null if the dimension was not found. + public ChunkCache GetChunkCache (int dim) + { + if (_caches.ContainsKey(dim)) { + return _caches[dim]; + } + return null; + } + /// /// Opens an existing Beta-compatible Minecraft world and returns a new to represent it. /// @@ -276,6 +302,8 @@ namespace Substrate _regionMgrs[dim] = rm; _chunkMgrs[dim] = cm; _blockMgrs[dim] = bm; + + _caches[dim] = cc; } private BetaWorld OpenWorld (string path) diff --git a/SubstrateCS/Source/Core/ChunkCache.cs b/SubstrateCS/Source/Core/ChunkCache.cs index 801ac4e..7404e67 100644 --- a/SubstrateCS/Source/Core/ChunkCache.cs +++ b/SubstrateCS/Source/Core/ChunkCache.cs @@ -3,16 +3,29 @@ using System.Collections.Generic; namespace Substrate.Core { + /// + /// An LRU-based caching data structure for holding references to objects. + /// + /// The class maintains a separate dictionary on the side for tracking + /// dirty chunks. References to dirty chunks will still be held even if the chunk has been evicted from + /// the normal LRU cache. The dirty list is reset when the world is saved, or manually cleared. public class ChunkCache { private LRUCache _cache; private Dictionary _dirty; + /// + /// Creates a new with the default capacity of 256 chunks. + /// public ChunkCache () : this(256) { } + /// + /// Creates a new with the given chunk capacity. + /// + /// The capacity of the LRU-portion of the cache. public ChunkCache (int cacheSize) { _cache = new LRUCache(cacheSize); @@ -23,6 +36,13 @@ namespace Substrate.Core #region IChunkCache Members + /// + /// Inserts a new chunk into the cache. + /// + /// The to add to the cache. + /// True if the chunk did not already exist in the cache, false otherwise. + /// If the chunk does not already exist and the list is full, then the least-recently used chunk in the cache will be evicted + /// to make room for the new chunk. If the chunk is present in the dirty list, it will be removed. public bool Insert (ChunkRef chunk) { ChunkKey key = new ChunkKey(chunk.X, chunk.Z); @@ -38,12 +58,25 @@ namespace Substrate.Core return false; } + /// + /// Removes a chunk from the cache. + /// + /// The key identifying which to try and remove. + /// True if the chunk was in the LRU-portion of the cache and removed, False otherwise. + /// The chunk will also be removed from the dirty list, if it is currently in it. public bool Remove (ChunkKey key) { _dirty.Remove(key); return _cache.Remove(key); } + /// + /// Attempts to get a chunk from the LRU- or dirty-portions of the cache. + /// + /// The key identifying which to find. + /// The cached if it was found anywhere in the cache, or null if it was not found. + /// If the is found in the LRU-portion of the cache, it will be moved to the front of the + /// LRU list, making future eviction less likely. public ChunkRef Fetch (ChunkKey key) { ChunkRef c; @@ -58,16 +91,37 @@ namespace Substrate.Core return null; } + /// + /// Gets an enumerator to iterate over all of the objects currently in the dirty list. + /// + /// An enumerator over all of the dirty objects. public IEnumerator GetDirtyEnumerator () { return _dirty.Values.GetEnumerator(); } + /// + /// Clears all chunks from the LRU list. + /// + /// This method will clear all chunks from the LRU-portion of the cache, including any chunks that are + /// dirty but have not yet been discovered and added to the dirty list. Chunks already in the dirty list will + /// not be affected. To clear dirty chunks as well, see . + public void Clear () + { + _cache.Clear(); + } + + /// + /// Clears all chunks from the dirty list. + /// public void ClearDirty () { _dirty.Clear(); } + /// + /// Scans the LRU list for any dirty chunks, and adds them to the dirty list. + /// public void SyncDirty () { foreach (KeyValuePair e in _cache) {