| TechTip: Create Hash Tables in RPG with the Dictionary ADT |
|
|
|
| Tips & Techniques - RPG | |||||
| Written by Adam Glauser | |||||
| Tuesday, 04 December 2007 18:00 | |||||
Sometimes other useful operations are added to a given implementation, such as...
A stack might be implemented using an array, a user space, or a database table as the storage area. The point of an ADT is that it allows us to think about a programming problem without worrying about how the structure is implemented. The Dictionary ADT A dictionary is an ADT that allows the programmer to store elements in the form of key-value pairs, much like an array. Unlike an array, the keys can be any type of data, not just positive integers. You could have keys that are floating point numbers or strings, or you could even have both in the same dictionary.
These are some of the other possible operations:
Sometimes a dictionary will allow multiple values to be associated with the same key, in which case these operations that operate on multiple values may be allowed:
To add to the confusion, dictionaries are also referred to as associative arrays, maps, or hash tables. Hash table is one of the more common names for dictionaries, because dictionaries are often implemented using tables (aka arrays) and a hash function. Hash tables enable very fast insertion and searching in most cases. In order to use an array to store the elements, we need some way to translate from the given key to an integer in the range [1,N], where N is the number of elements in the array. We will find this index value using two functions: a hash function and a compression map. Hash Codes The hash function takes the key as input and produces a hash code. The hash function needs certain properties in order for the hash table to perform well. Compression Maps The goal of the compression map is to transform the hash code h(x) into a suitable array index c(x). It should distribute the hash codes evenly over the range [1,N], where N is the capacity of the array we are using to store the elements. The two most popular compression maps are the division method, Collision HandlingIt is impossible to come up with a hashing function that has no collisions across all possible keys, because there are many more keys than hash codes. We try to avoid collisions as much as possible, because collision handling is where the performance of hash tables can start to suffer. The performance of a collision-handling scheme is usually measured relative to the load factor of the hash table. Load factor is the ratio of the number of elements in the hash table to the total number of elements in the array. So what happens if we try to add a key that has the same hash code as something that's already in the array? Separate ChainingUsing separate chaining, a collision is handled by storing a list of key-value pairs at each location in the array. When a collision occurs, the new key-value pair is added to the end of this list. The advantages of this method are its simplicity and its relatively good performance at high load factors. The disadvantages are that it tends not to perform as well as other methods on average and that it requires more storage overhead. Open Addressing When a collision occurs in a hash table using open addressing, a second probing algorithm determines the next spot in the array to check. Linear probing is the simplest probing method, where the probing algorithm checks for open slots by incrementing the array index by a fixed amount, usually 1. Linear probing tends to perform very well at low load factors, but the performance degrades very quickly at load factors above 0.8. Data Structure ArraysHash tables may seem like an overly complex solution, particularly for RPG programmers, who have such easy access to database tables. A simpler method of implementing a dictionary could use a data structure array to sort the key-value pairs. A number of experts have published articles on how to set up the data structure arrays. Paul Tuohy has a particularly clear explanation. Once you have a sorted array, searching for a particular key is pretty fast because binary search can be used. The Advantages of Hash Tables That said, hash tables have certain advantages for large data sets and applications in which the performance of dictionary operations is critical. If the load factor is kept at an appropriate level and a good hash function is used, collisions can be kept to a minimum. For all intents and purposes, the hash table method allows the time taken for the three main dictionary operations to stay constant no matter how many items are added to the dictionary. Other methods—such as using sorted arrays or using a sorting tree ADT—cannot boast this, as the time taken to insert, remove, or find elements using those methods increases as the number of elements increases. | |||||
View all articles by this author
|
|||||
| Last Updated on Saturday, 22 December 2007 02:46 |





[size="1">Code[/size>
[size="1">Code[/size>