diff options
author | vitalyisaev <vitalyisaev@ydb.tech> | 2023-11-30 13:26:22 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@ydb.tech> | 2023-11-30 15:44:45 +0300 |
commit | 0a98fece5a9b54f16afeb3a94b3eb3105e9c3962 (patch) | |
tree | 291d72dbd7e9865399f668c84d11ed86fb190bbf /contrib/tools/swig/Source/DOH/hash.c | |
parent | cb2c8d75065e5b3c47094067cb4aa407d4813298 (diff) | |
download | ydb-0a98fece5a9b54f16afeb3a94b3eb3105e9c3962.tar.gz |
YQ Connector:Use docker-compose in integrational tests
Diffstat (limited to 'contrib/tools/swig/Source/DOH/hash.c')
-rw-r--r-- | contrib/tools/swig/Source/DOH/hash.c | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/DOH/hash.c b/contrib/tools/swig/Source/DOH/hash.c new file mode 100644 index 0000000000..b9d501e3c4 --- /dev/null +++ b/contrib/tools/swig/Source/DOH/hash.c @@ -0,0 +1,583 @@ +/* ----------------------------------------------------------------------------- + * This file is part of SWIG, which is licensed as a whole under version 3 + * (or any later version) of the GNU General Public License. Some additional + * terms also apply to certain portions of SWIG. The full details of the SWIG + * license and copyrights can be found in the LICENSE and COPYRIGHT files + * included with the SWIG source code as distributed by the SWIG developers + * and at https://www.swig.org/legal.html. + * + * hash.c + * + * Implements a simple hash table object. + * ----------------------------------------------------------------------------- */ + +#include "dohint.h" + +extern DohObjInfo DohHashType; + +/* Hash node */ +typedef struct HashNode { + DOH *key; + DOH *object; + struct HashNode *next; +} HashNode; + +/* Hash object */ +typedef struct Hash { + DOH *file; + int line; + HashNode **hashtable; + int hashsize; + int nitems; +} Hash; + +/* Key interning structure */ +typedef struct KeyValue { + char *cstr; + DOH *sstr; + struct KeyValue *left; + struct KeyValue *right; +} KeyValue; + +static KeyValue *root = 0; +static int max_expand = 1; + +/* Find or create a key in the interned key table */ +static DOH *find_key(DOH *doh_c) { + char *c = (char *) doh_c; + KeyValue *r, *s; + int d = 0; + /* OK, sure, we use a binary tree for maintaining interned + symbols. Then we use their hash values for accessing secondary + hash tables. */ + r = root; + s = 0; + while (r) { + s = r; + d = strcmp(r->cstr, c); + if (d == 0) + return r->sstr; + if (d < 0) + r = r->left; + else + r = r->right; + } + /* fprintf(stderr,"Interning '%s'\n", c); */ + r = (KeyValue *) DohMalloc(sizeof(KeyValue)); + r->cstr = (char *) DohMalloc(strlen(c) + 1); + strcpy(r->cstr, c); + r->sstr = NewString(c); + DohIntern(r->sstr); + r->left = 0; + r->right = 0; + if (!s) { + root = r; + } else { + if (d < 0) + s->left = r; + else + s->right = r; + } + return r->sstr; +} + +#define HASH_INIT_SIZE 7 + +/* Create a new hash node */ +static HashNode *NewNode(DOH *k, void *obj) { + HashNode *hn = (HashNode *) DohMalloc(sizeof(HashNode)); + hn->key = k; + Incref(hn->key); + hn->object = obj; + Incref(obj); + hn->next = 0; + return hn; +} + +/* Delete a hash node */ +static void DelNode(HashNode *hn) { + Delete(hn->key); + Delete(hn->object); + DohFree(hn); +} + +/* ----------------------------------------------------------------------------- + * DelHash() + * + * Delete a hash table. + * ----------------------------------------------------------------------------- */ + +static void DelHash(DOH *ho) { + Hash *h = (Hash *) ObjData(ho); + HashNode *n, *next; + int i; + + for (i = 0; i < h->hashsize; i++) { + n = h->hashtable[i]; + while (n) { + next = n->next; + DelNode(n); + n = next; + } + } + DohFree(h->hashtable); + h->hashtable = 0; + h->hashsize = 0; + DohFree(h); +} + +/* ----------------------------------------------------------------------------- + * Hash_clear() + * + * Clear all of the entries in the hash table. + * ----------------------------------------------------------------------------- */ + +static void Hash_clear(DOH *ho) { + Hash *h = (Hash *) ObjData(ho); + HashNode *n, *next; + int i; + + for (i = 0; i < h->hashsize; i++) { + n = h->hashtable[i]; + while (n) { + next = n->next; + DelNode(n); + n = next; + } + h->hashtable[i] = 0; + } + h->nitems = 0; +} + +/* resize the hash table */ +static void resize(Hash *h) { + HashNode *n, *next, **table; + int oldsize, newsize; + int i, p, hv; + + if (h->nitems < 2 * h->hashsize) + return; + + /* Too big. We have to rescale everything now */ + oldsize = h->hashsize; + + /* Calculate a new size */ + newsize = 2 * oldsize + 1; + p = 3; + while (p < (newsize >> 1)) { + if (((newsize / p) * p) == newsize) { + newsize += 2; + p = 3; + continue; + } + p = p + 2; + } + + table = (HashNode **) DohCalloc(newsize, sizeof(HashNode *)); + + /* Walk down the old set of nodes and re-place */ + h->hashsize = newsize; + for (i = 0; i < oldsize; i++) { + n = h->hashtable[i]; + while (n) { + hv = Hashval(n->key) % newsize; + next = n->next; + n->next = table[hv]; + table[hv] = n; + n = next; + } + } + DohFree(h->hashtable); + h->hashtable = table; +} + +/* ----------------------------------------------------------------------------- + * Hash_setattr() + * + * Set an attribute in the hash table. Deletes the existing entry if it already + * exists. + * ----------------------------------------------------------------------------- */ + +static int Hash_setattr(DOH *ho, DOH *k, DOH *obj) { + int hv; + HashNode *n, *prev; + Hash *h = (Hash *) ObjData(ho); + + if (!obj) { + return DohDelattr(ho, k); + } + if (!DohCheck(k)) + k = find_key(k); + if (!DohCheck(obj)) { + obj = NewString((char *) obj); + Decref(obj); + } + hv = (Hashval(k)) % h->hashsize; + n = h->hashtable[hv]; + prev = 0; + while (n) { + if (Cmp(n->key, k) == 0) { + /* Node already exists. Just replace its contents */ + if (n->object == obj) { + /* Whoa. Same object. Do nothing */ + return 1; + } + Delete(n->object); + n->object = obj; + Incref(obj); + return 1; /* Return 1 to indicate a replacement */ + } else { + prev = n; + n = n->next; + } + } + /* Add this to the table */ + n = NewNode(k, obj); + if (prev) + prev->next = n; + else + h->hashtable[hv] = n; + h->nitems++; + resize(h); + return 0; +} + +/* ----------------------------------------------------------------------------- + * Hash_getattr() + * + * Get an attribute from the hash table. Returns 0 if it doesn't exist. + * ----------------------------------------------------------------------------- */ +typedef int (*binop) (DOH *obj1, DOH *obj2); + + +static DOH *Hash_getattr(DOH *h, DOH *k) { + DOH *obj = 0; + Hash *ho = (Hash *) ObjData(h); + DOH *ko = DohCheck(k) ? k : find_key(k); + int hv = Hashval(ko) % ho->hashsize; + DohObjInfo *k_type = ((DohBase*)ko)->type; + HashNode *n = ho->hashtable[hv]; + if (k_type->doh_equal) { + binop equal = k_type->doh_equal; + while (n) { + DohBase *nk = (DohBase *)n->key; + if ((k_type == nk->type) && equal(ko, nk)) obj = n->object; + n = n->next; + } + } else { + binop cmp = k_type->doh_cmp; + while (n) { + DohBase *nk = (DohBase *)n->key; + if ((k_type == nk->type) && (cmp(ko, nk) == 0)) obj = n->object; + n = n->next; + } + } + return obj; +} + +/* ----------------------------------------------------------------------------- + * Hash_delattr() + * + * Delete an object from the hash table. + * ----------------------------------------------------------------------------- */ + +static int Hash_delattr(DOH *ho, DOH *k) { + HashNode *n, *prev; + int hv; + Hash *h = (Hash *) ObjData(ho); + + if (!DohCheck(k)) + k = find_key(k); + hv = Hashval(k) % h->hashsize; + n = h->hashtable[hv]; + prev = 0; + while (n) { + if (Cmp(n->key, k) == 0) { + /* Found it, kill it */ + + if (prev) { + prev->next = n->next; + } else { + h->hashtable[hv] = n->next; + } + DelNode(n); + h->nitems--; + return 1; + } + prev = n; + n = n->next; + } + return 0; +} + +static DohIterator Hash_firstiter(DOH *ho) { + DohIterator iter; + Hash *h = (Hash *) ObjData(ho); + iter.object = ho; + iter._current = 0; + iter.item = 0; + iter.key = 0; + iter._index = 0; /* Index in hash table */ + while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) + iter._index++; + + if (iter._index >= h->hashsize) { + return iter; + } + iter._current = h->hashtable[iter._index]; + iter.item = ((HashNode *) iter._current)->object; + iter.key = ((HashNode *) iter._current)->key; + + /* Actually save the next slot in the hash. This makes it possible to + delete the item being iterated over without trashing the universe */ + iter._current = ((HashNode *) iter._current)->next; + return iter; +} + +static DohIterator Hash_nextiter(DohIterator iter) { + Hash *h = (Hash *) ObjData(iter.object); + if (!iter._current) { + iter._index++; + while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) { + iter._index++; + } + if (iter._index >= h->hashsize) { + iter.item = 0; + iter.key = 0; + iter._current = 0; + return iter; + } + iter._current = h->hashtable[iter._index]; + } + iter.key = ((HashNode *) iter._current)->key; + iter.item = ((HashNode *) iter._current)->object; + + /* Store the next node to iterator on */ + iter._current = ((HashNode *) iter._current)->next; + return iter; +} + +/* ----------------------------------------------------------------------------- + * Hash_keys() + * + * Return a list of keys + * ----------------------------------------------------------------------------- */ + +static DOH *Hash_keys(DOH *so) { + DOH *keys; + Iterator i; + + keys = NewList(); + for (i = First(so); i.key; i = Next(i)) { + Append(keys, i.key); + } + return keys; +} + +/* ----------------------------------------------------------------------------- + * DohSetMaxHashExpand() + * + * Controls how many Hash objects are displayed in full in Hash_str + * ----------------------------------------------------------------------------- */ + +void DohSetMaxHashExpand(int count) { + max_expand = count; +} + +/* ----------------------------------------------------------------------------- + * DohGetMaxHashExpand() + * + * Returns how many Hash objects are displayed in full in Hash_str + * ----------------------------------------------------------------------------- */ + +int DohGetMaxHashExpand(void) { + return max_expand; +} + +/* ----------------------------------------------------------------------------- + * Hash_str() + * + * Create a string representation of a hash table (mainly for debugging). + * ----------------------------------------------------------------------------- */ + +static DOH *Hash_str(DOH *ho) { + int i, j; + HashNode *n; + DOH *s; + static int expanded = 0; + static const char *tab = " "; + Hash *h = (Hash *) ObjData(ho); + + s = NewStringEmpty(); + if (ObjGetMark(ho)) { + Printf(s, "Hash(%p)", ho); + return s; + } + if (expanded >= max_expand) { + /* replace each hash attribute with a '.' */ + Printf(s, "Hash(%p) {", ho); + for (i = 0; i < h->hashsize; i++) { + n = h->hashtable[i]; + while (n) { + Putc('.', s); + n = n->next; + } + } + Putc('}', s); + return s; + } + ObjSetMark(ho, 1); + Printf(s, "Hash(%p) {\n", ho); + for (i = 0; i < h->hashsize; i++) { + n = h->hashtable[i]; + while (n) { + for (j = 0; j < expanded + 1; j++) + Printf(s, tab); + expanded += 1; + Printf(s, "'%s' : %s, \n", n->key, n->object); + expanded -= 1; + n = n->next; + } + } + for (j = 0; j < expanded; j++) + Printf(s, tab); + Printf(s, "}"); + ObjSetMark(ho, 0); + return s; +} + +/* ----------------------------------------------------------------------------- + * Hash_len() + * + * Return number of entries in the hash table. + * ----------------------------------------------------------------------------- */ + +static int Hash_len(DOH *ho) { + Hash *h = (Hash *) ObjData(ho); + return h->nitems; +} + +/* ----------------------------------------------------------------------------- + * CopyHash() + * + * Make a copy of a hash table. Note: this is a shallow copy. + * ----------------------------------------------------------------------------- */ + +static DOH *CopyHash(DOH *ho) { + Hash *h, *nh; + HashNode *n; + DOH *nho; + + int i; + h = (Hash *) ObjData(ho); + nh = (Hash *) DohMalloc(sizeof(Hash)); + nh->hashsize = h->hashsize; + nh->hashtable = (HashNode **) DohMalloc(nh->hashsize * sizeof(HashNode *)); + for (i = 0; i < nh->hashsize; i++) { + nh->hashtable[i] = 0; + } + nh->nitems = 0; + nh->line = h->line; + nh->file = h->file; + if (nh->file) + Incref(nh->file); + + nho = DohObjMalloc(&DohHashType, nh); + for (i = 0; i < h->hashsize; i++) { + n = h->hashtable[i]; + while (n) { + Hash_setattr(nho, n->key, n->object); + n = n->next; + } + } + return nho; +} + + + +static void Hash_setfile(DOH *ho, DOH *file) { + DOH *fo; + Hash *h = (Hash *) ObjData(ho); + + if (!DohCheck(file)) { + fo = NewString(file); + Decref(fo); + } else + fo = file; + Incref(fo); + Delete(h->file); + h->file = fo; +} + +static DOH *Hash_getfile(DOH *ho) { + Hash *h = (Hash *) ObjData(ho); + return h->file; +} + +static void Hash_setline(DOH *ho, int line) { + Hash *h = (Hash *) ObjData(ho); + h->line = line; +} + +static int Hash_getline(DOH *ho) { + Hash *h = (Hash *) ObjData(ho); + return h->line; +} + +/* ----------------------------------------------------------------------------- + * type information + * ----------------------------------------------------------------------------- */ + +static DohHashMethods HashHashMethods = { + Hash_getattr, + Hash_setattr, + Hash_delattr, + Hash_keys, +}; + +DohObjInfo DohHashType = { + "Hash", /* objname */ + DelHash, /* doh_del */ + CopyHash, /* doh_copy */ + Hash_clear, /* doh_clear */ + Hash_str, /* doh_str */ + 0, /* doh_data */ + 0, /* doh_dump */ + Hash_len, /* doh_len */ + 0, /* doh_hash */ + 0, /* doh_cmp */ + 0, /* doh_equal */ + Hash_firstiter, /* doh_first */ + Hash_nextiter, /* doh_next */ + Hash_setfile, /* doh_setfile */ + Hash_getfile, /* doh_getfile */ + Hash_setline, /* doh_setline */ + Hash_getline, /* doh_getline */ + &HashHashMethods, /* doh_mapping */ + 0, /* doh_sequence */ + 0, /* doh_file */ + 0, /* doh_string */ + 0, /* doh_positional */ + 0, +}; + +/* ----------------------------------------------------------------------------- + * NewHash() + * + * Create a new hash table. + * ----------------------------------------------------------------------------- */ + +DOH *DohNewHash(void) { + Hash *h; + int i; + h = (Hash *) DohMalloc(sizeof(Hash)); + h->hashsize = HASH_INIT_SIZE; + h->hashtable = (HashNode **) DohMalloc(h->hashsize * sizeof(HashNode *)); + for (i = 0; i < h->hashsize; i++) { + h->hashtable[i] = 0; + } + h->nitems = 0; + h->file = 0; + h->line = 0; + return DohObjMalloc(&DohHashType, h); +} |