📄 hust_hash_qiu_5.20.c
字号:
/*------------------------------------------------------------------------- * hash.c - htnew, htreaderbegin, htreaderend, htwriterbegin, htwriterend, * htget, htgetent, htdel, htadd, hashstring, hashunsignedint, htcount, * htenum, htdestroy, unsignedinteq *------------------------------------------------------------------------- */////#include <stdio.h>#include "ipOS.h"#include "ipHAL.h"#include "hust_rtp.h"#include "hust_hash.h"/////#include <stdlib.h>/////#include <strings.h>/*------------------------------------------------------------------------ * htnew - create and return pointer to a new hashtable *------------------------------------------------------------------------ */struct ht *htnew(u8_t size, int(* hashfcn)(unsigned long int, u8_t), int(* cmpfcn)(unsigned long int, unsigned long int), u8_t destroytype){ struct ht *ht; ht = (struct ht *) heap_alloc(sizeof(struct ht)); memset(ht,0,sizeof(struct ht)); if (ht == NULL) return NULL; /*pthread_mutex_init(&ht->ht_writepend, NULL); pthread_mutex_init(&ht->ht_readblk, NULL); pthread_mutex_init(&ht->ht_writeblk, NULL); pthread_mutex_init(&ht->ht_rdcntmutex, NULL); pthread_mutex_init(&ht->ht_wrcntmutex, NULL);*/ ht->ht_readcnt = 0; ht->ht_writecnt = 0; ht->ht_entries = (struct htent **) heap_alloc(sizeof(struct htent *) * size); memset(ht->ht_entries,0,sizeof(struct htent *) * size); ht->ht_count = 0; ht->ht_hashfcn = hashfcn; ht->ht_cmpfcn = cmpfcn; ht->ht_destroy = destroytype; if (ht->ht_entries == NULL) { heap_free(ht); return NULL; } memset((char *)ht->ht_entries,0, size * sizeof(struct htent *)); ht->ht_size = size; return ht;}//////新建一个哈希表,并返回该表的指针。在初始化一个session时被调用。/*------------------------------------------------------------------------ * htreaderbegin - to be called before reader access for locking *------------------------------------------------------------------------ */voidhtreaderbegin(struct ht *ht){ /*pthread_mutex_lock(&ht->ht_writepend); pthread_mutex_lock(&ht->ht_readblk); pthread_mutex_lock(&ht->ht_rdcntmutex);*/ /*if ((++(ht->ht_readcnt)) == 1) { pthread_mutex_lock(&ht->ht_writeblk); } pthread_mutex_unlock(&ht->ht_rdcntmutex); pthread_mutex_unlock(&ht->ht_readblk); pthread_mutex_unlock(&ht->ht_writepend);*/}/////*------------------------------------------------------------------------ * htreaderend - to be called after reader access for locking *------------------------------------------------------------------------ */voidhtreaderend(struct ht *ht){ /*pthread_mutex_lock(&ht->ht_rdcntmutex); if (--ht->ht_readcnt == 0) { pthread_mutex_unlock(&ht->ht_writeblk); } pthread_mutex_unlock(&ht->ht_rdcntmutex);*/}/*------------------------------------------------------------------------ * htwriterbegin - to be called before writer access for locking *------------------------------------------------------------------------ */voidhtwriterbegin(struct ht *ht){ /*pthread_mutex_lock(&ht->ht_wrcntmutex); if ((++(ht->ht_writecnt)) == 1) pthread_mutex_lock(&ht->ht_readblk); pthread_mutex_unlock(&ht->ht_wrcntmutex); pthread_mutex_lock(&ht->ht_writeblk);*/}/*------------------------------------------------------------------------ * htwriterend - to be called after writer access for locking *------------------------------------------------------------------------ */voidhtwriterend(struct ht *ht){ /*pthread_mutex_unlock(&ht->ht_writeblk); pthread_mutex_lock(&ht->ht_wrcntmutex); if ((--(ht->ht_writecnt)) == 0) pthread_mutex_unlock(&ht->ht_readblk); pthread_mutex_unlock(&ht->ht_wrcntmutex);*/}/*------------------------------------------------------------------------ * htget - retreive an object from the ht *------------------------------------------------------------------------ */char *htget(struct ht *ht, unsigned long int key){ struct htent *p; void *object;/// htreaderbegin(ht); p = htgetent(ht, key); if (p != NULL) { object = p->hte_object;/// htreaderend(ht); return object; } else {/// htreaderend(ht); return NULL; }}/*------------------------------------------------------------------------ * htgetent - non-locking internal call to do the work of retreiving * object from ht *------------------------------------------------------------------------ */struct htent *htgetent(struct ht *ht, unsigned long int key){ u8_t hash; struct htent *p; hash = ht->ht_hashfcn(key, ht->ht_size); p = ht->ht_entries[hash]; while(p) { if (!ht->ht_cmpfcn(p->hte_key, key)) return p; p = p->hte_chain; } /* * Not found. */ return NULL;}/*------------------------------------------------------------------------ * htdel - remove an object from the hashtable *------------------------------------------------------------------------ */inthtdel(struct ht *ht, unsigned long int key){ u8_t hash; struct htent *p, *follow; hash = ht->ht_hashfcn(key, ht->ht_size); ///根据映射算法,计算索引 /// htwriterbegin(ht); ////为写操作作准备,主要是锁读的操作 p = ht->ht_entries[hash];////获得可能包括要找的对象的bulk follow = NULL; while(p) {////从bulk的入口开始逐个比较key的值来确定 if (!ht->ht_cmpfcn(p->hte_key, key)) { if (follow) follow->hte_chain = p->hte_chain; else ht->ht_entries[hash] = p->hte_chain; ////通过指针操作把p所指的对象移到哈希表外 /* if (ht->ht_destroykeyfcn != NULL) ht->ht_destroykeyfcn(p->hte_key); if (ht->ht_destroyobjectfcn != NULL) ht->ht_destroyobjectfcn(p->hte_object); */ ////销毁p所指向的对象 if (ht->ht_destroy == SSRCDESTROY) { rtpdestroystream(p->hte_object); } if (ht->ht_destroy == CNAMEDESTROY) { heap_free(p->hte_key); heap_free(p->hte_object); } heap_free(p); ht->ht_count--;//// htwriterend(ht); return OK; } follow = p; p = p->hte_chain; /////遍历整个bulk链表。 } /* * Not found. *//// htwriterend(ht); return ERROR;}/*------------------------------------------------------------------------ * htadd - add an object to the hash table. Returns ERROR * if key is already present. *------------------------------------------------------------------------ */inthtadd(struct ht *ht, unsigned long int key, void *object){ u8_t len; u8_t hash; struct htent *ent, *p; /* * Check for key. *//// htwriterbegin(ht); p = htgetent(ht, key); if (p != NULL) {/// htwriterend(ht); return ERROR; } ///这个object在表中已经存在 len = ht->ht_size; ent = (struct htent *) heap_alloc(sizeof(struct htent)); if (ent == NULL) {//// htwriterend(ht); return ERROR; } ent->hte_key = key; ent->hte_object = object; hash = ht->ht_hashfcn(key, len); ////根据key来计算哈希表中的索引值 /* * Add to front of chain. */ p = ht->ht_entries[hash]; ent->hte_chain = p; ht->ht_entries[hash] = ent; ///对象插入到chain当中,是放到chain的开头 ht->ht_count++;/// htwriterend(ht); return OK;}////把一个object(stream)放到hash table中去/*------------------------------------------------------------------------ * hashstring - function to generate hash value for a string. * Fix me! TBD: Use use better string hash function. *------------------------------------------------------------------------ */inthashstring(unsigned long int key, u8_t len){ int i; int acc = 0; char *str = (char *) key; u8_t test; for (i = 0; i < strlen(str); i++) /* * Convert to uppercase. */ acc += (str[i] >= 97 && str[i] <= 122 ? str[i] - 32 : str[i]); test= acc % len; return test;}////把key当作是string变量,从而获得索引,并不去分string中字母的大小写。/*------------------------------------------------------------------------ * hashunsignedint - function to generate a hashvalue for an unsigned int * Because SSRCs are expected to be random, using value % htsize should * suffice as a hash function. *------------------------------------------------------------------------ */inthashunsignedint(unsigned long int key, u8_t len){ return key % len;}////从一个整型的key来计算哈希表的索引/*------------------------------------------------------------------------ * htcount - return number of objects in the hashtable *------------------------------------------------------------------------ */inthtcount(struct ht *ht){ int count; /* * Return number of items in hashtable. *//// htreaderbegin(ht); count = ht->ht_count;/// htreaderend(ht); return count;}////获取表中对象的数目/*------------------------------------------------------------------------ * htenum - enumerate entries in the hashtable *------------------------------------------------------------------------ */struct htent **htenum(struct ht *ht){ struct htent **v, *p; int i; int j;/// htreaderbegin(ht); v = (struct htent **) heap_alloc(sizeof(struct htent *) * (ht->ht_count + 1)); if (v == NULL) {/// htreaderend(ht); return NULL; } for (j = 0, i = 0; j < ht->ht_size; j++) { p = ht->ht_entries[j]; ////查找chain(bulk)的入口 while (p != NULL) { v[i++] = p; p = p->hte_chain; ///遍历每个chain } }/// htreaderend(ht); /* * Use NULL to mark end */ v[i] = NULL; return v;}////把一个表中所有的entry的指针放到指针数组v中,这个函数被rtpsources调用。/*------------------------------------------------------------------------ * htdestroy - destroy hashtable and free all memory *------------------------------------------------------------------------ */inthtdestroy(struct ht *ht){ int j; struct htent *p, *q; if (ht == NULL) return ERROR; ///对于已空的表,destroy失败 for (j = 0; j < ht->ht_size; j++) { p = ht->ht_entries[j]; while (p != NULL) { q = p->hte_chain; /* * Destroy the key and object. */ /* if (ht->ht_destroykeyfcn != NULL) ht->ht_destroykeyfcn(p->hte_key); if (ht->ht_destroyobjectfcn != NULL) ht->ht_destroyobjectfcn(p->hte_object); */ /* * Free the memory from the hashtable entry. */ if (ht->ht_destroy == SSRCDESTROY) { rtpdestroystream(p->hte_object); } if (ht->ht_destroy == CNAMEDESTROY) { heap_free(p->hte_key); heap_free(p->hte_object); } heap_free(p); p = q; } } /* * Free the array of pointers and ht structure. */ heap_free(ht->ht_entries); heap_free(ht); return OK;}/*------------------------------------------------------------------------ * unsignedinteq - determine if two unsigned ints are equal *------------------------------------------------------------------------ */intunsignedinteq(unsigned long int a, unsigned long int b){ return (!(a == b));}////相等则返回0////函数ht->ht_cmpfcn(p->hte_key, key)的原型。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -