?? 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); ///根據(jù)映射算法,計算索引 /// 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在表中已經(jīng)存在 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); ////根據(jù)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;}////獲取表中對象的數(shù)目/*------------------------------------------------------------------------ * 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的指針放到指針數(shù)組v中,這個函數(shù)被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////函數(shù)ht->ht_cmpfcn(p->hte_key, key)的原型。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -