forked from mirrors/NBTExplorer
Exposing access to the worlds' ChunkCaches.
This commit is contained in:
parent
b2981ac04f
commit
ce3a3537d0
2 changed files with 82 additions and 0 deletions
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue