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
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;
|
|
}
|
|
}
|
|
}
|
|
|