From f85c9b875b060681b51f57b15074ba1c7c9f5636 Mon Sep 17 00:00:00 2001
From: wangzhengquan <wangzhengquan85@126.com>
Date: 星期一, 20 七月 2020 11:10:02 +0800
Subject: [PATCH] update

---
 queue/hashtable.c |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/queue/hashtable.c b/queue/hashtable.c
index 9b66bb3..43c59ce 100755
--- a/queue/hashtable.c
+++ b/queue/hashtable.c
@@ -1,7 +1,8 @@
 #include "usg_common.h"
 #include "hashtable.h"
 #include "mm.h"
-
+#include "sem_util.h"
+#include <set>
 
 typedef struct tailq_entry_t
 {
@@ -14,6 +15,7 @@
   TAILQ_ENTRY(tailq_entry_t) joint;
 } tailq_entry_t;
 
+#define START_KEY 1000
 
 typedef  TAILQ_HEAD(tailq_header_t, tailq_entry_t) tailq_header_t;
 
@@ -21,11 +23,16 @@
 
 void hashtable_init(hashtable_t *hashtable )
 {
+  
   memset(hashtable, 0, sizeof(hashtable_t));
+  hashtable->mutex = SemUtil::get(IPC_PRIVATE, 1);
+  hashtable->wlock = SemUtil::get(IPC_PRIVATE, 1);
+  hashtable->cond = SemUtil::get(IPC_PRIVATE, 1);
+  hashtable->readcnt = 0;
 }
 
 
-void *hashtable_get(hashtable_t *hashtable, int key)
+void *_hashtable_get(hashtable_t *hashtable, int key)
 {
   size_t code = hashcode(key);
   tailq_entry_t *item;
@@ -47,7 +54,7 @@
 
 }
 
-void* hashtable_put(hashtable_t *hashtable, int key, void *value)
+void * _hashtable_put(hashtable_t *hashtable, int key, void *value)
 {
   size_t code = hashcode(key);
   void *oldvalue;
@@ -55,7 +62,7 @@
   tailq_header_t *my_tailq_head = hashtable->array[code] ;
   if ( my_tailq_head == NULL)
   {
-    my_tailq_head  = (tailq_header_t*)  mm_malloc(sizeof(tailq_header_t ));
+    my_tailq_head  = (tailq_header_t*) mm_malloc(sizeof(tailq_header_t ));
     TAILQ_INIT(my_tailq_head);
     hashtable->array[code] = my_tailq_head;
     goto putnew;
@@ -110,6 +117,10 @@
 
 }
 
+
+
+
+
 void hashtable_removeall(hashtable_t *hashtable)
 {
   tailq_entry_t *item;
@@ -158,3 +169,95 @@
   return key % MAPSIZE;
   /*printf("hashfun = %ld\n", code);*/
 }
+
+
+int hashtable_alloc_key(hashtable_t *hashtable) {
+  int key = START_KEY;
+  SemUtil::dec(hashtable->wlock);
+
+  while(_hashtable_get(hashtable, key) != NULL) {
+    key++;
+  }
+
+  _hashtable_put(hashtable, key, (void *)1);
+  SemUtil::inc(hashtable->wlock);
+  return key;
+}
+
+void *hashtable_get(hashtable_t *hashtable, int key) {
+   SemUtil::dec(hashtable->mutex);
+   hashtable->readcnt++;
+   if (hashtable->readcnt == 1) {
+    //鑾峰彇璇诲啓閿�
+    SemUtil::dec(hashtable->wlock);
+   }
+   SemUtil::inc(hashtable->mutex);
+
+   void * res = _hashtable_get(hashtable, key);
+
+   SemUtil::dec(hashtable->mutex);
+   hashtable->readcnt--;
+   if(hashtable->readcnt == 0) {
+    //閲婃斁璇诲啓閿�
+    SemUtil::inc(hashtable->wlock);
+  //閫氱煡鍐�
+    SemUtil::set(hashtable->cond, 1);
+   }
+   SemUtil::inc(hashtable->mutex);
+   return res;
+}
+
+void hashtable_put(hashtable_t *hashtable, int key, void *value) {
+  SemUtil::dec(hashtable->mutex);
+  while (hashtable->readcnt > 0)
+  {
+    SemUtil::set(hashtable->cond, 0);
+    SemUtil::inc(hashtable->mutex);
+    //绛夊緟鍐欓�氱煡
+    SemUtil::dec(hashtable->cond);
+
+    SemUtil::dec(hashtable->mutex);
+     
+  }
+  SemUtil::inc(hashtable->mutex);
+
+  //鑾峰彇璇诲啓閿�
+  SemUtil::dec(hashtable->wlock);
+  _hashtable_put(hashtable, key, value);
+  //閲婃斁璇诲啓閿�
+  SemUtil::inc(hashtable->wlock);
+}
+
+
+
+void hashtable_foreach(hashtable_t *hashtable, hashtable_foreach_cb cb) {
+  tailq_entry_t *item;
+  for (int i = 0; i < MAPSIZE; i++) {
+    tailq_header_t *my_tailq_head = hashtable->array[i] ;
+
+    if (my_tailq_head == NULL )
+      continue;
+
+    TAILQ_FOREACH(item, my_tailq_head, joint)
+    {
+      cb(item->key,  item -> value);
+    }
+  }
+}
+
+std::set<int> * hashtable_keyset(hashtable_t *hashtable) {
+  std::set<int> *keyset = new std::set<int>;
+  tailq_entry_t *item;
+  for (int i = 0; i < MAPSIZE; i++) {
+    tailq_header_t *my_tailq_head = hashtable->array[i] ;
+
+    if (my_tailq_head == NULL )
+      continue;
+
+    TAILQ_FOREACH(item, my_tailq_head, joint)
+    {
+      keyset->insert(item->key);
+    }
+  }
+  return keyset;
+}

--
Gitblit v1.8.0