hash table based list operation

#define DEBUG_LIST 1
#ifdef DEBUG_LIST

//TODO warning removal here
//https://www.tutorialspoint.com/data_structures_algorithms/hash_table_program_in_c.htm
#include<stdio.h>
#include<stdlib.h>
#include<sys/queue.h>



#define SIZE 20

struct DataItem {
   int data;   
   int key;
};

struct DataItem* hashArray[SIZE]; 
struct DataItem* dummyItem;
struct DataItem* item;//todo optmize

int hashCode(int key) {
   return key % SIZE;
}

//todo change name later for function 
struct DataItem *search(int key) {
   //get the hash 
   int hashIndex = hashCode(key);  
	
   //move in array until an empty 
   while(hashArray[hashIndex] != NULL) {
	
      if(hashArray[hashIndex]->key == key)
         return hashArray[hashIndex]; 
			
      //go to next cell
      ++hashIndex;
		
      //wrap around the table
      hashIndex %= SIZE;
   }        
	
   return NULL;        
}

void insert(int key,int data) {

   struct DataItem *item = (struct DataItem*) malloc(sizeof(struct DataItem));
   item->data = data;  
   item->key = key;

   //get the hash 
   int hashIndex = hashCode(key);

   //move in array until an empty or deleted cell
   while(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1) {
      //go to next cell
      ++hashIndex;
		
      //wrap around the table
      hashIndex %= SIZE;
   }
	
   hashArray[hashIndex] = item;
}

struct DataItem* delete(struct DataItem* item) {
   int key = item->key;

   //get the hash 
   int hashIndex = hashCode(key);

   //move in array until an empty
   while(hashArray[hashIndex] != NULL) {
	
      if(hashArray[hashIndex]->key == key) {
         struct DataItem* temp = hashArray[hashIndex]; 
			
         //assign a dummy item at deleted position
         hashArray[hashIndex] = dummyItem; 
         return temp;
      }
		
      //go to next cell
      ++hashIndex;
		
      //wrap around the table
      hashIndex %= SIZE;
   }      
	
   return NULL;        
}

void display() {
   int i = 0;
	
   for(i = 0; i<SIZE; i++) {
	
      if(hashArray[i] != NULL)
         printf(" (%d,%d)",hashArray[i]->key,hashArray[i]->data);
      else
         printf(" ~~ ");
   }
	
   printf("\n");
}

/*-----------------------------above hashmap implementation ------------------------------*/

struct probe{
	LIST_ENTRY(probe) list_ping ;
	LIST_ENTRY(probe) list_pong ;
	
	unsigned int addr_start ;
	unsigned int addr_end ;
	
	unsigned int page_addr ;
};

typedef LIST_HEAD(probe_head, probe) probe_head ;
struct mem_protect{
	probe_head probe_ping;
	probe_head probe_pong;
	unsigned int active_probe ;
	
	unsigned int page_addr_mask ;
	
	
	unsigned int max_probe_cnt ;
	unsigned int probe_cnt ;
};


enum cpu_t{
CortexA8,
other};

static struct mem_protect mem_protect ;

/*----------------------------- LOCAL FUNCTIONS ------------------------------*/
int mem_protect_probe_init(unsigned int cpu)//CortexA8
{
	int ret = -1 ;	
	
	
	do{
		LIST_INIT( &(mem_protect.probe_ping) ) ;
		LIST_INIT( &(mem_protect.probe_pong) ) ;
		mem_protect.active_probe = 0 ;
		
		if(cpu != CortexA8)
			break ;
		
		
		/* 1MB
		 */	
		mem_protect.page_addr_mask = 0xFFF00000;
		
		
		mem_protect.max_probe_cnt = 5 ;
		mem_protect.probe_cnt = 0 ;
		
		ret = 0 ;
	}while(0) ;

	
	return ret ;
}

