180 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | 
						|
 | 
						|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | 
						|
be copied by any method or incorporated into another program without
 | 
						|
the express written consent of Aerospace C.Power. This Information or any portion
 | 
						|
thereof remains the property of Aerospace C.Power. The Information contained herein
 | 
						|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | 
						|
liability for its use in any way and conveys no license or title under
 | 
						|
any patent or copyright and makes no representation or warranty that this
 | 
						|
Information is free from patent or copyright infringement.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
/* os shim includes */
 | 
						|
#include "os_types.h"
 | 
						|
#include "os_mem.h"
 | 
						|
 | 
						|
/* common includes */
 | 
						|
#include "iot_errno.h"
 | 
						|
#include "iot_module.h"
 | 
						|
#include "iot_mem_pool.h"
 | 
						|
#include "iot_addr_hash_table.h"
 | 
						|
#include "iot_meter_addr_hash_table_api.h"
 | 
						|
 | 
						|
iot_addr_hash_table_h iot_meter_addr_hash_table_create(module_id_t module,
 | 
						|
    uint16_t entry_cnt, uint16_t entry_size, uint16_t table_size)
 | 
						|
{
 | 
						|
    iot_addr_hash_table_t *table;
 | 
						|
 | 
						|
    table = iot_addr_hash_table_create(module, entry_cnt, entry_size,
 | 
						|
        table_size);
 | 
						|
    if (table) {
 | 
						|
        table->meter_flag = 1;
 | 
						|
    }
 | 
						|
    return table;
 | 
						|
}
 | 
						|
 | 
						|
void iot_meter_addr_hash_table_delete(iot_addr_hash_table_h handle)
 | 
						|
{
 | 
						|
    iot_addr_hash_table_delete(handle);
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_meter_addr_hash_table_add(iot_addr_hash_table_h handle,
 | 
						|
    iot_meter_addr_hash_entry_t *entry)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK, index;
 | 
						|
    iot_addr_hash_table_t *table = handle;
 | 
						|
    iot_meter_addr_hash_entry_t *tmp;
 | 
						|
 | 
						|
    if (!table->meter_flag) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    index = iot_meter_addr_hash(entry->addr, table->table_size - 1);
 | 
						|
    tmp = (iot_meter_addr_hash_entry_t *)table->hash_ent[index];
 | 
						|
    if (tmp == NULL) {
 | 
						|
        table->hash_ent[index] = (iot_addr_hash_entry_t *)entry;
 | 
						|
    } else {
 | 
						|
        for (;;) {
 | 
						|
            if (iot_meter_addr_cmp(tmp->addr, entry->addr)) {
 | 
						|
                ret = ERR_EXIST;
 | 
						|
                goto out;
 | 
						|
            }
 | 
						|
            if (tmp->next) {
 | 
						|
                tmp = tmp->next;
 | 
						|
            } else {
 | 
						|
                /* iterate to the end of the list */
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        tmp->next = entry;
 | 
						|
    }
 | 
						|
    entry->next = NULL;
 | 
						|
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
void iot_meter_addr_hash_table_remove(iot_addr_hash_table_h handle,
 | 
						|
    iot_meter_addr_hash_entry_t *entry)
 | 
						|
{
 | 
						|
    uint32_t index;
 | 
						|
    iot_addr_hash_table_t *table = handle;
 | 
						|
    iot_meter_addr_hash_entry_t *curr, *prev = NULL;
 | 
						|
 | 
						|
    if (!table->meter_flag) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    /* search entry */
 | 
						|
    index = iot_meter_addr_hash(entry->addr, table->table_size - 1);
 | 
						|
    curr = (iot_meter_addr_hash_entry_t *)table->hash_ent[index];
 | 
						|
 | 
						|
    while (curr) {
 | 
						|
        if (curr == entry)
 | 
						|
            break;
 | 
						|
        prev = curr;
 | 
						|
        curr = curr->next;
 | 
						|
    }
 | 
						|
 | 
						|
    if (curr) {
 | 
						|
        /* remove entry from the hash table */
 | 
						|
        if (prev) {
 | 
						|
            prev->next = curr->next;
 | 
						|
        } else {
 | 
						|
            table->hash_ent[index] = (iot_addr_hash_entry_t *)curr->next;
 | 
						|
        }
 | 
						|
        curr->next = NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
iot_meter_addr_hash_entry_t *iot_meter_addr_hash_table_find(
 | 
						|
    iot_addr_hash_table_h handle, uint8_t* addr)
 | 
						|
{
 | 
						|
    uint32_t index;
 | 
						|
    iot_addr_hash_table_t *table = handle;
 | 
						|
    iot_meter_addr_hash_entry_t *entry;
 | 
						|
 | 
						|
    if (!table->meter_flag) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    index = iot_meter_addr_hash(addr, table->table_size - 1);
 | 
						|
    entry = (iot_meter_addr_hash_entry_t *)table->hash_ent[index];
 | 
						|
    while (entry) {
 | 
						|
        if (iot_meter_addr_cmp(addr, entry->addr)) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        entry = entry->next;
 | 
						|
    }
 | 
						|
 | 
						|
    return entry;
 | 
						|
}
 | 
						|
 | 
						|
void iot_meter_addr_hash_table_loop(iot_addr_hash_table_h handle,
 | 
						|
    iot_meter_addr_hash_loop_func_t func, void *param)
 | 
						|
{
 | 
						|
    uint32_t index = 0;
 | 
						|
    iot_addr_hash_table_t *table = handle;
 | 
						|
    iot_meter_addr_hash_entry_t *entry, *next_entry;
 | 
						|
 | 
						|
    if (!table->meter_flag) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    while (index < table->table_size) {
 | 
						|
        entry = (iot_meter_addr_hash_entry_t *)table->hash_ent[index];
 | 
						|
        while (entry) {
 | 
						|
            next_entry = entry->next;
 | 
						|
            func(entry, param);
 | 
						|
            /* caution, after this point, entry pointer is invalid */
 | 
						|
            entry = next_entry;
 | 
						|
        }
 | 
						|
        index++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
iot_meter_addr_hash_entry_t *iot_meter_addr_hash_table_alloc(
 | 
						|
    iot_addr_hash_table_h handle)
 | 
						|
{
 | 
						|
    iot_addr_hash_table_t *table = handle;
 | 
						|
 | 
						|
    if (!table->meter_flag) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    return (iot_meter_addr_hash_entry_t *)iot_addr_hash_table_alloc(handle);
 | 
						|
}
 | 
						|
 | 
						|
void iot_meter_addr_hash_table_free(iot_addr_hash_table_h handle,
 | 
						|
    iot_meter_addr_hash_entry_t *entry)
 | 
						|
{
 | 
						|
    iot_addr_hash_table_t *table = handle;
 | 
						|
 | 
						|
    if (!table->meter_flag) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    iot_addr_hash_table_free(handle, (iot_addr_hash_entry_t *)entry);
 | 
						|
}
 | 
						|
 |