400行代码实现本地Key-Value缓存(三)
hCode = key.HashCode();
uint32_t index = hashCode % m_HeadAddr->m_TableLen;
Array *tmpArray = m_ArrayAddr + index;
uint32_t nodeId = tmpArray->m_Head;
while(nodeId != m_InvalidId)
{
Entry *tmpNode = m_EntryAddr + nodeId;
if(tmpNode->m_Code == hashCode && key.Equals(tmpNode->m_Key)) break;
nodeId = tmpNode->m_Next;
}
return nodeId;
}
template
void HashTable::AddNodeToHead(uint32_t index, uint32_t nodeId)
{
if(index >= m_HeadAddr->m_TableLen || nodeId >= m_HeadAddr->m_NodeTotal) return;
Array *tmpArray = m_ArrayAddr + index;
Entry *tmpNode = m_EntryAddr + nodeId;
if(m_InvalidId == tmpArray->m_Head)
{
tmpArray->m_Head = nodeId;
tmpArray->m_Tail = nodeId;
}
else
{
tmpNode->m_Next = tmpArray->m_Head;
(m_EntryAddr + tmpArray->m_Head)->m_Prev = nodeId;
tmpArray->m_Head = nodeId;
}
}
template
bool HashTable::MoveNodeToHead(uint32_t index, uint32_t nodeId)
{
if(index >= m_HeadAddr->m_TableLen || nodeId >= m_HeadAddr->m_NodeTotal) return false;
Array *tmpArray = m_ArrayAddr + index;
Entry *tmpNode = m_EntryAddr + nodeId;
//already head
if(tmpArray->m_Head == nodeId)
{
return true;
}
uint32_t nodePrev = tmpNode->m_Prev;
uint32_t nodeNext = tmpNode->m_Next;
(m_EntryAddr+nodePrev)->m_Next = nodeNext;
if(nodeNext != m_InvalidId)
{
(m_EntryAddr+nodeNext)->m_Prev = nodePrev;
}
else
{
tmpArray->m_Tail = nodePrev;
}
tmpNode->m_Prev = m_InvalidId;
tmpNode->m_Next = tmpArray->m_Head;
(m_EntryAddr + tmpArray->m_Head)->m_Prev = nodeId;
tmpArray->m_Head = nodeId;
return true;
}
template
bool HashTable::RecycleNode(uint32_t index, uint32_t nodeId)
{
if(index >
= m_HeadAddr->m_TableLen || nodeId >= m_HeadAddr->m_NodeTotal) return false;
Array *tmpArray = m_ArrayAddr + index;
Entry *tmpNode = m_EntryAddr + nodeId;
uint32_t nodePrev = tmpNode->m_Prev;
uint32_t nodeNext = tmpNode->m_Next;
if(nodePrev != m_InvalidId)
{
(m_EntryAddr + nodePrev)->m_Next = nodeNext;
}
else
{
tmpArray->m_Head = nodeNext;
}
if(nodeNext != m_InvalidId)
{
(m_EntryAddr + nodeNext)->m_Prev = nodePrev;
}
else
{
tmpArray->m_Tail = nodePrev;
}
(m_EntryAddr+nodeId)->m_Next = m_HeadAddr->m_RecycleHead;
m_HeadAddr->m_RecycleHead = nodeId;
--(m_HeadAddr->m_UsedCount);
return true;
}
template
uint32_t HashTable::GetTailNodeId(uint32_t index)
{
if(index >= m_HeadAddr->m_TableLen) return m_InvalidId;
Array *tmpArray = m_ArrayAddr + index;
return tmpArray->m_Tail;
}
template
uint32_t HashTable::GetFreeNode()
{
uint32_t nodeId = m_InvalidId;
if(m_HeadAddr->m_UsedCount < m_HeadAddr->m_FreeBase)//get from recycle list
{
nodeId = m_HeadAddr->m_RecycleHead;
m_HeadAddr->m_RecycleHead = (m_EntryAddr+nodeId)->m_Next;
++(m_HeadAddr->m_UsedCount);
}
else if(m_HeadAddr->m_UsedCount < m_HeadAddr->m_NodeTotal)//get from free mem
{
nodeId = m_HeadAddr->m_FreeBase;
++(m_HeadAddr->m_FreeBase);
++(m_HeadAddr->m_UsedCount);
}
else
{
nodeId = m_InvalidId;
}
//init node
if(nodeId < m_HeadAddr->m_NodeTotal)
{
Entry *tmpNode = m_EntryAddr + nodeId;
memset(tmpNode, 0, sizeof(Entry));
tmpNode->m_Next = m_InvalidId;
tmpNode->m_Prev = m_InvalidId;
}
return nodeId;
}