int mem_protect_list_probes()
{
	int ret = -1;

	do{
		probe_head * active_head = NULL, *inactive_head = NULL ;
		if(mem_protect.active_probe){
			active_head = &(mem_protect.probe_pong) ;
			inactive_head = &(mem_protect.probe_ping) ;
		}else{
			active_head = &(mem_protect.probe_ping) ;
			inactive_head = &(mem_protect.probe_pong) ;
		}

		struct probe  *pitter = NULL ;//TODO KW check
		printf("List all the probe info: totally %d probes\r\n",mem_protect.probe_cnt);

		//now ping == pong ,without  mem_protect.active_probe ==1 precondition
		LIST_FOREACH(pitter, inactive_head, list_ping){
			printf("inactive_list: list foreach (address start | address end | page):%x\t%x\t%x\r\n",pitter->addr_start, pitter->addr_end,pitter->page_addr);
			//last_probe=pitter ;
			//if( pitter->addr_start >= addr )
			//break ;
		}

		LIST_FOREACH(pitter, active_head, list_pong){
			printf("Active_list: list foreach (address start || address end || page):%x\t%x\t%x\r\n",pitter->addr_start, pitter->addr_end,pitter->page_addr);

		}

		ret = 0;
	}while(0) ;
	return ret;
}

//TODO replace printf by atdebug(0,
#define ERROR_DEL_NULLLIST (-1)
#define ERROR_DEL_NOTFOUND (-2)
int mem_protect_del_probe(unsigned int addr)
{
	int ret = ERROR_DEL_NULLLIST;
	do
	{
		if(0==mem_protect.probe_cnt)
		{
			ret = ERROR_DEL_NULLLIST;
			break;
		}
		probe_head * active_head = NULL , *inactive_head = NULL ;
		if(mem_protect.active_probe){
			active_head = &(mem_protect.probe_pong) ;
			inactive_head = &(mem_protect.probe_ping) ;
		}else{
			active_head = &(mem_protect.probe_ping) ;
			inactive_head = &(mem_protect.probe_pong) ;
		}


		struct probe *last_probe= NULL, *pitter ;
		LIST_FOREACH(pitter, inactive_head, list_ping){

			if( pitter->addr_start == addr )
			{
				last_probe=pitter ;
				break ;
			}
		}

		if(last_probe == NULL)
		{
			ret = ERROR_DEL_NOTFOUND;
			break;
		}
		
		//TODO add page property recover here
		struct DataItem*   DataItemTarget = search(addr&0x100000);
		if(DataItemTarget == NULL)
		{
			printf("invalid addr to delete \n");
			ret = -1;
		}
		else if (DataItemTarget->data == 1)
		{
			if (!delete(DataItemTarget)) //if not null ,it delete ok	
			{
				ret = 0;
			}
			ret = -2;
		}
		else
		{
			(DataItemTarget->data)--;
			ret = 0;
		}
		

		if(mem_protect.active_probe){
			LIST_REMOVE(last_probe,list_ping);
			mem_protect.active_probe = 0 ;
			LIST_REMOVE(last_probe,list_pong);
		}
		else
		{
			LIST_REMOVE(last_probe,list_pong);
			mem_protect.active_probe = 1 ;
			LIST_REMOVE(last_probe,list_ping);
		}
		mem_protect.probe_cnt-- ;	

	}while(0) ;
	return ret;
}
int mem_protect_add_probe(unsigned int addr, unsigned int len) 
{
	int ret = -1 ;
//mutex->lock	
	do{
		if(mem_protect.probe_cnt >= mem_protect.max_probe_cnt)
		{
			break ;
		}
		if(len > ~(mem_protect.page_addr_mask) )
		{
			break ;
		}
		
		/*TODO: cross different page
		 */
		
		struct probe* probe = malloc( sizeof(*probe) ) ;
		if(NULL == probe)
		{
			break ;
		}
		memset(probe, 0, sizeof(*probe) ) ;
		
		probe->addr_start = addr ;
		probe->addr_end  = addr+len ;
		probe->page_addr = addr & mem_protect.page_addr_mask ;
		

		
		probe_head * active_head, *inactive_head ;
		if(mem_protect.active_probe){
			active_head = &(mem_protect.probe_pong) ;
			inactive_head = &(mem_protect.probe_ping) ;
		}else{
			active_head = &(mem_protect.probe_ping) ;
			inactive_head = &(mem_protect.probe_pong) ;
		}
		
		
		struct probe *last_probe = NULL , *pitter = NULL  ;
		LIST_FOREACH(pitter, inactive_head, list_ping){
			last_probe=pitter ;
			if( pitter->addr_start >= addr )
			{
				break ;
			}
		}
		
		
		if(mem_protect.active_probe){
			if(last_probe)
			{
				LIST_INSERT_AFTER(last_probe, probe, list_ping) ;
			}
			else
			{
				LIST_INSERT_HEAD(inactive_head, probe, list_ping) ;
			}
		
			mem_protect.active_probe = 0 ;
			
			if(last_probe)
			{
				LIST_INSERT_AFTER(last_probe, probe, list_pong) ;
			}
			else
			{
				LIST_INSERT_HEAD(active_head, probe, list_pong) ;
			}
		}else{
			if(last_probe)
			{
				LIST_INSERT_AFTER(last_probe, probe, list_pong) ;
			}
			else
			{
				LIST_INSERT_HEAD(inactive_head, probe, list_pong) ;
			}
			
			mem_protect.active_probe = 1 ;
			
			if(last_probe)
			{
				LIST_INSERT_AFTER(last_probe, probe, list_ping) ;
			}
			else
			{
				LIST_INSERT_HEAD(active_head, probe, list_ping) ;
			}
			
			
		}		
		
		////TODO enable
		//mmu_set_access_permission(addr, len) ;
		
		struct DataItem*   DataItemTarget = search(addr&0x100000);
		if(DataItemTarget == NULL)
		{
			insert(addr&0x100000,1);
		}
		else
		{
			(DataItemTarget->data)++; //key data
		}
		
		
		mem_protect.probe_cnt++ ;
		if(1==mem_protect.probe_cnt){
			//TODO enable
			//setup_memprotect_exception_handler() ;
		}
		
		
		ret = 0 ;
	}while(0) ;
	
	
	
//mutex->unlock	
	return ret ;	
}
int main(void){

	dummyItem = (struct DataItem*) malloc(sizeof(struct DataItem));//for delete use ,never delete it
   dummyItem->data = -1;  
   dummyItem->key = -1; 
   //later move it into mem_protect_probe_init
   
	int ret1 = mem_protect_probe_init(CortexA8);//CortexA8
	int ret2 = mem_protect_add_probe(0x8f000000,4);
	ret2 = mem_protect_add_probe(0x8f000010,4);
	ret2 = mem_protect_add_probe(0x8f000020,4);
	ret2 = mem_protect_add_probe(0x8f000030,4);
	ret2 = mem_protect_add_probe(0x8f000040,4);
	//printlist
	int ret0 = mem_protect_list_probes();

	//delete list
	int ret3 = 0;
	ret3 = mem_protect_del_probe(0x8f000040);
	ret3 =mem_protect_del_probe(0x8f000030);
	ret3 =mem_protect_del_probe(0x8f000020);
	ret3 =mem_protect_del_probe(0x8f000010);
	ret3 =mem_protect_del_probe(0x8f000000);
	
	ret0 = mem_protect_list_probes();
	
	printf("del null list item%d \r\n",mem_protect_del_probe(0x8f000040));

#if 0
	ret2 = mem_protect_add_probe(0x8f000010,4);
	ret2 = mem_protect_add_probe(0x8f000020,4);

	printf("del invalid item %d \r\n",mem_protect_del_probe(0x8f000048));
	ret0 = mem_protect_list_probes();

#endif



return 0;
}




#endif

你可能感兴趣的:(hash table based list operation)