2 #include "ged_hashtable.h"
3 #include <linux/hashtable.h>
5 typedef struct GED_HASHTABLE_TAG
8 unsigned int ui32Length
;
9 unsigned int ui32CurrentID
;
10 unsigned int ui32Count
;
11 struct hlist_head
* psHashTable
;
14 typedef struct GED_HASHNODE_TAG
18 struct hlist_node sNode
;
21 #define GED_HASHTABLE_INIT_ID 1234 // 0 = invalid
23 void* __ged_hashtable_find(struct hlist_head
*head
, unsigned int ui32ID
)
26 hlist_for_each_entry_rcu(psHN
, head
, sNode
)
28 if (psHN
->ui32ID
== ui32ID
)
36 static int ged_hash(GED_HASHTABLE_HANDLE hHashTable
, unsigned int ui32ID
)
38 GED_HASHTABLE
* psHT
= (GED_HASHTABLE
*)hHashTable
;
39 return hash_32(ui32ID
, psHT
->ui32Bits
);
42 GED_HASHTABLE_HANDLE
ged_hashtable_create(unsigned int ui32Bits
)
50 // Need to check the necessary
54 psHT
= (GED_HASHTABLE
*)ged_alloc(sizeof(GED_HASHTABLE
));
57 psHT
->ui32Bits
= ui32Bits
;
58 psHT
->ui32Length
= 1 << ui32Bits
;
59 psHT
->ui32CurrentID
= GED_HASHTABLE_INIT_ID
; // 0 = invalid
60 psHT
->psHashTable
= (struct hlist_head
*)ged_alloc(psHT
->ui32Length
* sizeof(struct hlist_head
));
61 if (psHT
->psHashTable
)
63 for (i
= 0; i
< psHT
->ui32Length
; i
++)
65 INIT_HLIST_HEAD(&psHT
->psHashTable
[i
]);
67 return (GED_HASHTABLE_HANDLE
)psHT
;
71 ged_hashtable_destroy(psHT
);
75 void ged_hashtable_destroy(GED_HASHTABLE_HANDLE hHashTable
)
77 GED_HASHTABLE
* psHT
= (GED_HASHTABLE
*)hHashTable
;
81 while(psHT
->ui32Count
> 0)
83 unsigned int ui32ID
= 0;
85 // get one to be freed
86 for (;i
< psHT
->ui32Length
; i
++)
88 struct hlist_head
*head
= &psHT
->psHashTable
[i
];
89 hlist_for_each_entry_rcu(psHN
, head
, sNode
)
91 ui32ID
= psHN
->ui32ID
;
100 if (i
>= psHT
->ui32Length
)
105 ged_hashtable_remove(psHT
, ui32ID
);
108 /* free the hash table */
109 ged_free(psHT
->psHashTable
, psHT
->ui32Length
* sizeof(struct hlist_head
));
110 ged_free(psHT
, sizeof(GED_HASHTABLE
));
114 GED_ERROR
ged_hashtable_insert(GED_HASHTABLE_HANDLE hHashTable
, void* pvoid
, unsigned int* pui32ID
)
116 GED_HASHTABLE
* psHT
= (GED_HASHTABLE
*)hHashTable
;
117 GED_HASHNODE
* psHN
= NULL
;
118 unsigned int ui32Hash
, ui32ID
;
120 if ((!psHT
) || (!pui32ID
))
122 return GED_ERROR_INVALID_PARAMS
;
125 ui32ID
= psHT
->ui32CurrentID
+ 1;
128 ui32Hash
= ged_hash(psHT
, ui32ID
);
129 psHN
= __ged_hashtable_find(&psHT
->psHashTable
[ui32Hash
], ui32ID
);
133 if (ui32ID
== 0)//skip the value 0
137 if (ui32ID
== psHT
->ui32CurrentID
)
139 return GED_ERROR_FAIL
;
148 psHN
= (GED_HASHNODE
*)ged_alloc(sizeof(GED_HASHNODE
));
152 psHN
->ui32ID
= ui32ID
;
153 psHT
->ui32CurrentID
= ui32ID
;
155 hlist_add_head_rcu(&psHN
->sNode
, &psHT
->psHashTable
[ui32Hash
]);
156 psHT
->ui32Count
+= 1;
160 return GED_ERROR_OOM
;
163 void ged_hashtable_remove(GED_HASHTABLE_HANDLE hHashTable
, unsigned int ui32ID
)
165 GED_HASHTABLE
* psHT
= (GED_HASHTABLE
*)hHashTable
;
168 unsigned int ui32Hash
= ged_hash(psHT
, ui32ID
);
169 GED_HASHNODE
* psHN
= __ged_hashtable_find(&psHT
->psHashTable
[ui32Hash
], ui32ID
);
172 hlist_del_rcu(&psHN
->sNode
);
174 ged_free(psHN
, sizeof(GED_HASHNODE
));
175 psHT
->ui32Count
-= 1;
180 void* ged_hashtable_find(GED_HASHTABLE_HANDLE hHashTable
, unsigned int ui32ID
)
182 GED_HASHTABLE
* psHT
= (GED_HASHTABLE
*)hHashTable
;
185 unsigned int ui32Hash
= ged_hash(psHT
, ui32ID
);
186 GED_HASHNODE
* psHN
= __ged_hashtable_find(&psHT
->psHashTable
[ui32Hash
], ui32ID
);
194 GED_LOGE("ged_hashtable_find: ui32ID=%u ui32Hash=%u psHN=%p\n", ui32ID
, ui32Hash
, psHN
);
201 GED_ERROR
ged_hashtable_set(GED_HASHTABLE_HANDLE hHashTable
, unsigned int ui32ID
, void* pvoid
)
203 GED_HASHTABLE
* psHT
= (GED_HASHTABLE
*)hHashTable
;
206 unsigned int ui32Hash
= ged_hash(psHT
, ui32ID
);
207 GED_HASHNODE
* psHN
= __ged_hashtable_find(&psHT
->psHashTable
[ui32Hash
], ui32ID
);
215 return GED_ERROR_INVALID_PARAMS
;