QUESTIONS LAST TIME: - SiteRiter questions, New TA, Memory and pointer, the uber data structure TODAY: - SiteRiter final turn-in details, README.txt - The uber data structure. - Hash tables - Collision handling PROJECT 1 STATUS DAY 22: +--------------+ - FINAL DELIVERABLE FRI SEP 20, 2013 12N MST |1 days 1 hours| +--------------+ - BONUS PAIN SALE! If you >need< it, you can take the ENTIRE WEEKEND, until MON SEP 23 12NOON MST, for the low low price of ONE LATE DAY - Final deliverable latest turn-in for ANY CREDIT is UNCHANGED, still TUE SEP 24, 2013 9AM MST - Make It WORK! PROJECT 1 Q: Exactly what do we turn-in? A: A single JAR file named P1D3.jar, containing com.putable.siteriter.test containing your test suite com.putable.siteriter.YOURNAME containing your SDLParserImpl and support com.putable.siteriter.server containing your mods to the ExampleServer README.txt a single text file PROJECT 1 Q: Exactly what do we turn-in? A: A single JAR file named P1D3.jar, containing com.putable.siteriter.test containing your test suite com.putable.siteriter.YOURNAME containing your SDLParserImpl and support com.putable.siteriter.server containing your mods to the ExampleServer README.txt a single text file Q: Why should we have a README.txt? A: Because every piece of software should have a README.txt. It's explicitly there to be a starting point for people getting the software. Q: What should be in the README.txt? A: See below PROJECT 1 Q: Exactly what do we turn-in? A: A single JAR file named P1D3.jar, containing com.putable.siteriter.test containing your test suite com.putable.siteriter.YOURNAME containing your SDLParserImpl and support com.putable.siteriter.server containing your mods to the ExampleServer README.txt a single text file Q: Why should we have a README.txt? A: Because every piece of software should have a README.txt. It's explicitly there to be a starting point for people getting the software. Q: What should be in the README.txt? A: See below Q: If we wrote some really cool SiteRiter grammars, can we include them? A: Yes, if you want! Put them at the top-level next to the README.txt PROJECT 1 README.txt A single text file AT THE TOP-LEVEL of the JAR file. Containing at least: - Your name! - Identification of this class and this project - Description of any spec problems you encountered and how you resolved them - Description of any bugs in the code that you are aware of. -> Bugs hurt, but _documented_ and _test detected_ bugs hurt less! -> If you are aware of ANY bugs in your code, your TESTS should show them! It MAY also include: - Description of your solution - Any particular points of pride you want people to notice PROJECT 1 DELIVERABLES - SAMPLE README.txt 1/3 CS351 Project 1 - Implementing SiteRiter CONTACT INFORMATION Project author: Tess Tawl Email: ttawl@unm.edu Date: Thu Sep 19 09:55:12 2013 PROJECT DESCRIPTION SiteRiter is a system for generating web sites based on custom grammars. See http://cs.unm.edu/~ackley/351/projects/1 for a complete description. In addition to the functionality described there, this implementation also provides the following features: .. PROJECT 1 DELIVERABLES - SAMPLE README.txt 2/3 .. SPECIFICATION ISSUES The following discussion is with respect to the SiteRiter v1.0 specification. The following issues were noted during project development, presented along with the chosen resolutions: - ISSUE #1: (C.X.Y) on pancake buttering does not make clear whether it is legal to put butter under the bottommost cake. - RESOLUTION #1: My SDLParserImpl does _not_ allow it, because - IMPLEMENTATION SPECIFICS The enclosed SiteRiter is a fully-conforming implementation of the SiteRiter v1.0 specification. Points of particular design interest include - .. PROJECT 1 DELIVERABLES - SAMPLE README.txt 3/3 .. ACKNOWLEDGMENTS: Professor Ackley designed the spec as well as providing some test cases and a sample implementation. Brady helped me with a problem getting HashMap code to compile. I discussed PRNG seeding and URL parsing with Val Atull (347m3@abcquad.org) but didn't use the suggestions, and KNOWN BUGS: Well, perhaps one or two little ones.. For example, redefining the start symbol rule doesn't 'take' (detected by test). Also, if a secondary start symbol rule is redefined to NOT be a secondary start, it can still be accessed (detected by test). Also, it seems I get a 'Null Pointer Exception' sometimes, but I haven't been able to reduce that to a test case. Also, ------------------------------------------------------------------ WARNING WARNING WARNING YOU WILL LOSE 1% CREDIT IF YOUR README.txt DOESN'T CONTAIN YOUR ACTUAL NAME, OR DOES CONTAIN THIS WARNING OR ANY INSTANCES OF THE STRING ''!! ------------------------------------------------------------------ MEMORY AND POINTERS - BLOWOUT! class Test { c (Test) args String[] private static int c = 0; +------+ +-------+ +------+ private int x = ++c; | 2 | | ------->| | private char y = 'd'; +------+ +-------+ | | private Test t; i j | ? | public static void main(String[] args) { +-----+ +-------+ | | /* HERE0 */ | 7 | | 7 | | | int i = 7; +-----+ +-------+ | | int j = i; /* HERE1 */ | | k b | | int k = 9; a +-----+ +------+ | | Integer m = k; /* HERE2 */ +-----+ | 9 | | | | +------+ |null | +-----+ +-|----+ Test a = new Test();/* HERE3 */ +-----+ Test | Test b = new Test();/* HERE4 */ +--------+<----/ a.t = b; /* HERE5 */ | 1 | b = a; /* HERE6 */ |--------| a = null; /* HERE7 */ | 'd' | b.t = null; /*HERE8*/ } |--------| } | null | +--------+ MAP - THE UBER DATASTRUCTURE - TYPES OF MAPS All Known Implementing Classes: AbstractMap, Attributes, HashMap, Hashtable, IdentityHashMap, RenderingHints, TreeMap, WeakHashMap (Actually, that was from Java 1.4.2. Now it's like: All Known Implementing Classes: AbstractMap, Attributes, AuthProvider, ConcurrentHashMap, ConcurrentSkipListMap, EnumMap, HashMap, Hashtable, IdentityHashMap, LinkedHashMap, PrinterStateReasons, Properties, Provider, RenderingHints, SimpleBindings, TabularDataSupport, TreeMap, UIDefaults, WeakHashMap ) But still: -> The most important ones are HashMap and TreeMap ('Hashtable' is mostly like a Good Olde Tymey HashMap. Use HashMap.) HASH TABLES Goal Store and access associations between names and values. (Or just fast name lookup, if no value). Seeking 'nearly constant time' accessing in terms of number of name-value associations stored. How? - Linked lists at best O(n) to access an arbitrary element - Trees at best O(log n) " " - Array accessing is O(1) " " -> So use an array But accessing an array requires an array index, some kind of integer, to specify which arbitrary element. - But, a (general-purpose) 'name', whatever that is, isn't always going to be an integer. - Idea: Think of some way, some kind of 'hashing function' to mash up a name and turn it into an integer, then use that integer as an array index. A 'hashCode' or something.. HASH TABLES - VERY GENERALLY - Maintain an array to hold things (because array access is O(1)) - Given a 'key' of some kind, somehow turn that key into an array index. - Look in the corresponding array slot, and find something useful there. - If the array gets too full of things, get a bigger array, move all the things from the old array to the new array, and throw away the old array. HASH TABLES - VERY GENERALLY +------+ - Maintain an array to hold|things|(because array access is O(1)) +-+-------+ - Given a 'key' of some kind,|somehow|turn that key into an array index. +-------+ +----------------+ - Look in the corresponding array slot, and find|something useful| there. +----------------+ - If the array gets too full of things, get a bigger array, move all the things from the old array to the new array, and throw away the old array. HASH TABLES - VERY GENERALLY +------+ - Maintain an array to hold|things|(because array access is O(1)) +-+-------+ - Given a 'key' of some kind,|somehow|turn that key into an array index. +-------+ +----------------+ - Look in the corresponding array slot, and find|something useful| there. +----------------+ - If the array gets too full of things, get a bigger array, move all the things from the old array to the new array, and throw away the old array. 'things' -- usually an Object reference to be downcast -- before GENERICS! 'somehow' -- (an override of) int Object.hashCode() http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#hashCode() 'something useful' -- another Object reference to be downcast later (or just used if we're hip to generics). CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(String key, String value) { map.put(key,value); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(String key, String value) { map.put(key,value); } private String lookup(String key) { String val = map.get(key); if (val == null) throw new IllegalArgumentException(); return val; } insert("foo",null); if (map.containsKey("foo")) .. lookup("foo"); } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(String key, String value) { map.put(key,value); } private String lookup(String key) { String val = map.get(key); if (val == null) throw new IllegalArgumentException(); return val; } public static void main(String[] args) { Test t = new Test(); t.insert("foo","bar"); t.insert("bar","gah"); System.out.println(t.lookup("foo")); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(String key, String value) { map.put(key,value); } private String lookup(String key) { String val = map.get(key); if (val == null) throw new IllegalArgumentException(); return val; } public static void main(String[] args) { Test t = new Test(); t.insert("foo","bar"); t.insert("bar","gah"); System.out.println(t.lookup("foo")); } } $ javac Test.java;java Test bar $ CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) .. private Object lookup(short x, short y) .. } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) .. private Object lookup(short x, short y) .. public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) { map.put(new Integer((x<<16)+y),value); } private Object lookup(short x, short y) .. public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) { map.put(new Integer((x<<16)+y),value); } private Object lookup(short x, short y) .. public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) { map.put(new Integer((x<<16)+y),value); } private Object lookup(short x, short y) { return map.get(new Integer((x<<16)+y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) { map.put(new Integer((x<<16)+y),value); } private Object lookup(short x, short y) { return map.get(new Integer((x<<16)+y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8S,3S,"boom"); System.out.println(t.lookup(8,3)); } } javac Test.java;java Test Test.java:10: insert(short,short,java.lang.Object) in Test cannot be applied.. t.insert(8,3,"boom"); ^ Test.java:11: lookup(short,short) in Test cannot be applied to (int,int) System.out.println(t.lookup(8,3)); ^ 2 errors $ CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) { map.put(new Integer((x<<16)+y),value); } private Object lookup(short x, short y) { return map.get(new Integer((x<<16)+y)); } public static void main(String[] args) { Test t = new Test(); t.insert((short)8,(short)3,"boom"); System.out.println(t.lookup((short)8,(short)3)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(short x, short y, Object value) { map.put(new Integer((x<<16)+y),value); } private Object lookup(short x, short y) { return map.get(new Integer((x<<16)+y)); } public static void main(String[] args) { Test t = new Test(); short sx = 8, sy = 3; t.insert(sx, sy, "boom"); System.out.println(t.lookup((short)8,(short)3)); } } $ javac Test.java;java Test boom $ CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private void insert(int x, int y, Object value) private Object lookup(int x, int y) } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public Key(int x, int y) { this.x = x; this.y = y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java;java Test boom CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java;java Test boom ...Pretty cool... CLASS HASHMAP import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } // Is this a GOOD hashCode??? public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java;java Test boom ...Pretty cool... CLASS HASHMAP - UPSHOTS - Associates arbitrary 'keys' and 'values' CLASS HASHMAP - UPSHOTS - Associates arbitrary 'keys' and 'values' - Built on = a HASH FUNCTION, that converts key objects to (hopefully usually different) integer values, and on = an EQUALITY FUNCTION to specify when two objects should be considered as the same key. CLASS HASHMAP - UPSHOTS - Associates arbitrary 'keys' and 'values' - Built on = a hash function, that converts key objects to (hopefully usually different) integer values, and on = an equality function to specify when two objects should be considered as the same key. - So, objects used as keys must provide two essential properties: P1: boolean equals(Object other) Returns true iff the 'other' object is equal to the 'this' object in all ways that matter. P2: int hashCode() Returns a numeric code derived from the object 'this' such that for any Object A and B, if A.equals(B), then A.hashCode() == B.hashCode() CLASS HASHMAP - UPSHOTS - Associates arbitrary 'keys' and 'values' - Built on = a hash function, that converts key objects to (hopefully usually different) integer values, and on = an equality function to specify when two objects should be considered as the same key. - So, objects used as keys must provide two essential properties: P1: boolean equals(Object other) Returns true iff the 'other' object is equal to the 'this' object in all ways that matter. P2: int hashCode() Returns a numeric code derived from the object 'this' such that for any Object A and B, if A.equals(B), then A.hashCode() == B.hashCode() - WARNING: You can get way screwed if P1 or P2 isn't true! CLASS HASHMAP - UPSHOTS - Associates arbitrary 'keys' and 'values' - Built on = a hash function, that converts key objects to (hopefully usually different) integer values, and on = an equality function to specify when two objects should be considered as the same key. - So, objects used as keys must provide two essential properties: P1: boolean equals(Object other) Returns true iff the 'other' object is equal to the 'this' object in all ways that matter. P2: int hashCode() Returns a numeric code derived from the object 'this' such that for any Object A and B, if A.equals(B), then A.hashCode() == B.hashCode() - WARNING: You can get way screwed if P1 or P2 isn't true! - When everything works: Approximately O(1) lookup! Sweet! CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java $ java Test boom CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; /* public int hashCode() { return x*1771+y; } */ public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; /* public int hashCode() { return x*1771+y; } */ public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java $ CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; /* public int hashCode() { return x*1771+y; } */ public Key(int x, int y) { this.x = x; this.y = y; } public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java $ java Test null CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } /* public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } */ } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } /* public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } */ } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java $ java Test null CLASS HASHMAP - DANGERS import java.util.Map; import java.util.HashMap; class Test { private Map map = new HashMap(); private class Key { int x, y; public int hashCode() { return x*1771+y; } public Key(int x, int y) { this.x = x; this.y = y; } /* public boolean equals(Object o) { if (!(o instanceof Key)) return false; Key k = (Key) o; return k.x == x && k.y == y; } */ } private void insert(int x, int y, Object value) { map.put(new Key(x,y), value); } private Object lookup(int x, int y) { return map.get(new Key(x,y)); } public static void main(String[] args) { Test t = new Test(); t.insert(8,3,"boom"); System.out.println(t.lookup(8,3)); } } $ javac Test.java - The default implementations in Object.hashCode $ java Test and Object.equals means (1) No compiler errors, but null (2) Incorrect behavior. Thanks a lot, class Object! HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array Downside: Have to deal with COLLISIONS: When two different names get hashed to the same number HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array Downside: Have to deal with COLLISIONS: When two different names get hashed to the same number Issues: - What hash function? HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array Downside: Have to deal with COLLISIONS: When two different names get hashed to the same number Issues: - What hash function? -> Speed -> Spread HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array Downside: Have to deal with COLLISIONS: When two different names get hashed to the same number Issues: - What hash function? -> Speed -> Spread - How to deal with collisions? -> 'Open addressing' - put collided entries somewhere else in the table HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array Downside: Have to deal with COLLISIONS: When two different names get hashed to the same number Issues: - What hash function? -> Speed -> Spread - How to deal with collisions? -> 'Open addressing' - put collided entries somewhere else in the table -> 'Separate chaining' - make a linked list of collided entries at each index in the array HASH TABLES - HOW DO THEY REALLY WORK? Getting an index from a name IDEA: 'Hash' the name up into a reasonably small number to use as an array index, with a HASH FUNCTION Upside: Can use a reasonably small array Downside: Have to deal with COLLISIONS: When two different names get hashed to the same number Issues: - What hash function? -> Speed -> Spread - How to deal with collisions? -> 'Open addressing' - put collided entries somewhere +----------------------------------------------+ ->|'Separate chaining' - make a linked list of | | collided entries at each index in the array | +----------------------------------------------+