Use ht_* in mixed.c

This commit is contained in:
alvarofe 2017-02-12 17:36:26 +01:00
parent ed8d668247
commit 8695dbf3b5
2 changed files with 63 additions and 46 deletions

View File

@ -1,14 +1,14 @@
#ifndef R_MIXED_H #ifndef R_MIXED_H
#define R_MIXED_H #define R_MIXED_H
#include <r_list.h> #include <r_list.h>
#include "ht.h" #include <sdb.h>
#define RMIXED_MAXKEYS 256 #define RMIXED_MAXKEYS 256
typedef struct r_mixed_data_t { typedef struct r_mixed_data_t {
int size; int size;
union { union {
RHashTable *ht; SdbHash *ht;
RHashTable64 *ht64; SdbHash *ht64;
} hash; } hash;
} RMixedData; } RMixedData;

View File

@ -2,9 +2,14 @@
#include <r_util.h> #include <r_util.h>
#define STR64OFF(x) sdb_fmt (2, "%"PFMT64x, x)
#define STR32OFF(x) sdb_fmt (3, "%"PFMT32x, x)
R_API RMixed *r_mixed_new () { R_API RMixed *r_mixed_new () {
RMixed *m = R_NEW (RMixed); RMixed *m = R_NEW (RMixed);
if (!m) return NULL; if (!m) {
return NULL;
}
memset (m->keys, 0, sizeof (m->keys)); memset (m->keys, 0, sizeof (m->keys));
m->list = r_list_new (); m->list = r_list_new ();
return m; return m;
@ -12,13 +17,14 @@ R_API RMixed *r_mixed_new () {
R_API void r_mixed_free (RMixed *m) { R_API void r_mixed_free (RMixed *m) {
int i; int i;
for (i=0; i<RMIXED_MAXKEYS; i++) { for (i = 0; i < RMIXED_MAXKEYS; i++) {
if (m->keys[i]) { if (m->keys[i]) {
switch (m->keys[i]->size) { switch (m->keys[i]->size) {
case 1: case 2: case 4: case 1: case 2: case 4:
r_hashtable_free (m->keys[i]->hash.ht); ht_free (m->keys[i]->hash.ht);
break; break;
case 8: r_hashtable64_free (m->keys[i]->hash.ht64); case 8:
ht_free (m->keys[i]->hash.ht64);
break; break;
} }
free (m->keys[i]); free (m->keys[i]);
@ -30,8 +36,8 @@ R_API void r_mixed_free (RMixed *m) {
} }
R_API int r_mixed_key_check(RMixed *m, int key, int sz) { R_API int r_mixed_key_check(RMixed *m, int key, int sz) {
if (key>=0 && key<RMIXED_MAXKEYS) { if (key >= 0 && key < RMIXED_MAXKEYS) {
if (sz==1 || sz==2 || sz==4 || sz==8) if (sz == 1 || sz == 2 || sz == 4 || sz == 8)
return true; return true;
} }
return false; return false;
@ -39,19 +45,20 @@ R_API int r_mixed_key_check(RMixed *m, int key, int sz) {
#define R_MIXED_KEY(m,x,y,z) r_mixed_key(m, r_offsetof(x,z), sizeof(y->z)) #define R_MIXED_KEY(m,x,y,z) r_mixed_key(m, r_offsetof(x,z), sizeof(y->z))
R_API int r_mixed_key(RMixed *m, int key, int size) { R_API int r_mixed_key(RMixed *m, int key, int size) {
if (size>0 && r_mixed_key_check (m, key, size)) { if (size > 0 && r_mixed_key_check (m, key, size)) {
if (m->keys[key]) { if (m->keys[key]) {
m->keys[key]->size = size; m->keys[key]->size = size;
} else { } else {
m->keys[key] = R_NEW (RMixedData); m->keys[key] = R_NEW (RMixedData);
if (!m->keys[key]) if (!m->keys[key]) {
return false; return false;
}
m->keys[key]->size = size; m->keys[key]->size = size;
switch (size) { switch (size) {
case 1: case 2: case 4: case 1: case 2: case 4:
m->keys[key]->hash.ht = r_hashtable_new (); m->keys[key]->hash.ht = ht_new (NULL, NULL, NULL);
return true; return true;
case 8: m->keys[key]->hash.ht64 = r_hashtable64_new (); case 8: m->keys[key]->hash.ht64 = ht_new (NULL, NULL, NULL);
return true; return true;
} }
} }
@ -62,21 +69,26 @@ R_API int r_mixed_key(RMixed *m, int key, int size) {
// static? // static?
R_API ut64 r_mixed_get_value(int key, int sz, const void *p) { R_API ut64 r_mixed_get_value(int key, int sz, const void *p) {
switch (sz) { switch (sz) {
case 1: return (ut64) *((ut8*)((ut8*)p+key)); case 1: return (ut64) *((ut8*)((ut8*)p + key));
case 2: return (ut64) *((ut16*)((ut8*)p+key)); case 2: return (ut64) *((ut16*)((ut8*)p + key));
case 4: return (ut64) *((ut32*)((ut8*)p+key)); case 4: return (ut64) *((ut32*)((ut8*)p + key));
case 8: return (ut64) *((ut32*)((ut8*)p+key)); case 8: return (ut64) *((ut32*)((ut8*)p + key));
} }
return 0LL; return 0LL;
} }
R_API RList *r_mixed_get (RMixed *m, int key, ut64 value) { R_API RList *r_mixed_get (RMixed *m, int key, ut64 value) {
if (key>=0 && key<RMIXED_MAXKEYS) if (key >= 0 && key < RMIXED_MAXKEYS) {
if (m->keys[key]) if (m->keys[key]) {
switch (m->keys[key]->size) { switch (m->keys[key]->size) {
case 1: case 2: case 4: case 1:
return r_hashtable_lookup (m->keys[key]->hash.ht, (ut32)value); case 2:
case 8: return r_hashtable64_lookup (m->keys[key]->hash.ht64, value); case 4:
return ht_find (m->keys[key]->hash.ht, STR32OFF (value), NULL);
case 8:
return ht_find (m->keys[key]->hash.ht64, STR64OFF (value), NULL);
}
}
} }
return NULL; return NULL;
} }
@ -85,41 +97,44 @@ R_API void *r_mixed_get0 (RMixed *m, int key, ut64 value) {
RList *list = r_mixed_get (m, key, value); RList *list = r_mixed_get (m, key, value);
if (list && !r_list_empty (list)) { if (list && !r_list_empty (list)) {
RListIter *head = r_list_head (list); RListIter *head = r_list_head (list);
if (head) return head->data; if (head) {
return head->data;
}
} }
return NULL; return NULL;
} }
R_API int r_mixed_add (RMixed *m, void *p) { R_API int r_mixed_add(RMixed *m, void *p) {
RHashTable *ht; SdbHash *ht;
RHashTable64 *ht64; SdbHash *ht64;
RList *list = NULL; RList *list = NULL;
ut64 value; ut64 value;
int i, size, ret = false;; int i, size, ret = false;;
r_list_append (m->list, p); r_list_append (m->list, p);
for (i=0; i<RMIXED_MAXKEYS; i++) { for (i = 0; i < RMIXED_MAXKEYS; i++) {
if (!m->keys[i]) if (!m->keys[i]) {
continue; continue;
}
size = m->keys[i]->size; size = m->keys[i]->size;
value = r_mixed_get_value (i, size, p); value = r_mixed_get_value (i, size, p);
switch (size) { switch (size) {
case 1: case 2: case 4: case 1: case 2: case 4:
ht = m->keys[i]->hash.ht; ht = m->keys[i]->hash.ht;
list = r_hashtable_lookup (ht, (ut32)value); list = ht_find (ht, STR32OFF (value), NULL);
if (!list) { if (!list) {
list = r_list_new (); list = r_list_new ();
r_hashtable_insert (ht, (ut32)value, list); ht_insert (ht, STR32OFF (value), list);
} }
r_list_append (list, p); r_list_append (list, p);
ret = true; ret = true;
break; break;
case 8: case 8:
ht64 = m->keys[i]->hash.ht64; ht64 = m->keys[i]->hash.ht64;
list = r_hashtable64_lookup (ht64, value); list = ht_find (ht64, STR64OFF (value), NULL);
if (!list) { if (!list) {
list = r_list_new (); list = r_list_new ();
r_hashtable64_insert (ht64, value, list); ht_insert (ht64, STR64OFF (value), list);
} }
r_list_append (list, p); r_list_append (list, p);
ret = true; ret = true;
@ -132,14 +147,15 @@ R_API int r_mixed_add (RMixed *m, void *p) {
R_API int r_mixed_del (RMixed *m, void *p) { R_API int r_mixed_del (RMixed *m, void *p) {
int i; int i;
r_list_delete_data (m->list, p); r_list_delete_data (m->list, p);
for (i=0; i<RMIXED_MAXKEYS; i++) { for (i = 0; i < RMIXED_MAXKEYS; i++) {
ut64 value = r_mixed_get_value (i, m->keys[i]->size, p); ut64 value = r_mixed_get_value (i, m->keys[i]->size, p);
if (!m->keys[i]) continue; if (!m->keys[i]) continue;
switch (m->keys[i]->size) { switch (m->keys[i]->size) {
case 1: case 2: case 4: case 1: case 2: case 4:
r_hashtable_remove (m->keys[i]->hash.ht, (ut32)value); ht_delete (m->keys[i]->hash.ht, STR32OFF (value));
break; break;
case 8: r_hashtable64_remove (m->keys[i]->hash.ht64, value); case 8:
ht_delete (m->keys[i]->hash.ht64, STR64OFF (value));
break; break;
} }
} }
@ -148,7 +164,7 @@ R_API int r_mixed_del (RMixed *m, void *p) {
R_API void r_mixed_change_begin(RMixed *m, void *p) { R_API void r_mixed_change_begin(RMixed *m, void *p) {
int i; int i;
for (i=0; i<RMIXED_MAXKEYS; i++) for (i = 0; i < RMIXED_MAXKEYS; i++)
if (m->keys[i]) { if (m->keys[i]) {
m->state[i] = r_mixed_get_value (i, m->keys[i]->size, p); m->state[i] = r_mixed_get_value (i, m->keys[i]->size, p);
eprintf ("store state %d (0x%08"PFMT64x")\n", i, m->state[i]); eprintf ("store state %d (0x%08"PFMT64x")\n", i, m->state[i]);
@ -158,10 +174,10 @@ R_API void r_mixed_change_begin(RMixed *m, void *p) {
R_API bool r_mixed_change_end(RMixed *m, void *p) { R_API bool r_mixed_change_end(RMixed *m, void *p) {
int i; int i;
void *q; void *q;
for (i=0; i<RMIXED_MAXKEYS; i++) { for (i = 0; i < RMIXED_MAXKEYS; i++) {
if (m->keys[i]) { if (m->keys[i]) {
RHashTable *ht = m->keys[i]->hash.ht; SdbHash *ht = m->keys[i]->hash.ht;
RHashTable64 *ht64 = m->keys[i]->hash.ht64; SdbHash *ht64 = m->keys[i]->hash.ht64;
ut64 newstate = r_mixed_get_value (i, m->keys[i]->size, p); ut64 newstate = r_mixed_get_value (i, m->keys[i]->size, p);
if (newstate != m->state[i]) { if (newstate != m->state[i]) {
// rehash this pointer // rehash this pointer
@ -183,26 +199,27 @@ R_API bool r_mixed_change_end(RMixed *m, void *p) {
r_list_free (list); r_list_free (list);
switch (m->keys[i]->size) { switch (m->keys[i]->size) {
case 1: case 2: case 4: case 1: case 2: case 4:
r_hashtable_remove (ht, m->state[i]); ht_delete (ht, STR32OFF (m->state[i]));
break; break;
case 8: r_hashtable64_remove (ht64, m->state[i]); case 8:
ht_delete (ht64, STR64OFF (m->state[i]));
break; break;
} }
} }
switch (m->keys[i]->size) { switch (m->keys[i]->size) {
case 1: case 2: case 4: case 1: case 2: case 4:
list = r_hashtable_lookup (ht, (ut32)newstate); list = ht_find (ht, STR32OFF (newstate), NULL);
if (!list) { if (!list) {
list = r_list_new (); list = r_list_new ();
r_hashtable_insert (ht, (ut32)newstate, list); ht_insert (ht, STR32OFF (newstate), list);
} }
r_list_append (list, p); r_list_append (list, p);
break; break;
case 8: case 8:
list = r_hashtable64_lookup (ht64, newstate); list = ht_find (ht64, STR64OFF (newstate), NULL);
if (!list) { if (!list) {
list = r_list_new (); list = r_list_new ();
r_hashtable64_insert (ht64, newstate, list); ht_insert (ht64, STR64OFF (newstate), list);
} }
r_list_append (list, p); r_list_append (list, p);
break; break;