2011-04-14 07:04:13 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
2011-06-29 02:58:34 +00:00
|
|
|
|
namespace Substrate.Core
|
2011-04-14 07:04:13 +00:00
|
|
|
|
{
|
2011-05-13 03:09:57 +00:00
|
|
|
|
public class ChunkCache
|
2011-04-14 07:04:13 +00:00
|
|
|
|
{
|
2011-05-13 03:09:57 +00:00
|
|
|
|
private LRUCache<ChunkKey, ChunkRef> _cache;
|
2011-04-14 07:04:13 +00:00
|
|
|
|
private Dictionary<ChunkKey, ChunkRef> _dirty;
|
|
|
|
|
|
|
|
|
|
public ChunkCache ()
|
|
|
|
|
{
|
2011-05-13 03:09:57 +00:00
|
|
|
|
_cache = new LRUCache<ChunkKey, ChunkRef>(256);
|
2011-04-14 07:04:13 +00:00
|
|
|
|
_dirty = new Dictionary<ChunkKey, ChunkRef>();
|
2011-05-13 03:09:57 +00:00
|
|
|
|
|
|
|
|
|
_cache.RemoveCacheValue += EvictionHandler;
|
2011-04-14 07:04:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region IChunkCache Members
|
|
|
|
|
|
|
|
|
|
public bool Insert (ChunkRef chunk)
|
|
|
|
|
{
|
|
|
|
|
ChunkKey key = new ChunkKey(chunk.X, chunk.Z);
|
|
|
|
|
|
2011-08-14 19:32:46 +00:00
|
|
|
|
_dirty.Remove(key);
|
|
|
|
|
|
2011-05-13 03:09:57 +00:00
|
|
|
|
ChunkRef c;
|
|
|
|
|
if (!_cache.TryGetValue(key, out c)) {
|
|
|
|
|
_cache[key] = chunk;
|
2011-04-14 07:04:13 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Remove (ChunkKey key)
|
|
|
|
|
{
|
|
|
|
|
_dirty.Remove(key);
|
|
|
|
|
return _cache.Remove(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ChunkRef Fetch (ChunkKey key)
|
|
|
|
|
{
|
2011-05-13 03:09:57 +00:00
|
|
|
|
ChunkRef c;
|
2011-08-14 19:32:46 +00:00
|
|
|
|
if (_dirty.TryGetValue(key, out c)) {
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_cache.TryGetValue(key, out c)) {
|
|
|
|
|
return c;
|
2011-04-14 07:04:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-14 19:32:46 +00:00
|
|
|
|
return null;
|
2011-04-14 07:04:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerator<ChunkRef> GetDirtyEnumerator ()
|
|
|
|
|
{
|
|
|
|
|
return _dirty.Values.GetEnumerator();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearDirty ()
|
|
|
|
|
{
|
|
|
|
|
_dirty.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-13 03:09:57 +00:00
|
|
|
|
public void SyncDirty ()
|
|
|
|
|
{
|
|
|
|
|
foreach (KeyValuePair<ChunkKey, ChunkRef> e in _cache) {
|
|
|
|
|
if (e.Value.IsDirty) {
|
|
|
|
|
_dirty[e.Key] = e.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void EvictionHandler (object sender, LRUCache<ChunkKey, ChunkRef>.CacheValueArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.Value.IsDirty) {
|
|
|
|
|
_dirty[e.Key] = e.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-14 07:04:13 +00:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|