?? hust_hash.c
字號(hào):
/*------------------------------------------------------------------------- * hash.c - htnew, htreaderbegin, htreaderend, htwriterbegin, htwriterend, * htget, htgetent, htdel, htadd, hashstring, hashunsignedint, htcount, * htenum, htdestroy, unsignedinteq *------------------------------------------------------------------------- */#include <ipOS.h>#include <ipHAL.h>#include <ipStack.h>#include <ipEthernet.h>#include "hust_rtp.h"#include "hust_rtplibcommon.h"#include "hust_rtcp.h"#include "hust_event.h"#include "hust_hash.h"#include "hust_linux.h"////#include <stdio.h>///#include "hust_hash.h"/////#include <stdlib.h>/////#include <strings.h>/*------------------------------------------------------------------------ * htnew - create and return pointer to a new hashtable *------------------------------------------------------------------------ */struct ht *htnew(int size, int(* hashfcn)(unsigned long int, int), int(* cmpfcn)(unsigned long int, unsigned long int), void(* destroykeyfcn)(unsigned long int), void(* destroyobjectfcn)(void *)){ struct ht *ht; ht = (struct ht *) heap_alloc(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); ht->ht_count = 0; ht->ht_hashfcn = hashfcn; ht->ht_cmpfcn = cmpfcn; ht->ht_destroykeyfcn = destroykeyfcn; ht->ht_destroyobjectfcn = destroyobjectfcn; 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;}//////新建一個(gè)哈希表,并返回該表的指針。在初始化一個(gè)session時(shí)被調(diào)用。/*------------------------------------------------------------------------ * 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){ int 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){ int hash; struct htent *p, *follow; hash = ht->ht_hashfcn(key, ht->ht_size); ///根據(jù)映射算法,計(jì)算索引 ///htwriterbegin(ht); ////為寫操作作準(zhǔn)備,主要是鎖讀的操作 p = ht->ht_entries[hash];////獲得可能包括要找的對(duì)象的bulk follow = NULL; while(p) {////從bulk的入口開始逐個(gè)比較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所指的對(duì)象移到哈希表外 if (ht->ht_destroykeyfcn != NULL) ht->ht_destroykeyfcn(p->hte_key); if (ht->ht_destroyobjectfcn != NULL) ht->ht_destroyobjectfcn(p->hte_object); ////銷毀p所指向的對(duì)象 heap_free(p); ht->ht_count--; ///htwriterend(ht); return OK; } follow = p; p = p->hte_chain; /////遍歷整個(gè)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){ int len; int hash; struct htent *ent, *p; /* * Check for key. */ ///htwriterbegin(ht); p = htgetent(ht, key); if (p != NULL) { ///htwriterend(ht); return ERROR; } ///這個(gè)object在表中已經(jīng)存在 len = ht->ht_size; ent = (struct htent *)heap_alloc(sizeof(struct htent)); if (ent == NULL) { ///htwriterend(ht); } ent->hte_key = key; ent->hte_object = object; hash = ht->ht_hashfcn(key, len); ////根據(jù)key來計(jì)算哈希表中的索引值 /* * Add to front of chain. */ p = ht->ht_entries[hash]; ent->hte_chain = p; ht->ht_entries[hash] = ent; ///對(duì)象插入到chain當(dāng)中,是放到chain的開頭 ht->ht_count++; ///htwriterend(ht); return OK;}////把一個(gè)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, int len){ int i; int acc = 0; char *str = (char *) key; for (i = 0; i < strlen(str); i++) /* * Convert to uppercase. */ acc += (str[i] >= 97 && str[i] <= 122 ? str[i] - 32 : str[i]); return acc % len;}////把key當(dāng)作是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, int len){ return key % len;}////從一個(gè)整型的key來計(jì)算哈希表的索引/*------------------------------------------------------------------------ * 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;}////獲取表中對(duì)象的數(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); } 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; ///遍歷每個(gè)chain } } ///htreaderend(ht); /* * Use NULL to mark end */ v[i] = NULL; return v;}////把一個(gè)表中所有的entry的指針放到指針數(shù)組v中,這個(gè)函數(shù)被rtpsources調(diào)用。/*------------------------------------------------------------------------ * htdestroy - destroy hashtable and free all memory *------------------------------------------------------------------------ */inthtdestroy(struct ht *ht){ int j; struct htent *p, *q; if (ht == NULL) return ERROR; ///對(duì)于已空的表,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. */ 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)的原型。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -