哈希表除去重复数据

 

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

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值