aboutsummaryrefslogtreecommitdiff
path: root/pkg/utilities/nttools/tunits/unhash.x
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/utilities/nttools/tunits/unhash.x
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'pkg/utilities/nttools/tunits/unhash.x')
-rw-r--r--pkg/utilities/nttools/tunits/unhash.x212
1 files changed, 212 insertions, 0 deletions
diff --git a/pkg/utilities/nttools/tunits/unhash.x b/pkg/utilities/nttools/tunits/unhash.x
new file mode 100644
index 00000000..3ae9c24e
--- /dev/null
+++ b/pkg/utilities/nttools/tunits/unhash.x
@@ -0,0 +1,212 @@
+# A set of procedures that implement a generic hash table. The hash table
+# stores the key, plus a pointer to the value structure. It should be
+# wrapped in a more specific set of calls that can read the value structure
+
+define LEN_UNHSTRUCT 5
+
+define UNH_SIZE Memi[$1]
+define UNH_NEXT Memi[$1+1]
+define UNH_KEYBUF Memi[$1+2]
+define UNH_VALBUF Memi[$1+3]
+define UNH_STRBUF Memi[$1+4]
+
+define UNH_KEY Memi[UNH_KEYBUF($1)+$2]
+define UNH_VALUE Memi[UNH_VALBUF($1)+$2]
+
+#* HISTORY *
+#* B.Simon 07-Jan-99 Original
+
+# ADD_UNHASH -- Add a new keyword and value to the hash table
+
+procedure add_unhash (hash, keyword, value)
+
+pointer hash # i: Descriptor of hash table
+char keyword[ARB] # i: Keyword to add to hash table
+pointer value # i: Value descriptor
+#--
+int index, nc
+
+string duplicate "Cannot add duplicate keyword to hash table"
+
+int gstrcpy(), loc_unhash()
+
+begin
+ # Find where keyword should be inserted
+
+ index = loc_unhash (hash, keyword)
+
+ # Adding duplicate keywords is not allowed
+
+ if (UNH_KEY(hash,index) != NULL) {
+ call tuniterr (duplicate, keyword)
+
+ } else {
+ UNH_KEY(hash,index) = UNH_NEXT(hash)
+ UNH_VALUE(hash,index) = value
+
+ nc = gstrcpy (keyword, Memc[UNH_NEXT(hash)], ARB)
+ UNH_NEXT(hash) = UNH_NEXT(hash) + nc + 1
+ }
+end
+
+# CALC_UNHASH -- Calculate hash index and step size from keyword
+
+procedure calc_unhash (hash, keyword, index, step)
+
+pointer hash # i: Descriptor of hash table
+char keyword[ARB] # i: Keyword to search for in hash table
+int index # o: Location to place keyword at in hash
+int step # o: Step size in case location is filled
+#--
+int ic
+
+begin
+ # Standard hash table function based on munging characters
+
+ index = 0
+ step = 0
+
+ for (ic = 1; keyword[ic] != EOS; ic = ic + 1) {
+ index = 2 * index + keyword[ic]
+ step = step + keyword[ic]
+ }
+
+ # This line ensures the step size is odd
+
+ step = step - mod (step, 2) + 1
+end
+
+# EACH_UNHASH -- Retrieve values from hash table serially
+
+int procedure each_unhash (hash, index, keyword, value, maxch)
+
+pointer hash # i: Descriptor of hash table
+int index # u: Index of next slot in hash table to examine
+char keyword[ARB] # o: Keyword name
+pointer value # o: Keyword value
+int maxch # i: Maximum length of keyword
+#--
+
+begin
+ while (index < UNH_SIZE(hash)) {
+ if (UNH_KEY(hash,index) != NULL) {
+ call strcpy (Memc[UNH_KEY(hash,index)], keyword, maxch)
+ value = UNH_VALUE(hash,index)
+ index = index + 1
+ return (OK)
+ }
+
+ index = index + 1
+ }
+
+ return (EOF)
+end
+
+# FREE_UNHASH -- Free a hash table
+
+procedure free_unhash (hash)
+
+pointer hash # i: hash table descriptor
+#--
+
+begin
+ # This code assumes that all memory associated
+ # with the values has already been freed
+
+ call mfree (UNH_STRBUF(hash), TY_CHAR)
+ call mfree (UNH_VALBUF(hash), TY_INT)
+ call mfree (UNH_KEYBUF(hash), TY_INT)
+ call mfree (hash, TY_INT)
+end
+
+# GET_UNHASH -- Return a keyword's value from a hash
+
+int procedure get_unhash (hash, keyword, value)
+
+pointer hash # i: Descriptor of hash table
+char keyword[ARB] # i: Keyword to add to hash table
+pointer value # o: pointer to hash table value
+#--
+int index, status
+
+int loc_unhash ()
+
+begin
+ # The keyword is found if its slot is not null
+
+ index = loc_unhash (hash, keyword)
+
+ if (UNH_KEY(hash,index) == NULL) {
+ value = NULL
+ status = NO
+ } else {
+ value = UNH_VALUE(hash,index)
+ status = YES
+ }
+
+ return (status)
+end
+
+# LOC_UNHASH -- Return index of location where a key should be inserted
+
+int procedure loc_unhash (hash, keyword)
+
+pointer hash # i: Descriptor of hash table
+char keyword[ARB] # i: Keyword to add to hash table
+#--
+int index, step
+
+bool streq()
+
+begin
+ # Calculate initial guess at position in hash table
+ # and step size in case guessed position is already filled
+
+ call calc_unhash (hash, keyword, index, step)
+ index = mod (index, UNH_SIZE(hash))
+
+ # Loop until an empty slot is found or the keyword is matched
+
+ repeat {
+ if (UNH_KEY(hash,index) == NULL) {
+ break
+
+ } else if (streq (Memc[UNH_KEY(hash,index)], keyword)) {
+ break
+ }
+
+ index = mod (index + step, UNH_SIZE(hash))
+ }
+
+ return (index)
+end
+
+# NEW_UNHASH -- Create a new hash table
+
+pointer procedure new_unhash (nkey, keysize)
+
+int nkey # i: number of keywords in the hash
+int keysize # i: maximum length of a key
+#--
+int size
+pointer hash
+
+begin
+ # Find a power of two greater than the number of keywords
+
+ for (size = 1; size < 2 * nkey; size = 2 * size)
+ ;
+
+ # Allocate structure for hash and set initial values
+
+ call malloc (hash, LEN_UNHSTRUCT, TY_INT)
+ call calloc (UNH_KEYBUF(hash), size, TY_INT)
+ call calloc (UNH_VALBUF(hash), size, TY_INT)
+ call malloc (UNH_STRBUF(hash), size*(keysize+1), TY_CHAR)
+
+ UNH_SIZE(hash) = size
+ UNH_NEXT(hash) = UNH_STRBUF(hash)
+
+ return (hash)
+end
+