memcpy((char*)&E, (char*)&tag, sizeof(HashElem_t));
Hash_Save(&g_Hash, &E, &Addr, &c);
#include "main.h"
#if C_USE_TAG_HASH==1
//==============================================================================
// Variables
HashTable_t g_Hash;
/*==============================================================================
* Function:
* Input para1: Void
* Return: Void
==============================================================================*/
Status_t Hash_Initial(HashTable_t *pHash)
{
int i,m;
m = C_HASH_TABLE_SIZE;
pHash->Cnt = 0;
pHash->MaxCnt = m;
#if C_HASH_MALLOC
pHash->pElem = (HashElem_t*)malloc(m*sizeof(HashElem_t)); // 动态分配数组
//void *malloc(size_t size);
#endif
// memset((char*)&pHash, 0, sizeof(HashTable_t));
for(i=0;i<m;i++)
{
// memset((char*)&pHash->pElem[i].Value, 0, sizeof(HashValue_t));
memset((char*)&pHash->pElem[i], 0, sizeof(HashElem_t));
HashKeySource(pHash->pElem[i]) = C_HASH_KEY_NULL;
// pHash->pElem[i].Key = C_HASH_KEY_NULL;
pHash->AddrFifo.Addr[i] = C_HASH_ADDR_INVALID;
}
return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function:
* Input para1: Void
* Return: Void
==============================================================================*/
uint16_t Hash_Cnt(HashTable_t *pHash)
{
return(pHash->Cnt);
}
/*==============================================================================
* Function:
* Input para1: pHash 哈希表地址
* K 关键字
* Output para1: pAddr 存储地址
* c 冲突次数
* Return:
// 在开放定址哈希表pHash中查找关键码为K的元素,若查找成功,以pAddr指示待查数据
// 元素在表中位置,并返回SUCCESS;否则,以pAddr指示插入位置,并返回UNSUCCESS
// c用以计冲突次数,其初值置零,供建表插入时参考。算法9.17
==============================================================================*/
Status_t Hash_Find(HashTable_t *pHash, HashKey_t K, uint16_t *pAddr, uint16_t *c)
{
int m;
m = C_HASH_TABLE_SIZE;
*c = 0;
*pAddr = Hash(K); // 求得哈希地址
// if(pHash->pElem[*pAddr].Key == K)
if(HashKeySource(pHash->pElem[*pAddr]) == K)
{
return(C_HASH_STATUS_OK);
}
while(1)
{
(*c)++;
if((*c) >= m)
{
return(C_HASH_STATUS_ERROR); // 溢出
}
// *pAddr = (*pAddr+1) % m; /* 开放定址法的线性探测 */
*pAddr = Collision(*pAddr, 1); // 求得下一探查地址
//Collision(pAddr, *c); // 求得下一探查地址
if(HashKeySource(pHash->pElem[*pAddr]) == K)
{
break;
}
// if((pHash->pElem[*pAddr].Key == C_HASH_KEY_NULL)
// {
// return(C_HASH_STATUS_ERROR); //
// }
}
// memcpy((char*)pElem, (char*)&pHash->pElem[*pAddr], sizeof(HashElem_t));
return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function:
* Input para1: pHash 哈希表地址
* pNewElem 新元素
* Output para1: pAddr 存储地址
* c 冲突次数
* Return:
==============================================================================*/
Status_t Hash_Insert(HashTable_t *pHash, HashElem_t *pNewElem, uint16_t *pAddr, uint16_t *c)
{
Status_t ret;
if(pHash->Cnt >= pHash->MaxCnt)
{
return(C_HASH_STATUS_ERROR); // 满
}
ret = Hash_Find(&g_Hash, C_HASH_KEY_NULL, pAddr, c); // 找个空位
if(C_HASH_STATUS_OK != ret)
{
return(C_HASH_STATUS_ERROR);
}
memcpy((char*)&pHash->pElem[*pAddr], (char*)pNewElem, sizeof(HashElem_t)); // 保存
pHash->Cnt++;
return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function:
* Input para1: pHash 哈希表地址
* pNewElem 新元素
* Output para1: pAddr 存储地址
* c 冲突次数
* Return:
==============================================================================*/
//Status_t Hash_Insert_(HashTable_t *pHash, HashElem_t *pElem, uint16_t *pAddr, uint16_t *c)
//{
// int m;
//
// if(pHash->Cnt >= pHash->MaxCnt)
// {
// return(C_HASH_STATUS_ERROR); // 满
// }
// m = C_HASH_TABLE_SIZE;
// *c = 0;
//
*pAddr = Hash(pElem->Key); // 求得哈希地址
// *pAddr = Hash(HashKeySource((*pElem))); // 求得哈希地址
//
//
// while(1)
// {
// if(HashKeySource(pHash->pElem[*pAddr]) != C_HASH_KEY_NULL)
// { /* 如果不为空,则冲突 */
// (*c)++;
// if((*c)<m)
// {
// *pAddr = (*pAddr+1) % m; /* 开放定址法的线性探测 */
// // Collision(pAddr, *c); // 求得下一探查地址p
// }
// else
// {
// return(C_HASH_STATUS_ERROR); // 溢出
// }
// }
// else
// { /* 直到有空位后插入关键字 */
// //pHash->pElem[*pAddr].Key = pElem->Key;
// memcpy((char*)&pHash->pElem[*pAddr], (char*)pElem, sizeof(HashElem_t));
pHash->pElem[*pAddr].HashPos = *pAddr;
// pHash->Cnt++;
// break;
// }
// }
// return(C_HASH_STATUS_OK);
//}
/*==============================================================================
* Function:
* Input para1: pHash 哈希表地址
* pNewElem 新元素
* Output para1: pAddr 存储地址
* c 冲突次数
* Return:
==============================================================================*/
Status_t Hash_Save(HashTable_t *pHash, HashElem_t *pNewElem, uint16_t *pAddr, uint16_t *c)
{
int m;
// bool Hash_Repeat= false;//20170629 Seven 区别是否有重复数据
m = C_HASH_TABLE_SIZE;
*c = 0;
// *pAddr = Hash(pNewElem->Key); // 求得哈希地址
*pAddr = Hash(HashKeySource((*pNewElem))); // 求得哈希地址
while(1)
{
if(HashKeySource(pHash->pElem[*pAddr]) == HashKeySource((*pNewElem)))
{// 找到已有位置
if(pHash->pElem[*pAddr].UplodeCnt>=0)
{
(*pNewElem).UplodeCnt = pHash->pElem[*pAddr].UplodeCnt;//超时时间未到,不更新超时
}
else
{
}
// Hash_Repeat = false;
// // 补充测试
// if(0x7F != pHash->pElem[*pAddr].Bat)
// {
// return(C_HASH_STATUS_ERROR); // 溢出
// }
break;
}
if(HashKeySource(pHash->pElem[*pAddr]) == C_HASH_KEY_NULL)
{// 找到空位置
pHash->Cnt++;
Hash_AddrFifo_In(&g_Hash, *pAddr); //
break;
}
(*c)++;
if((*c) >= m)
{
return(C_HASH_STATUS_ERROR); // 溢出
}
*pAddr = Collision(*pAddr, 1); // 求得下一探查地址 /* 开放定址法的线性探测 */
}
memcpy((char*)&pHash->pElem[*pAddr],
(char*)pNewElem,
sizeof(HashElem_t)); // 保存
return(C_HASH_STATUS_OK);
// 方法2
// ret = Hash_Find(&g_Hash, pNewElem->Key, &Addr, &c);
// if(C_HASH_STATUS_OK != ret)
// {
// return(C_HASH_STATUS_ERROR);
// }
// memcpy((char*)&pHash->pElem[Addr], (char*)pNewElem, sizeof(HashElem_t));
//
// return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function: 按关键字查找并读出
* Input para1: pHash 哈希表地址
* K 关键字
* Output para1: pElem 元素地址
* pAddr 元素存储地址
* c 冲突次数
* Return:
==============================================================================*/
Status_t Hash_Read(HashTable_t *pHash, HashKey_t K, HashElem_t *pElem, uint16_t *pAddr, uint16_t *c)
{
Status_t ret;
ret = Hash_Find(&g_Hash, K, pAddr, c);
if(C_HASH_STATUS_OK != ret)
{
return(C_HASH_STATUS_ERROR);
}
memcpy((char*)pElem, (char*)&pHash->pElem[*pAddr], sizeof(HashElem_t));
return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function: 按关键字删除
* Input para1: pHash 哈希表地址
* K 关键字
* Output para1: pAddr 元素存储地址
* c 冲突次数
* Return:
==============================================================================*/
Status_t Hash_Remove(HashTable_t *pHash, HashKey_t K, uint16_t *pAddr, uint16_t *c)
{
Status_t ret;
// HashElem_t EmptyElem;
// EmptyElem.Key = C_HASH_KEY_NULL;
ret = Hash_Find(&g_Hash, K, pAddr, c);
if(C_HASH_STATUS_OK != ret)
{
return(C_HASH_STATUS_ERROR);
}
if(*pAddr >= C_HASH_TABLE_SIZE)
{
return(C_HASH_STATUS_ERROR);
}
// memcpy((char*)&pHash->pElem[*pAddr], (char*)EmptyElem, sizeof(HashElem_t));
HashKeySource((pHash->pElem[*pAddr])) = C_HASH_KEY_NULL;
return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function: 直接删除
* Input para1: pHash 哈希表地址
* pAddr 元素存储地址
* Return:
==============================================================================*/
Status_t Hash_Delete(HashTable_t *pHash, uint16_t *pAddr)
{
// HashElem_t EmptyElem;
// EmptyElem.Key = C_HASH_KEY_NULL;
if(*pAddr >= C_HASH_TABLE_SIZE)
{
return(C_HASH_STATUS_ERROR);
}
if(C_HASH_KEY_NULL != HashKeySource(pHash->pElem[*pAddr]))
{
if(pHash->Cnt > 0)
{
pHash->Cnt--;
}
}
// memcpy((char*)&pHash->pElem[*pAddr], (char*)EmptyElem, sizeof(HashElem_t));
HashKeySource((pHash->pElem[*pAddr])) = C_HASH_KEY_NULL;
return(C_HASH_STATUS_OK);
}
/*==============================================================================
* Function:
* Input para1: Void
* Return: Void
==============================================================================*/
int Hash_AddrFifo_In(HashTable_t *pHash, uint16_t NewAddr)
{
if(pHash->AddrFifo.WriteIndex>=C_HASH_ADDR_FIFO_SIZE)
{
return(-1);
}
//-------------------------------------------
pHash->AddrFifo.Addr[pHash->AddrFifo.WriteIndex] = NewAddr;
//-------------------------------------------
pHash->AddrFifo.WriteIndex++;
if(pHash->AddrFifo.WriteIndex>=C_HASH_ADDR_FIFO_SIZE)
{
pHash->AddrFifo.WriteIndex = 0;
}
//-------------------------------------------
pHash->AddrFifo.Num++;
if(pHash->AddrFifo.Num>C_HASH_ADDR_FIFO_SIZE)
{
pHash->AddrFifo.Num = C_HASH_ADDR_FIFO_SIZE;
}
//-------------------------------------------
return(g_TagFifo.WriteIndex);
}
//==============================================================================
//==============================================================================
int Hash_AddrFifo_Out(HashTable_t *pHash, uint16_t *pNewAddr)
{
// if(g_TagFifo.ReadIndex==g_TagFifo.WriteIndex)
// {
// return(-1);
// }
uint16_t index, Addr;
uint16_t i;//Seven
uint16_t z = 0;
if(pHash->AddrFifo.ReadIndex >= C_HASH_ADDR_FIFO_SIZE)
{
pHash->AddrFifo.ReadIndex = 0;
return(-1);
}
if(g_Hash.Cnt>0)
{
for(i=0;i<C_HASH_ADDR_INVALID;i++)
{
Addr = pHash->AddrFifo.Addr[pHash->AddrFifo.ReadIndex];
if(pHash->pElem[Addr].Flag)
{
z++;
if(z>g_Hash.Cnt)
{
break;
}
if(pHash->pElem[Addr].UplodeCnt==0)
{
break;
}
}
pHash->AddrFifo.ReadIndex++;
if(pHash->AddrFifo.ReadIndex>=C_HASH_ADDR_FIFO_SIZE)
{
pHash->AddrFifo.ReadIndex = 0;
}
}
}
else
{
Addr = pHash->AddrFifo.Addr[pHash->AddrFifo.ReadIndex];
}
if(C_HASH_ADDR_INVALID <= Addr)
{
return(-1);
}
//-------------------------------------------
*pNewAddr = Addr;
//-------------------------------------------
pHash->AddrFifo.Addr[pHash->AddrFifo.ReadIndex] = C_HASH_ADDR_INVALID;
index = pHash->AddrFifo.ReadIndex;
//-------------------------------------------
pHash->AddrFifo.ReadIndex++;
if(pHash->AddrFifo.ReadIndex>=C_HASH_ADDR_FIFO_SIZE)
{
pHash->AddrFifo.ReadIndex = 0;
}
//-------------------------------------------
if(pHash->AddrFifo.Num!=0)
{
pHash->AddrFifo.Num--;
if(pHash->AddrFifo.Num==0)
{
if(pHash->AddrFifo.ReadIndex==g_TagFifo.WriteIndex)
{
pHash->AddrFifo.ReadIndex = 0;
pHash->AddrFifo.WriteIndex = 0;
}
}
}
//-------------------------------------------
return(index);
}
//#if C_USE_UPLOAD_LIMIT
//int Hash_AddrFifo_Out_One(HashTable_t *pHash, uint16_t *pNewAddr)
//{
if(g_TagFifo.ReadIndex==g_TagFifo.WriteIndex)
{
return(-1);
}
// uint16_t index, Addr;
//
// if(pHash->AddrFifo.ReadIndex >= C_HASH_ADDR_FIFO_SIZE)
// {
// pHash->AddrFifo.ReadIndex = 0;
// }
//
// Addr = pHash->AddrFifo.Addr[pHash->AddrFifo.ReadIndex];
//
// if(C_HASH_ADDR_INVALID <= Addr)
// {
// return(-1);
// }
// //-------------------------------------------
// *pNewAddr = Addr;
//
// //-------------------------------------------
// pHash->AddrFifo.Addr[pHash->AddrFifo.ReadIndex] = C_HASH_ADDR_INVALID;
//
// index = pHash->AddrFifo.ReadIndex;
//
// //-------------------------------------------
// pHash->AddrFifo.ReadIndex++;
// if(pHash->AddrFifo.ReadIndex>=C_HASH_ADDR_FIFO_SIZE)
// {
// pHash->AddrFifo.ReadIndex = 0;
// }
// //-------------------------------------------
// // if(pHash->pElem[Addr].UplodeCnt==0)
// // {
// if(pHash->AddrFifo.Num!=0)
// {
// pHash->AddrFifo.Num--;
//
// if(pHash->AddrFifo.Num==0)
// {
// if(pHash->AddrFifo.ReadIndex==g_TagFifo.WriteIndex)
// {
// pHash->AddrFifo.ReadIndex = 0;
// pHash->AddrFifo.WriteIndex = 0;
// }
// }
// }
}
// //-------------------------------------------
// return(index);
//}
//#endif
//
/*==============================================================================
* Function:
* Input para1: Void
* Return: Void
==============================================================================*/
void Hash_Test(void)
{
#if 0
Status_t ret;
HashElem_t E;
uint16_t Addr;
uint16_t c;
HashKey_t K;
ret = Hash_Initial(&g_Hash);
E.Value.TagData.ReadTime = 43;
E.Value.TagData.Bat = 0;
E.Value.TagData.Rssi = 55;
E.Value.TagData.Flag = 0;
E.Key = 120;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
E.Key = 4120;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
E.Key = 450;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
E.Key = 670;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
E.Key = 4;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
E.Key = 50;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
E.Key = 170;
ret = Hash_Insert(&g_Hash, &E, &Addr, &c);
K = 450;
ret = Hash_Find(&g_Hash, K, &Addr, &c);
K = 4;
ret = Hash_Find(&g_Hash, K, &Addr, &c);
K = 7;
ret = Hash_Find(&g_Hash, K, &Addr, &c);
if(ret)
{
return;
}
#endif
}
void Tag_Hash_flash(HashTable_t *pHash)
{
if(g_Config.iLimitUPloadFlag)
{
uint16_t i;
F_LED2_ON();
if(pHash->Cnt<=0)
{
return;
}
for(i=0;i<C_HASH_TABLE_SIZE;i++)
{
if(pHash->pElem[pHash->AddrFifo.Addr[i]].Flag)
{
if(pHash->pElem[pHash->AddrFifo.Addr[i]].UplodeCnt>0)
{
pHash->pElem[pHash->AddrFifo.Addr[i]].UplodeCnt--;
}
// else
// {
// pHash->pElem[pHash->AddrFifo.Addr[i]].UplodeCnt=5;
// }
}
}
F_LED2_OFF();
}
#if 0//test
uint8_t data,data1;
if(g_Hash.Cnt>0)
{//刷新超时
data = g_Hash.pElem[g_Hash.AddrFifo.Addr[0]].UplodeCnt;
data1 = data;
if(data1==0)
data1 = 5;
else
data1--;
g_Hash.pElem[g_Hash.AddrFifo.Addr[0]].UplodeCnt = data1;
}
#endif
}
#endif