Implement hash table lookup logic
This commit is contained in:
		
							parent
							
								
									4e5883f384
								
							
						
					
					
						commit
						53a369952e
					
				| @ -2,23 +2,20 @@ const std = @import("std"); | ||||
| 
 | ||||
| pub fn Dynamic(comptime Key: type, comptime Value: type, comptime key_context: KeyContext(Key)) type { | ||||
|     return struct { | ||||
|         load_maximum: f32, | ||||
|         buckets_used: usize, | ||||
|         bucket_map: []?Bucket, | ||||
|         buckets: []Bucket, | ||||
| 
 | ||||
|         /// | ||||
|         /// | ||||
|         /// | ||||
|         const Bucket = struct { | ||||
|             key: Key, | ||||
|             value: Value, | ||||
|             next: ?usize, | ||||
|         }; | ||||
| 
 | ||||
|         /// | ||||
|         /// | ||||
|         /// | ||||
|         pub const InsertError = error { | ||||
|             maybe_entry: ?struct { | ||||
|                 key: Key, | ||||
|                 value: Value, | ||||
|             }, | ||||
| 
 | ||||
|             maybe_next_index: ?usize, | ||||
|         }; | ||||
| 
 | ||||
|         /// | ||||
| @ -29,8 +26,7 @@ pub fn Dynamic(comptime Key: type, comptime Value: type, comptime key_context: K | ||||
|         /// | ||||
|         /// | ||||
|         /// | ||||
|         pub fn insert(self: Self, key: Key, value: Value) InsertError!void { | ||||
|             _ = value; | ||||
|         pub fn delete(self: Self, key: Key) bool { | ||||
|             _ = key; | ||||
|             _ = self; | ||||
|         } | ||||
| @ -38,14 +34,43 @@ pub fn Dynamic(comptime Key: type, comptime Value: type, comptime key_context: K | ||||
|         /// | ||||
|         /// | ||||
|         /// | ||||
|         pub fn insert(self: Self, key: Key, value: Value) InsertError!void { | ||||
|             if ((@intToFloat(f32, self.buckets_used) / @intToFloat( | ||||
|                 f32, self.buckets.len)) >= self.load_maximum) try self.rehash(); | ||||
| 
 | ||||
|             var hash = @mod(key_context.hash(key), self.buckets.len); | ||||
| 
 | ||||
|             while (true) { | ||||
|                 const bucket = &(self.buckets[hash]); | ||||
| 
 | ||||
|                 const entry = &(bucket.maybe_entry orelse { | ||||
|                     bucket.maybe_entry = .{ | ||||
|                         .key = key, | ||||
|                         .value = value | ||||
|                     }; | ||||
|                 }); | ||||
| 
 | ||||
|                 if (key_context.equals(entry.key, key)) return error.KeyExists; | ||||
| 
 | ||||
|                 hash = @mod(hashHash(hash), self.buckets.len); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// | ||||
|         /// Searches for a value indexed with `key` in `self`, returning it or `null` if no matching | ||||
|         /// entry was found. | ||||
|         /// | ||||
|         pub fn lookup(self: Self, key: Key) ?*Value { | ||||
|             var bucket = &(self.bucket_map[@mod(key_context.hash( | ||||
|                 key), self.bucket_map.len)] orelse return null); | ||||
|             var bucket = &(self.buckets[@mod(key_context.hash(key), self.buckets.len)]); | ||||
| 
 | ||||
|             while (bucket) { | ||||
|                 if (key_context.equals(bucket.key, key)) return &bucket.value; | ||||
|             if (bucket.maybe_entry) |*entry| | ||||
|                 if (key_context.equals(entry.key, key)) return &entry.value; | ||||
| 
 | ||||
|                 bucket = bucket.next; | ||||
|             while (bucket.maybe_next_index) |index| { | ||||
|                 bucket = &(self.buckets[index]); | ||||
| 
 | ||||
|                 if (bucket.maybe_entry) |*entry| | ||||
|                     if (key_context.equals(entry.key, key)) return &entry.value; | ||||
|             } | ||||
| 
 | ||||
|             return null; | ||||
| @ -53,6 +78,13 @@ pub fn Dynamic(comptime Key: type, comptime Value: type, comptime key_context: K | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| /// | ||||
| /// | ||||
| /// | ||||
| pub const InsertError = std.mem.Allocator || error { | ||||
|     KeyExists, | ||||
| }; | ||||
| 
 | ||||
| pub fn KeyContext(comptime Key: type) type { | ||||
|     return struct { | ||||
|         hash: fn (Key) usize, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user