Created
June 21, 2024 03:39
-
-
Save jweinst1/9df1e5002dc4a01d45416991b82fef82 to your computer and use it in GitHub Desktop.
in place rehash of hash table in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import random | |
import string | |
def rand_str(n): | |
return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(n)) | |
def rand_str_set(n, amount): | |
return {rand_str(n) for i in range(amount)} | |
class DeleteMarker: | |
def __repr__(self): | |
return "X" | |
class EmptyMarker: | |
def __repr__(self): | |
return "O" | |
class HashMarker: | |
def __init__(self, key, hsize, hashv): | |
self.key = key | |
self.hsize = hsize | |
self.hashv = hashv | |
def __repr__(self): | |
return str((self.key, self.hsize, self.hashv)) | |
def isKey(self, other): | |
return self.key == other | |
def empty_arr(n): | |
return [EmptyMarker() for i in range(n)] | |
class HashTable: | |
def __init__(self, size): | |
self.size = size | |
self.table = empty_arr(self.size) | |
def __repr__(self): | |
return str(self.table) | |
def checkSlot(self, i, keystr): | |
if isinstance(self.table[i], EmptyMarker) or isinstance(self.table[i], DeleteMarker): | |
return True | |
elif self.table[i].isKey(keystr): | |
return True | |
else: | |
return False | |
def insert(self, keystr, use_size=0, verbose=False): | |
hashed = abs(hash(keystr)) | |
if use_size == 0: | |
use_size = self.size | |
table_hash = hashed % use_size | |
if verbose: | |
print("will hash {} into slot {}".format(keystr, table_hash)) | |
if self.checkSlot(table_hash, keystr): | |
self.table[table_hash] = HashMarker(keystr, use_size, hashed) | |
return True | |
for i in range(table_hash, use_size): | |
if self.checkSlot(i, keystr): | |
self.table[i] = HashMarker(keystr, use_size, hashed) | |
return True | |
for j in range(table_hash): | |
if self.checkSlot(j, keystr): | |
self.table[j] = HashMarker(keystr, use_size, hashed) | |
return True | |
return False | |
def rehash_inplace(self, new_size): | |
self.table += empty_arr(new_size - self.size) | |
for i in range(self.size): | |
if isinstance(self.table[i], HashMarker): | |
self.insert(self.table[i].key, new_size, True) | |
# this step needs a global lock | |
old_size = self.size | |
self.size = new_size | |
# print("---------------") | |
# print(self.table) | |
# print("---------------") | |
for i in range(self.size): | |
if isinstance(self.table[i], HashMarker): | |
if self.table[i].hsize == old_size: | |
self.table[i] = DeleteMarker() | |
if __name__ == '__main__': | |
h = HashTable(50) | |
h.insert("foo", verbose = True) | |
h.insert("foo", verbose = True) | |
h.insert("doo", verbose = True) | |
h.insert("blue", verbose = True) | |
h.insert("blee", verbose = True) | |
h.insert("green", verbose = True) | |
print(h) | |
h.rehash_inplace(100) | |
print("-------------------") | |
print(h) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment