You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

174 lines
4.4 KiB

using System;
using System.Collections.Generic;
namespace Sog
{
//结构对象需要实现这个接口
public interface IStructObject
{
int GetObjectID();
void SetObjectID(int id);
bool IsNull();//空结构,代替空指针,表示无效
}
public class StructMemoryCache<ST> where ST : struct, IStructObject
{
//数组
private ST m_empty;
private ST[] m_array;
private int[] m_indexStat;
public Queue<long> m_freeQueue = new Queue<long>();
public StructMemoryCache(long count)
{
m_empty.SetObjectID(-1);
m_array = new ST[count];
m_indexStat = new int[count];
//第一个默认为空,不要动了
ref ST tobject1 = ref m_array[0];
tobject1.SetObjectID(-1);
for (int i = 1; i < m_array.Length; i++)
{
//设置ID
ref ST tobject = ref m_array[i];
tobject.SetObjectID(i);
//对象id为0的不要了,方便代码处理,0表示无效
m_freeQueue.Enqueue(i);
}
}
public int GetTotalCount()
{
return m_array.Length;
}
public int GetFreeCount()
{
return m_freeQueue.Count;
}
public int GetUsedCount()
{
return GetTotalCount() - GetFreeCount();
}
public ref ST Malloc()
{
if (m_freeQueue.Count == 0)
{
TraceLog.Error("StructMemoryCache.Malloc no free space");
return ref m_empty;
}
long index = m_freeQueue.Dequeue();
if (m_indexStat[index] == 1)
{
TraceLog.Error("StructMemoryCache.Malloc index {0} already be used", index);
return ref m_empty;
}
m_indexStat[index] = 1;
m_array[index].SetObjectID((int)index);
return ref m_array[index];
}
// 自己管理index时, 不要调用Free, 也不要和Malloc()混用
// 最好不要自己管理index
public ref ST Malloc(long index)
{
if (m_freeQueue.Count == 0)
{
TraceLog.Error("StructMemoryCache.Malloc no free space");
return ref m_empty;
}
if (m_indexStat[index] == 1)
{
TraceLog.Error("StructMemoryCache.Malloc index {0} already be used", index);
return ref m_empty;
}
m_indexStat[index] = 1;
m_array[index].SetObjectID((int)index);
return ref m_array[index];
}
public void Free(ref ST tobject)
{
int index = tobject.GetObjectID();
if (m_indexStat[index] == 0)
{
return;
}
// objectId也必须清空
m_array[index].SetObjectID(-1);
m_indexStat[index] = 0;
m_freeQueue.Enqueue(index);
}
public void Free(long index)
{
if (m_indexStat[index] == 0)
{
return;
}
// objectId也必须清空
m_array[index].SetObjectID(-1);
m_indexStat[index] = 0;
m_freeQueue.Enqueue(index);
}
public ref ST GetByIndex(long index)
{
if (index >= m_indexStat.Length)
{
TraceLog.Trace("StructMemoryCache.GetByIndex index {0} is too large", index);
return ref m_empty;
}
if (m_indexStat[index] == 0)
{
//太多日志了
//TraceLog.Error("StructMemoryCache.GetByIndex index {0} is free, invalid", index);
return ref m_empty;
}
return ref m_array[index];
}
public int GetUsedPercent()
{
if (GetTotalCount() > 0)
{
return Convert.ToInt32(GetUsedCount() * 100.0 / GetTotalCount());
}
return 0;
}
public int GetUsedIndex(int startIdx)
{
for (int i = startIdx; i < m_indexStat.Length; i++)
{
if (m_indexStat[i] > 0)
{
return i;
}
}
return 0;
}
}
}