Exposing access to the worlds' ChunkCaches.

This commit is contained in:
Justin Aquadro 2011-12-17 01:43:41 -05:00
parent b2981ac04f
commit ce3a3537d0
2 changed files with 82 additions and 0 deletions

View file

@ -26,6 +26,8 @@ namespace Substrate
private Dictionary<int, BetaChunkManager> _chunkMgrs;
private Dictionary<int, BlockManager> _blockMgrs;
private Dictionary<int, ChunkCache> _caches;
private PlayerManager _playerMan;
private BetaDataManager _dataMan;
@ -36,6 +38,8 @@ namespace Substrate
_regionMgrs = new Dictionary<int, RegionManager>();
_chunkMgrs = new Dictionary<int, BetaChunkManager>();
_blockMgrs = new Dictionary<int, BlockManager>();
_caches = new Dictionary<int, ChunkCache>();
}
/// <summary>
@ -152,6 +156,28 @@ namespace Substrate
}
}
/// <summary>
/// Gets the <see cref="ChunkCache"/> currently managing chunks in the default dimension.
/// </summary>
/// <returns>The <see cref="ChunkCache"/> for the default dimension, or null if the dimension was not found.</returns>
public ChunkCache GetChunkCache ()
{
return GetChunkCache(Dimension.DEFAULT);
}
/// <summary>
/// Gets the <see cref="ChunkCache"/> currently managing chunks in the given dimension.
/// </summary>
/// <param name="dim">The id of a dimension to look up.</param>
/// <returns>The <see cref="ChunkCache"/> for the given dimension, or null if the dimension was not found.</returns>
public ChunkCache GetChunkCache (int dim)
{
if (_caches.ContainsKey(dim)) {
return _caches[dim];
}
return null;
}
/// <summary>
/// Opens an existing Beta-compatible Minecraft world and returns a new <see cref="BetaWorld"/> to represent it.
/// </summary>
@ -276,6 +302,8 @@ namespace Substrate
_regionMgrs[dim] = rm;
_chunkMgrs[dim] = cm;
_blockMgrs[dim] = bm;
_caches[dim] = cc;
}
private BetaWorld OpenWorld (string path)

View file

@ -3,16 +3,29 @@ using System.Collections.Generic;
namespace Substrate.Core
{
/// <summary>
/// An LRU-based caching data structure for holding references to <see cref="ChunkRef"/> objects.
/// </summary>
/// <remarks>The <see cref="ChunkCache"/> 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.</remarks>
public class ChunkCache
{
private LRUCache<ChunkKey, ChunkRef> _cache;
private Dictionary<ChunkKey, ChunkRef> _dirty;
/// <summary>
/// Creates a new <see cref="ChunkCache"/> with the default capacity of 256 chunks.
/// </summary>
public ChunkCache ()
: this(256)
{
}
/// <summary>
/// Creates a new <see cref="ChunkCache"/> with the given chunk capacity.
/// </summary>
/// <param name="cacheSize">The capacity of the LRU-portion of the cache.</param>
public ChunkCache (int cacheSize)
{
_cache = new LRUCache<ChunkKey, ChunkRef>(cacheSize);
@ -23,6 +36,13 @@ namespace Substrate.Core
#region IChunkCache Members
/// <summary>
/// Inserts a new chunk into the cache.
/// </summary>
/// <param name="chunk">The <see cref="ChunkRef"/> to add to the cache.</param>
/// <returns><c>True</c> if the chunk did not already exist in the cache, <c>false</c> otherwise.</returns>
/// <remarks>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.</remarks>
public bool Insert (ChunkRef chunk)
{
ChunkKey key = new ChunkKey(chunk.X, chunk.Z);
@ -38,12 +58,25 @@ namespace Substrate.Core
return false;
}
/// <summary>
/// Removes a chunk from the cache.
/// </summary>
/// <param name="key">The key identifying which <see cref="ChunkRef"/> to try and remove.</param>
/// <returns><c>True</c> if the chunk was in the LRU-portion of the cache and removed, <c>False</c> otherwise.</returns>
/// <remarks>The chunk will also be removed from the dirty list, if it is currently in it.</remarks>
public bool Remove (ChunkKey key)
{
_dirty.Remove(key);
return _cache.Remove(key);
}
/// <summary>
/// Attempts to get a chunk from the LRU- or dirty-portions of the cache.
/// </summary>
/// <param name="key">The key identifying which <see cref="ChunkRef"/> to find.</param>
/// <returns>The cached <see cref="ChunkRef"/> if it was found anywhere in the cache, or <c>null</c> if it was not found.</returns>
/// <remarks>If the <see cref="ChunkRef"/> 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.</remarks>
public ChunkRef Fetch (ChunkKey key)
{
ChunkRef c;
@ -58,16 +91,37 @@ namespace Substrate.Core
return null;
}
/// <summary>
/// Gets an enumerator to iterate over all of the <see cref="ChunkRef"/> objects currently in the dirty list.
/// </summary>
/// <returns>An enumerator over all of the dirty <see cref="ChunkRef"/> objects.</returns>
public IEnumerator<ChunkRef> GetDirtyEnumerator ()
{
return _dirty.Values.GetEnumerator();
}
/// <summary>
/// Clears all chunks from the LRU list.
/// </summary>
/// <remarks>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 <see cref="ClearDirty"/>.</remarks>
public void Clear ()
{
_cache.Clear();
}
/// <summary>
/// Clears all chunks from the dirty list.
/// </summary>
public void ClearDirty ()
{
_dirty.Clear();
}
/// <summary>
/// Scans the LRU list for any dirty chunks, and adds them to the dirty list.
/// </summary>
public void SyncDirty ()
{
foreach (KeyValuePair<ChunkKey, ChunkRef> e in _cache) {